chore: CRM-NEW baseline

This commit is contained in:
wangliang
2026-10-23 10:35:28 +08:00
commit aa499f6dbf
111 changed files with 15126 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
# libredesk(crm-new/libredesk)
位于 `/home/dev/code/crm-new/libredesk` 的 **LibreDesk 版 CRM 客服栈**,与旧项目 `/home/dev/code/crm/crm-ai-demo` 完全隔离(独立目录、独立 git、独立 Postgres/Redis、独立端口)。
- **定位**:验证「LibreDesk 作为客服平台 + 内置 AI Assistant + 外部业务工具」能否替代现有 Chatwoot + bridge 架构。
- **当前阶段**:POC 骨架(可启动、工具服务可跑、含单元测试),尚未接入真实 widget 和生产数据。
- **旧系统不受影响**:`crm-ai-demo` 仍在 3000/3001/4000 端口运行。
## 当前状态(2026-10-21)
| 项 | 状态 |
|---|---|
| 目录/配置/脚本脚手架 | ✅ 完成 |
| crm-tools 服务(4 工具 + 鉴权 + 验证门控) | ✅ 单测 18/18 通过,本机 :4010 可运行 |
| config.toml 渲染 / compose 校验 | ✅ 通过 |
| LibreDesk 容器 | ✅ 运行中(**v2.9.0-rc.10**,health 200);Postgres 18 / Redis 健康 |
| 后台 AI/工具/助手配置 | ⏳ 登录 `http://localhost:9000` 后按 `docs/libredesk-setup.md` 执行 |
> 当前运行 **v2.9.0-rc.10**:渠道已包含 `email / livechat / whatsapp`,WhatsApp 表已迁移完成。
> RC 属于预发布版本,功能可用但生产使用前需评估稳定性(回滚方法见「镜像拉取」)。
## 架构
```
访客 ──► LibreDesk Live Chat Widget (:9000)
│
▼
LibreDesk AI Assistant ──HTTP tool calls──► crm-tools (:4010)
(snippets 向量检索 / 内置 OTP 验证) │
├──► 商品推荐 RPC (recommend)
├──► 订单 RPC (trading-service)
├──► 库存/ETA RPC (eta-service)
└──► Twenty CRM GraphQL (商机/备注/任务)
```
关键设计:**业务数据与身份验证不放进 LibreDesk 代码里**,而是通过它的自定义 HTTP 工具回调 `crm-tools`;工具服务二次校验 `X-Libredesk-Contact-Verified`,不信任模型参数里的邮箱。
详见 [docs/architecture.md](docs/architecture.md)。
## 目录
```
crm-new/libredesk/
├── docker-compose.yml # LibreDesk + 独立 Postgres(5433) + Redis(6380)
├── .env.example # 环境变量模板(bootstrap 自动生成 .env)
├── config/
│ └── config.toml.example # LibreDesk 配置模板(渲染成 config.toml,不入库)
├── scripts/
│ ├── bootstrap.sh # 生成密钥 + 渲染配置 + 启动 LibreDesk
│ ├── start-tools.sh # 宿主机启动 tools 服务
│ ├── render-config.js # config.toml 渲染
│ ├── register-tools.js # 把工具注册进 LibreDesk(可选)
│ └── smoke.sh # 冒烟测试
├── services/tools/ # 业务工具服务(Node 20+,零外部依赖)
│ ├── src/
│ │ ├── server.js # HTTP 入口 + 鉴权 + 验证门控
│ │ ├── tools.js # 4 个工具:商品/订单/库存/建商机
│ │ ├── twenty.js # Twenty GraphQL 客户端
│ │ ├── rpc.js # JSONRPC-TCP 客户端(Hyperf 协议)
│ │ ├── config.js / auth.js / errors.js
│ └── test/ # node:test 单元测试
├── docs/
│ ├── architecture.md # 架构与数据流
│ ├── libredesk-setup.md # 后台配置步骤(AI/工具/助手/自动化/Widget)
│ ├── api-mapping.md # Chatwoot → LibreDesk 接口/事件/字段对照
│ └── migration-plan.md # 6 层拆分、方案 A/B/C、代码存废清单
├── deploy/nginx.conf.example
└── uploads/ # LibreDesk 上传目录(运行时)
```
## 快速开始
> 网络提示:本机直连 Docker Hub 会 reset。`.env` 已默认复用本地已有镜像
> (`pgvector/pgvector:pg18`、`redis:8.8-alpine`),LibreDesk 镜像可用时可改
> `LIBREDESK_IMAGE=docker.1panel.live/libredesk/libredesk:latest` 等镜像源。
> 详见文末「镜像拉取」一节。
```bash
cd /home/dev/code/crm-new/libredesk
# 1) 启动 LibreDesk(自动生成 .env / config.toml,首次拉镜像)
bash scripts/bootstrap.sh
# 2) 另开终端,启动工具服务 :4010
bash scripts/start-tools.sh
# 3) 按 docs/libredesk-setup.md 配置 AI Provider / Inbox
# 然后在 Admin → Teammates → System 生成 API key,填入 .env
# 4) 自动注册 4 个 AI 工具(失败也可按文档手工创建)
node scripts/register-tools.js
# 5) 冒烟
bash scripts/smoke.sh
```
| 组件 | 地址 | 说明 |
|---|---|---|
| LibreDesk | http://localhost:9000 | `System` + bootstrap 生成的密码 |
| crm-tools | http://127.0.0.1:4010 | `/healthz`、`/tools/manifest`、`/tools/<name>` |
| Postgres | 127.0.0.1:5433 | 独立实例,库 `libredesk` |
| Redis | 127.0.0.1:6380 | 独立实例 |
## 工具清单
| 工具 | 需要验证 | 作用 |
|---|---|---|
| `search_products` | 否 | 商品关键词搜索(recommend RPC) |
| `search_orders` | **是** | 订单/物流查询,邮箱强制取自已验证身份头 |
| `search_inventory` | 否 | SKU 实时库存 + ETA |
| `create_opportunity` | **是** | Twenty 建商机 + 聊天摘要备注 + 3 天跟进任务,按邮箱去重 |
## 测试
```bash
cd services/tools && npm test
```
覆盖:地址解析、鉴权 fail-closed、验证门控、邮箱作用域/IDOR 防护、商机去重。
## 本阶段边界(未做)
- 未接入真实网站 widget(JWT 签发仍是下一步)
- 未做 Chatwoot → LibreDesk 数据迁移(当前旧库仅 2 条会话,可忽略)
- 未接入观测/评估/飞轮(需要时按 [docs/migration-plan.md](docs/migration-plan.md) 的 L6 保留 bridge)
- WhatsApp 需 v2.9 预发布版(见 setup 文档最后一节)
## 镜像拉取(国内网络)
本机实测:`registry-1.docker.io` 连接被 reset,直连不可用。
| 方案 | 命令 | 备注 |
|---|---|---|
| 1panel 镜像源 | `docker pull docker.1panel.live/libredesk/libredesk:v2.9.0-rc.10` | ✅ 2026-10-21 实测可用(74MB) |
| 稳定版 latest | `docker pull docker.1panel.live/libredesk/libredesk:latest` | ✅ 可用(= v2.8.0,无 WhatsApp) |
| 1ms 镜像源 | `docker pull docker.1ms.run/libredesk/libredesk:latest` | 备用 |
| 自建(不推荐) | 从 `v2.8.0` 源码构建 | 需要 Go + Node + pnpm,耗时较长 |
拉到镜像后改 `.env`:
```ini
LIBREDESK_IMAGE=docker.1panel.live/libredesk/libredesk:v2.9.0-rc.10
# 或本地打 tag 后继续用默认值
# docker tag docker.1panel.live/libredesk/libredesk:v2.9.0-rc.10 libredesk/libredesk:v2.9.0-rc.10
```
### 回滚到稳定版 v2.8.0
```bash
sed -i 's#^LIBREDESK_IMAGE=.*#LIBREDESK_IMAGE=docker.1panel.live/libredesk/libredesk:latest#' .env
docker compose up -d --force-recreate app # 跨版本回退需用备份库,见下
```
## 与旧系统的关系
| | 旧栈 `crm-ai-demo` | 新栈 `crm-new/libredesk` |
|---|---|---|
| 客服平台 | Chatwoot 4.16(Rails) | LibreDesk(Go 单二进制) |
| AI 编排 | bridge 自研 agent loop | LibreDesk AI Assistant(POC 目标) |
| 业务工具 | bridge 内置 | 独立 `services/tools` |
| 数据 | crm-postgres:5432 | 独立 postgres:5433 |
| 端口 | 3000/3001/4000 | 9000/4010 |
两套可以并行跑,方便同一批问题做 A/B 对比。