886 lines
44 KiB
Markdown
886 lines
44 KiB
Markdown
# 2026-07-18 GoChat CDP 点击式全量功能测试计划
|
||
|
||
> 创建日期:2026-07-18
|
||
> 最后更新:2026-07-20
|
||
> 适用范围:`/home/rogee/Projects/gochat`
|
||
> 执行方式:连接已手动启动的本地 GoChat 服务,通过 Chrome DevTools Protocol 做真实点击路径测试
|
||
> 关联文档:
|
||
> - [docs/qa/2026-07-15-cdp-user-function-test-plan.md](/home/rogee/Projects/gochat/docs/qa/2026-07-15-cdp-user-function-test-plan.md)
|
||
> - [docs/qa/2026-07-17-cdp-full-user-function-test-plan.md](/home/rogee/Projects/gochat/docs/qa/2026-07-17-cdp-full-user-function-test-plan.md)
|
||
> - [docs/qa/reports/2026-07-15-cdp-user-function-report.md](/home/rogee/Projects/gochat/docs/qa/reports/2026-07-15-cdp-user-function-report.md)
|
||
|
||
这份文档截至 2026-07-20 仍作为当前这轮 CDP 点击式全量测试的主执行基线;`2026-07-15` 与 `2026-07-17` 两份文档保留为补充参考,不再作为当前主执行稿。
|
||
|
||
## 1. 目标
|
||
|
||
这轮不是再写一个泛泛的 QA 说明,而是把后续 CDP 执行真正需要的三件事一次定清楚:
|
||
|
||
1. 用点击式路径把 GoChat 当前可见的用户页面全部纳入测试范围。
|
||
2. 把每类页面必须验证的功能点拆细,避免只看“能打开”。
|
||
3. 明确哪些测试数据和哪些假能力没有补齐前,不能宣称“全量实际功能测试完成”。
|
||
|
||
## 2. 当前执行前提
|
||
|
||
用户已手动启动以下 3 个服务:
|
||
|
||
```bash
|
||
pnpm dev:backend
|
||
pnpm dev:frontend
|
||
GOCHAT_WEBHOOK_URL=http://127.0.0.1:3000/webhooks/fake/fake_01 FAKE_AUTO_REPLY=true pnpm fake:start
|
||
```
|
||
|
||
本计划默认基于以下地址:
|
||
|
||
| 服务 | 地址 | 说明 |
|
||
|---|---|---|
|
||
| frontend | `http://127.0.0.1:3036` | Dashboard / Widget / Public surface |
|
||
| backend | `http://127.0.0.1:3000` | API / webhook / SSE / websocket |
|
||
| fake channel | `http://127.0.0.1:9100` | 外部客户消息、出站消息回收、自动回流 |
|
||
| Chrome CDP | `http://127.0.0.1:9222` | 优先复用现有浏览器会话 |
|
||
|
||
### 2.1 本轮直接产出
|
||
|
||
| 产出 | 位置 | 用途 |
|
||
|---|---|---|
|
||
| CDP 点击式全量测试主计划 | 当前文档 | 作为 Saturday, July 18, 2026 这一轮的唯一执行基线 |
|
||
| 持续追加的执行报告 | `docs/qa/reports/2026-07-15-cdp-user-function-report.md` | 沉淀后续每个页面族的 pass/fail/blocked 证据 |
|
||
| 全量测试数据缺口清单 | 第 8 节、第 9 节 | 明确哪些对象不补齐前不能宣称“全量实际功能测试完成” |
|
||
| AI 测试支撑方案 | 第 10 节到第 12 节 | 约束 `fake:ai` 的最小接口、场景模式、接入方式 |
|
||
|
||
### 2.2 当前最高优先级 blocker 摘要
|
||
|
||
| 优先级 | blocker | 最低要求 | 不补会卡住什么 |
|
||
|---|---|---|---|
|
||
| P0 | `fake_01` inbox 在 GoChat 内完成建档 | 1 个 | fake 入站、客服回复、auto reply 主链路 |
|
||
| P0 | 第二个可登录 agent | 1 个 | 分配、协作、mentions、在线状态、团队联动 |
|
||
| P0 | 多状态会话池 | 至少 6 条 | 会话列表、筛选、报表、回归重走 |
|
||
| P0 | CRM 非空数据 | contacts 8+、companies 3+ | 联系人/公司列表、搜索、分页、联动 |
|
||
| P0 | 标签与团队数据 | labels 5+、teams 2+ | team 视图、标签过滤、自动化条件、报表 |
|
||
| P0 | 本地 `fake:ai` | 1 套可保存并可观测的 `openai_compatible` 假服务 | Captain / Copilot 只能停留在 render-only |
|
||
|
||
### 2.3 截至 2026-07-20 的当前测试边界
|
||
|
||
基于现在已经手工启动的 `backend + frontend + fake channel`,本轮测试边界先明确为两层:
|
||
|
||
1. 可以立刻开始做 click-only CDP 实测的范围:
|
||
- 登录与 dashboard 主壳
|
||
- 会话主链路与 fake channel E2E
|
||
- 联系人、公司、搜索、通知、报表
|
||
- settings、widget、public、help center
|
||
2. 仍不能记为“全量实际功能通过”的范围:
|
||
- Captain / Copilot 的真实生成链路
|
||
- embedding、FAQ/document 索引、playground 生成、rewrite/summarize 等 AI 功能
|
||
|
||
原因不是页面没法打开,而是当前仓库还没有 `fake:ai`,因此 AI 相关页面在没有本地 OpenAI-compatible 假服务前,只能验证:
|
||
|
||
- 路由
|
||
- 页面渲染
|
||
- 表单保存
|
||
- provider disabled / provider error 降级提示
|
||
|
||
不能验证:
|
||
|
||
- 真实 chat completion
|
||
- 流式输出
|
||
- embedding 维度兼容
|
||
- AI 任务成功后的前后状态变化
|
||
|
||
## 3. 强约束
|
||
|
||
### 3.1 导航约束
|
||
|
||
- 登录页、public 页面、widget 根入口允许直接打开。
|
||
- 登录后的 GoChat 内部页面一律通过真实 UI 点击进入。
|
||
- 不允许把 `/app/accounts/:id/...` 深链当成页面通过证据。
|
||
- 如果只能靠手输 URL 才能进入,记为入口或路由组织问题,不算页面通过。
|
||
|
||
### 3.2 判定约束
|
||
|
||
每个页面至少同时满足以下 6 项,才可判为 `pass`:
|
||
|
||
1. 可达:从现有 UI 路径真实点击进入。
|
||
2. 可见:主区域不是空白壳,不是只变 URL。
|
||
3. 可载:关键 API 返回正常,首屏数据完成加载。
|
||
4. 可用:至少 1~3 个核心功能点能实际执行。
|
||
5. 可回:返回列表、刷新、再次进入时状态一致。
|
||
6. 可观测:console、network、runtime exception 均已记录。
|
||
|
||
以下情况直接记 `fail` 或 `partial pass`,不能算通过:
|
||
|
||
- URL 改了,但 `main` 区域没切换。
|
||
- 只看到 `离线的`、空白主区、`Unhandled error during execution of component update`、`Uncaught (in promise)`。
|
||
- API 422/500 明确落在当前页面主链路上。
|
||
|
||
## 4. 执行前检查
|
||
|
||
| 检查项 | 动作 | 通过标准 |
|
||
|---|---|---|
|
||
| backend health | `GET /health` | 200 |
|
||
| frontend login | 打开 `/app/login` | 登录页正常渲染 |
|
||
| fake health | `GET http://127.0.0.1:9100/health` | `status=ok` |
|
||
| smoke seed 基线 | 确认 `admin@gochat.local / changeme`、`Test Website Inbox`、`Smoke Company`、`Smoke Help Center` 等已存在;若缺失则执行 `cd backend && go run ./cmd/gochat seed` | 至少能登录并看到 smoke 基础对象 |
|
||
| fake inbox 绑定 | 确认 GoChat 内已存在 `fake_01` 对应的 fake inbox,且其 identifier 与 `GOCHAT_WEBHOOK_URL=http://127.0.0.1:3000/webhooks/fake/fake_01` 一致 | fake 平台发消息后能在 GoChat 建会话,而不只是 fake 服务自己健康 |
|
||
| CDP attach | `GET http://127.0.0.1:9222/json/version` | 能拿到 `webSocketDebuggerUrl` |
|
||
| Node tooling | `command -v npx` | `npx` 可用 |
|
||
| fake 配置 | `POST /api/config` 或读 fake 状态 | `fake_01` webhook 指向 GoChat,本轮 auto reply 已开启 |
|
||
| 登录态 | 通过 UI 登录 | 能进入主 dashboard |
|
||
| websocket/sse | 登录后观察 `/cable` / SSE 请求 | 无持续 401/403 重连风暴 |
|
||
| 报告落点 | 确认既有 report | 本轮证据继续追加同一份 report |
|
||
|
||
## 5. CDP 统一取证格式
|
||
|
||
每个页面或子页至少记录这些内容:
|
||
|
||
- 页面入口点击链路
|
||
- `page.url`
|
||
- 页面主标题或主区域关键文本
|
||
- 关键按钮/表单/列表是否出现
|
||
- 当前页面触发的关键 API 路径与状态码
|
||
- console warning / error
|
||
- runtime exception
|
||
- 操作前后截图或 snapshot 摘要
|
||
- 最终判定:`pass` / `partial pass` / `fail` / `blocked`
|
||
|
||
推荐统一证据模板:
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| page group | 模块或页面组名称 |
|
||
| click path | 从哪个菜单、哪个列表项点进来 |
|
||
| url | 最终路由 |
|
||
| expected | 本页应验证的能力 |
|
||
| observed | 实际看到的文案、列表、表单、图表、交互 |
|
||
| api | 关键请求及状态码 |
|
||
| console | warning/error 摘要 |
|
||
| verdict | pass / partial pass / fail / blocked |
|
||
|
||
### 5.1 每个页面都要过的统一检查维度
|
||
|
||
为了避免后续执行变成“页面能打开就算过”,这里再固定一层页面级验收维度。第 6 节所有页面组,都至少要按下面这些切面挑选对应项去验证:
|
||
|
||
| 维度 | 要检查什么 | 典型证据 |
|
||
|---|---|---|
|
||
| 入口可达 | 是否能从当前 UI 真实点到 | click path、snapshot、最终 URL |
|
||
| 首屏挂载 | 主区是否真的切换,不是只变 URL | 主标题、列表/表单/图表出现 |
|
||
| 数据加载 | 首屏关键 API 是否成功返回 | `/api`、`/platform`、`/public` 请求状态码 |
|
||
| 空态/非空态 | 空页面文案与非空列表是否都合理 | 空态文案、首条数据、计数器 |
|
||
| 列表能力 | 搜索、筛选、排序、分页、计数是否正常 | 查询前后列表变化、页码变化 |
|
||
| 详情能力 | 列表进入详情、详情返回列表是否稳定 | 详情标题、侧栏信息、返回后状态 |
|
||
| CRUD/主操作 | 创建、编辑、删除、保存、执行是否真实生效 | toast、回显、刷新后仍存在 |
|
||
| 模块联动 | 会话 ↔ 联系人 ↔ 公司,设置 ↔ 业务页是否串得起来 | 从 A 点进 B 后再返回 A 的状态 |
|
||
| 权限与可见性 | 管理员、agent、custom role 是否看到正确入口和禁用态 | 菜单裁剪、按钮禁用、403/422 提示 |
|
||
| 异常与降级 | 后端 4xx/5xx、空结果、feature gate、第三方缺失是否有明确反馈 | alert、inline error、空壳/离线态 |
|
||
| 刷新与返回 | browser back、页面刷新、重复进入是否一致 | URL、主区文本、筛选状态回显 |
|
||
| 可观测性 | console / runtime / websocket / SSE 是否稳定 | console message、runtime exception、`/cable`、SSE 请求 |
|
||
|
||
额外强调两条:
|
||
|
||
- 对列表页,至少要覆盖“空态”和“有数据态”其中之一;如果当前数据不够,要在报告里明确记成数据阻塞,不要把空态误记成通过。
|
||
- 对配置页,至少要覆盖“一次真实保存 + 一次刷新回显”;只看到表单渲染不算通过。
|
||
|
||
## 6. 页面覆盖矩阵
|
||
|
||
下面是后续 CDP 执行的主清单。不是所有页面都要一次测完,但最终报告需要按这个范围闭环。
|
||
|
||
### 6.1 登录与主壳
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 登录页 | `/app/login` | 邮箱/密码输入、回车提交、错误密码提示、loading、登录成功跳转 |
|
||
| 主 dashboard 壳 | 登录后默认页 | 左侧菜单、顶部栏、账号上下文、全局状态、页面切换时主区真的更新 |
|
||
| 刷新恢复 | 任意已进入页刷新 | session 保持、当前页恢复、不会回到空壳 |
|
||
|
||
### 6.2 会话工作台
|
||
|
||
来源:`conversation.routes.js` 与 `M03`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 会话总览 | 左侧“会话” | open/pending/resolved/snoozed 列表、计数、分页、切换 |
|
||
| Inbox 维度会话 | 会话侧栏 inbox 分组 | inbox 过滤、列表切换、详情联动 |
|
||
| Label 维度会话 | 会话侧栏 label 分组 | 标签过滤、列表计数、详情打开 |
|
||
| Team 维度会话 | 会话侧栏 team 分组 | 团队过滤、分配联动 |
|
||
| Mentions / Unattended / Participating | 会话侧栏对应入口 | 各维度列表是否正确、计数是否变化 |
|
||
| 单会话详情 | 从列表点进会话 | 时间线、状态、优先级、标签、assignee、team、侧栏联系人/公司信息 |
|
||
| 回复能力 | 会话编辑区 | 发送文本、private note、切换状态、加标签、分配 agent/team |
|
||
| 附件与富交互 | 会话编辑区 | 上传附件、粘贴、多消息类型渲染 |
|
||
| 实时链路 | fake channel + 会话列表/详情 | fake 入站、客服回复、fake 收到出站、auto reply 回流、UI 无刷新更新 |
|
||
|
||
### 6.3 Inbox View
|
||
|
||
来源:`dashboard/inbox/routes.js`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Inbox View 空页 | 左侧或相关入口进入 Inbox View | 空态渲染、说明文案、选择项 |
|
||
| Inbox View 详情 | 在 Inbox View 中点具体对象 | 列表与详情同步、筛选切换、返回路径稳定 |
|
||
|
||
### 6.4 联系人与公司
|
||
|
||
来源:`contacts/routes.js`、`companies/routes.js`、`M04`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 联系人列表 | 左侧“联系人” | 列表加载、分页、搜索、active/segment/label 过滤 |
|
||
| 联系人详情 | 联系人列表点进详情 | 基本资料、自定义属性、标签、最近活动、可用操作 |
|
||
| 联系人操作 | 联系人页按钮/弹窗 | 新建、编辑、删除、合并、加标签 |
|
||
| 联系人与会话联动 | 从会话侧栏进入联系人,再返回 | 联动跳转正确、状态不丢 |
|
||
| 公司列表 | 左侧“公司” | 列表、分页、搜索、计数 |
|
||
| 公司详情 | 公司列表点进详情 | 基本信息、关联联系人、历史记录、备注、自定义属性 |
|
||
| 公司与联系人联动 | 公司详情子 tab | 添加联系人、关联联系人详情跳转 |
|
||
|
||
### 6.5 全局搜索
|
||
|
||
来源:`modules/search/search.routes.js`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 搜索总页 | 顶部搜索入口 | 默认页渲染、recent searches、空态 |
|
||
| 搜索结果 | 输入关键词后回车或选择结果 | conversations/messages/contacts/articles tab 切换、高亮、跳转 |
|
||
| 错误态 | 搜索接口异常时 | UI 错误提示、非静默失败、不会误显示空结果 |
|
||
|
||
### 6.6 通知中心
|
||
|
||
来源:`notifications/routes.js`、`M08`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 通知列表 | 右上或设置包装后的通知入口 | 列表加载、已读/未读、分页或增量加载 |
|
||
| 通知动作 | 列表项按钮 | 标为已读、全部已读、删除、跳转回目标页面 |
|
||
| snooze/恢复 | 有对应入口时 | snooze 后状态变化、恢复后计数变化 |
|
||
|
||
### 6.7 报表
|
||
|
||
来源:`settings/reports/reports.routes.js`、`M07`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| 总览报表 | 左侧“报告”默认页 | 实时指标、筛选、时间范围 |
|
||
| 会话报表 | 报告 → 会话 | 指标卡、图表、筛选条件 |
|
||
| 客服概览/详情 | 报告 → 客服 | overview 列表、agent drilldown、时间范围、图表 |
|
||
| 收件箱概览/详情 | 报告 → 收件箱 | overview、detail、图表、计数 |
|
||
| 标签概览/详情 | 报告 → 标签 | overview、detail、summary、图表、错误态 |
|
||
| 团队概览/详情 | 报告 → 团队 | overview、detail、summary、图表 |
|
||
| SLA 报表 | 报告 → SLA | 筛选、列表、跳会话 |
|
||
| CSAT 报表 | 报告 → CSAT | 指标、分布、评论、筛选 |
|
||
| Bot 报表 | 报告 → Bot | 指标卡、图表、空态或 feature gate |
|
||
|
||
### 6.8 Settings:账户与个人设置
|
||
|
||
来源:`settings.routes.js` 下 account/profile/security。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| General / Account | 设置 → General | 账户名称、语言、时区、支持邮箱、保存回显 |
|
||
| Profile | 设置 → Profile | 昵称、签名、头像、语言偏好 |
|
||
| Security | 设置 → Security | 安全配置、受限项可见性、降级提示 |
|
||
| MFA | Profile/Security 子页 | 开关、二维码/验证码流程、错误态 |
|
||
|
||
### 6.9 Settings:人员、角色、组织
|
||
|
||
来源:`agents`、`teams`、`customRoles`、`assignmentPolicy`、`agentBots`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Agents | 设置 → Agents | 列表、新建/邀请、编辑、状态、重置密码 |
|
||
| Teams | 设置 → Teams | 列表、新建、编辑、成员管理 |
|
||
| Custom Roles | 设置 → Custom Roles | 角色列表、权限矩阵、创建/编辑、绑定用户 |
|
||
| Assignment Policy | 设置 → Assignment Policy | 规则列表、创建、编辑、Inbox 绑定 |
|
||
| Agent Bots | 设置 → Agent Bots | 列表、创建、编辑、绑定 inbox、token/配置可见性 |
|
||
|
||
### 6.10 Settings:Inbox 与渠道
|
||
|
||
来源:`settings/inbox` 及其 channels 页面。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Inbox 列表 | 设置 → Inboxes | 列表、搜索/筛选、进入详情 |
|
||
| 新建 Inbox 向导 | Add Inbox | 类型选择、步骤推进、校验、完成页 |
|
||
| Inbox 通用配置 | Inbox 详情 → Configuration | 名称、欢迎语、营业时间、sender name、锁单会话、保存 |
|
||
| Collaborators | Inbox 详情 → Collaborators | agent 绑定、移除、分配策略联动 |
|
||
| Customer Satisfaction | Inbox 详情 → CSAT | 开关、模板、survey rules、保存 |
|
||
| Voice Configuration | Voice inbox 子页 | voice 配置项、降级态 |
|
||
| Pre-chat Form | Website inbox 子页 | 字段增删改、必填、排序、预览 |
|
||
| Fake 渠道页 | Add Inbox / Inbox detail | Fake inbox 创建、配置、消息链路联调 |
|
||
| Website 渠道页 | Add Inbox / Inbox detail | website token、域名、widget 外观、预聊天 |
|
||
| API 渠道页 | Add Inbox / Inbox detail | API inbox 创建、可用 token/endpoint 文案 |
|
||
| Email 渠道页 | Add Inbox / Inbox detail | IMAP/SMTP 表单、校验、保存、错误提示 |
|
||
| SMS/Twilio/WhatsApp/Telegram/Facebook/Instagram/Line/Twitter/TikTok/Voice | 各渠道入口 | 页面挂载、核心表单、OAuth 或外部依赖降级态、保存校验 |
|
||
|
||
### 6.11 Settings:标签、属性、模板、自动化
|
||
|
||
来源:`labels`、`attributes`、`canned`、`macros`、`automation`、`conversationWorkflow`、`sla`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Labels | 设置 → Labels | 列表、新建、编辑、删除 |
|
||
| Custom Attributes | 设置 → Attributes | contact/conversation/company 三类定义 CRUD |
|
||
| Canned Responses | 设置 → Canned Responses | 列表、新建、搜索、插入回复框 |
|
||
| Macros | 设置 → Macros | 列表、新建、编辑、执行 |
|
||
| Automation | 设置 → Automation | 列表、新建、编辑、clone、删除、条件动作校验 |
|
||
| Conversation Workflow | 设置 → Workflow | 工作流配置、保存、回显 |
|
||
| SLA | 设置 → SLA | 策略列表、创建、编辑、适用范围 |
|
||
|
||
### 6.12 Settings:集成、审计、账单、Copilot 设置
|
||
|
||
来源:`integrations`、`auditlogs`、`billing`、`settings/copilot`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Integrations | 设置 → Integrations | webhook/integration 列表、创建、编辑、删除 |
|
||
| Audit Logs | 设置 → Audit Logs | 列表、时间排序、筛选、详情 |
|
||
| Billing | 设置 → Billing | 页面渲染、受限计划文案、外链或升级入口 |
|
||
| Copilot Settings | 设置 → Copilot | provider 配置、chat model、embedding model、base URL、保存与验证 |
|
||
|
||
### 6.13 Campaigns
|
||
|
||
来源:`campaigns.routes.js`、`M07`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Live Chat Campaigns | 左侧/菜单进入 Campaigns | ongoing 列表、创建、编辑、启停 |
|
||
| SMS Campaigns | Campaigns 子页 | one-off 列表、创建、schedule、受众 |
|
||
| WhatsApp Campaigns | Campaigns 子页 | feature flag、列表、创建、错误态/空态 |
|
||
|
||
### 6.14 Help Center
|
||
|
||
来源:`helpcenter.routes.js`、`M09`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Portal 列表 | 左侧“帮助中心” | portal 列表、切换、空态 |
|
||
| 新建 Portal | 帮助中心 → 新建 | 基本信息、保存、返回 |
|
||
| Articles 列表 | portal 内文章页 | 列表、tab、过滤、进入编辑 |
|
||
| New/Edit Article | portal 文章页按钮 | 新建、编辑、保存、预览 |
|
||
| Categories | portal 分类页 | 列表、新建、编辑、跳文章列表 |
|
||
| Locales | portal locales 页 | locale 列表、切换、多语言入口 |
|
||
| Portal Settings | portal settings 页 | 设置项加载、保存、异常态 |
|
||
| Public Preview | article preview | 公共预览页渲染、内容一致 |
|
||
|
||
### 6.15 Widget / Public Surface
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Website widget | website inbox 生成的入口 | 打开 widget、预聊天表单、建会话、收发消息 |
|
||
| Public CSAT | CSAT public 页 | 页面渲染、评分、提交、回显 |
|
||
| Public help center | public portal 链接 | portal 首页、分类、文章、搜索 |
|
||
|
||
### 6.16 Captain / Copilot / AI
|
||
|
||
来源:`dashboard/captain/captain.routes.js`、`settings/copilot`、`M10`。
|
||
|
||
| 页面组 | 真实入口 | 需验证的特性功能点 |
|
||
|---|---|---|
|
||
| Assistants 列表/空态 | 左侧 Captain | 列表、默认重定向、创建入口 |
|
||
| Assistant Settings | Captain → assistant → settings | 基本信息、system prompt、控制项、删除/切换 |
|
||
| Assistant FAQs / Responses | Captain → FAQs | 列表、搜索、创建、编辑、pending 切换 |
|
||
| Documents | Captain → documents | 列表、上传、状态、重试、删除 |
|
||
| Inboxes | Captain → inboxes | 关联 inbox、解除关联 |
|
||
| Playground | Captain → playground | 输入问题、获得回答、错误态、loading |
|
||
| Guardrails / Guidelines / Scenarios | Captain 子页 | 列表、新增、编辑、删除、保存 |
|
||
| Custom Tools | Captain → tools | 列表、新建、编辑、调用配置 |
|
||
| Copilot in message composer | 会话回复框 | rewrite、reply suggestions、生成失败提示 |
|
||
|
||
## 7. 推荐执行顺序
|
||
|
||
避免一开始就被局部页面问题拖住,建议按这个顺序跑:
|
||
|
||
1. 登录页 → dashboard 主壳
|
||
2. 会话列表 → 单会话 → fake 收发闭环
|
||
3. 联系人 / 公司 / 搜索
|
||
4. 报表
|
||
5. Settings 主链(General、Agents、Teams、Inboxes、Labels、Automation)
|
||
6. Help Center / Campaigns / Public / Widget
|
||
7. Captain / Copilot / AI
|
||
8. 权限边界、刷新恢复、异常态回归
|
||
|
||
## 8. 影响“全量实际功能测试”的数据缺口
|
||
|
||
下面这些对象如果不补齐,很多页面只能测到“能渲染”或“空态”,不能测到真实功能。
|
||
|
||
### 8.1 第一层:主链路必须先有
|
||
|
||
| 数据对象 | 最低要求 | 影响页面/功能 |
|
||
|---|---:|---|
|
||
| 管理员账号 | 1 个 | 登录、所有 Settings、报表、Captain |
|
||
| 普通 agent | 2 个 | 分配、协作、team、mentions、参与者、在线状态 |
|
||
| custom role 用户 | 1 个 | 权限边界、菜单裁剪、受限页 |
|
||
| Fake inbox `fake_01` | 1 个 | fake 消息主链路、会话实时测试 |
|
||
| Website inbox | 1 个 | widget、pre-chat form、campaign、portal 关联 |
|
||
| 基础会话池 | 6~12 条 | 会话列表、过滤、报表、搜索 |
|
||
| 基础消息池 | 每会话至少 3 条 | 时间线、报表、搜索、状态流转 |
|
||
|
||
### 8.2 第二层:CRM 与过滤能力必须有
|
||
|
||
| 数据对象 | 最低要求 | 影响页面/功能 |
|
||
|---|---:|---|
|
||
| Contacts | 8+ | 联系人列表、分页、搜索、合并、标签 |
|
||
| Companies | 3+ | 公司列表、详情、关联联系人 |
|
||
| Labels | 5+ | 会话/联系人标签、报表、自动化条件 |
|
||
| Teams | 2+ | 分配、team 视图、报表 |
|
||
| Contact custom attributes | 2+ | 联系人详情、自定义筛选 |
|
||
| Conversation custom attributes | 2+ | 自动化条件、详情、自定义筛选 |
|
||
| Company custom attributes | 2+ | 公司详情、属性设置页 |
|
||
|
||
### 8.3 第三层:设置与提效页面必须有
|
||
|
||
| 数据对象 | 最低要求 | 影响页面/功能 |
|
||
|---|---:|---|
|
||
| Canned responses | 3+ | 设置页 CRUD、回复框插入 |
|
||
| Macros | 3+ | 宏列表、编辑、执行 |
|
||
| Automation rules | 3+ | 列表、编辑、clone、条件动作验证 |
|
||
| Assignment policies | 2+ | 策略列表、Inbox 绑定 |
|
||
| SLA policies | 2+ | SLA 设置页、SLA 报表 |
|
||
| Notifications | 5+ | 通知中心、已读/未读、跳转 |
|
||
| Audit logs | 5+ | 审计日志页 |
|
||
|
||
### 8.4 第四层:报表与公共能力必须有
|
||
|
||
| 数据对象 | 最低要求 | 影响页面/功能 |
|
||
|---|---:|---|
|
||
| CSAT responses | 5+ | CSAT 报表、公共 CSAT 页面 |
|
||
| Reporting rollups / events | 连续 7 天内有数据 | 总览、客服/标签/团队/收件箱 drilldown |
|
||
| Help center portal | 1 套 | portal 列表、settings、public page |
|
||
| Categories | 2+ | 帮助中心分类页 |
|
||
| Articles | 5+ | 文章列表、预览、编辑、搜索 |
|
||
| Locales | 2+ | 多语言切换、locale 页面 |
|
||
| Campaigns | live chat / sms / whatsapp 各至少 1 | Campaigns 页面和调度状态 |
|
||
|
||
### 8.5 第五层:AI 页面必须有
|
||
|
||
| 数据对象 | 最低要求 | 影响页面/功能 |
|
||
|---|---:|---|
|
||
| Copilot 配置 | 1 套可保存配置 | Copilot 设置页、回复框 AI 功能 |
|
||
| Assistant | 1 个 | Captain 主入口、详情子页 |
|
||
| Assistant responses / FAQs | 5+ | FAQ 列表、pending、搜索 |
|
||
| Assistant documents | 3+ | 文档列表、状态、重试 |
|
||
| Assistant scenarios | 2+ | scenario 页 |
|
||
| Assistant guidelines / guardrails | 各 2+ | 子页编辑和展示 |
|
||
| Custom tools | 1+ | tools 页面 |
|
||
|
||
### 8.6 基于当前三服务 + smoke seed 的“已覆盖 / 仍缺”结论
|
||
|
||
这一节是把“仓库当前已有 smoke seed 能力”和“做全量真实功能测试仍然欠缺的数据”分开说,避免后续误判。
|
||
|
||
当前 `cd backend && go run ./cmd/gochat seed` 已能稳定准备出这些对象:
|
||
|
||
| 当前 smoke seed 已覆盖 | 当前状态 | 说明 |
|
||
|---|---|---|
|
||
| 管理员账号 | 已覆盖 | 默认可登录 `admin@gochat.local / changeme` |
|
||
| 1 个 website inbox | 已覆盖 | `Test Website Inbox`,含 `website_token` |
|
||
| 1 个 voice inbox | 已覆盖 | `Smoke Voice Inbox` |
|
||
| 1 个 company + 1 个 contact | 已覆盖 | `Smoke Company` / `Smoke Customer` |
|
||
| 1 条 open 会话 + 3 条消息 | 已覆盖 | 仅够做最小烟测,不够覆盖列表/过滤/报表 |
|
||
| 1 套 help center portal/category/article | 已覆盖 | 仅 1 portal、1 category、1 article |
|
||
| 1 条 SLA policy | 已覆盖 | 仅最小样本 |
|
||
| 1 个 custom role / 1 个 capacity policy | 已覆盖 | 仅可验证页面首屏和单对象详情 |
|
||
| 1 个 Captain assistant / 1 条 Captain message / 1 个 agent bot | 已覆盖 | 只够做 AI 页面初始挂载,不够测多对象和主链路 |
|
||
|
||
但基于你当前已经手动启动的三项服务,下面这些仍然是会影响“全量实际功能测试”结论的缺口:
|
||
|
||
| 当前仍缺 | 最低补齐要求 | 为什么仍然卡全量测试 |
|
||
|---|---:|---|
|
||
| fake inbox `fake_01` 在 GoChat 内完成建档与关联 | 1 个 | `pnpm fake:start` 只启动 fake 平台,不会自动在 GoChat 里创建 fake inbox |
|
||
| 第二个可登录 agent | 1 个 | 目前 smoke seed 只有管理员,没有第二坐席,无法测分配/协作/在线状态/mentions |
|
||
| custom role 绑定到真实用户 | 1 个用户 | 仅有 role 定义不足以验证菜单裁剪和权限边界 |
|
||
| 多状态会话池 | 6~12 条 | 当前只有 1 条 open 会话,缺 pending/resolved/snoozed/unassigned 等 |
|
||
| 更丰富消息类型 | 每会话再补 2~3 条 | 当前主要是 text + 1 条 CSAT 模板,不够覆盖 private note/附件/状态流转 |
|
||
| CRM 列表数据 | contacts 8+、companies 3+ | 当前 1 个联系人、1 个公司不足以测分页、搜索、合并、联动 |
|
||
| labels / teams | labels 5+、teams 2+ | 影响过滤、报表、自动化条件、team 视图 |
|
||
| canned responses / macros / automation rules | 各 3+ | 设置页能打开,但无法验证真实 CRUD 与执行 |
|
||
| notifications / audit logs | 各 5+ | 否则只能测空态,不能测跳转、已读、筛选 |
|
||
| help center 丰富数据 | categories 2+、articles 5+、locales 2+ | 当前 smoke help center 只有单文章样本 |
|
||
| campaigns 丰富样本 | live chat / sms / whatsapp 各 1 | 当前很难证明列表、状态和调度是真实可用 |
|
||
| AI fixtures | FAQ 5+、documents 3+、scenarios 2+、guardrails/guidelines 各 2+、tool 1+ | 当前 Captain 页面大多只能停留在 render-only 或单对象样本 |
|
||
|
||
### 8.7 模块与数据依赖映射
|
||
|
||
这一节是给后续执行时快速判断“为什么这个页面现在只能测到一半”。
|
||
|
||
| 模块 | 没有这些数据时会退化成什么 | 需要补的最低数据 |
|
||
|---|---|---|
|
||
| 会话列表 / 详情 | 只能验证空态或单条样本,无法验证状态切换、分配、报表回流 | `fake_01` inbox、6~12 条多状态会话、每会话 3+ 消息、2 个 agent、2 个 team、5 个 labels |
|
||
| Inbox View / Mentions / Participating / Unattended | 只能验证入口和空态,无法验证计数、协作、提醒链路 | 第二个 agent、至少 1 条 mention、1 条 participating、1 条 unattended 会话 |
|
||
| 联系人 / 公司 | 只能验证首屏挂载,无法验证搜索、分页、合并、交叉跳转 | contacts 8+、companies 3+、带标签联系人 3+、带公司联系人 3+ |
|
||
| 全局搜索 | 容易出现“空结果”和“真没索引”混淆 | 会话、联系人、文章、消息各自至少 3 条可命中样本 |
|
||
| 报表 | 只能看图表壳和空图,无法验证趋势与 drilldown | 连续 7 天事件、不同 inbox/team/label/agent 维度数据、CSAT 5+、SLA 命中样本 3+ |
|
||
| Agents / Teams / Roles / Assignment | 只能看列表壳,无法验证权限、分配、成员管理 | 2 个普通 agent、1 个 custom-role user、2 个 teams、2 个 assignment policies |
|
||
| Inboxes / Channels | 只能验证 website/voice/fake 的部分页面,很多渠道只能测降级态 | `fake_01`、website inbox、voice inbox、至少 1 个配置过 webhook/OAuth 的可回显样本 |
|
||
| Labels / Attributes / Macros / Automation | 只能验证空态或新建入口,无法验证编辑与实际执行 | labels 5+、三类 custom attributes 各 2+、canned responses 3+、macros 3+、automation 3+ |
|
||
| Notifications / Audit Logs | 只能看空态,无法验证跳转、筛选、时间排序 | notifications 5+、audit logs 5+ |
|
||
| Help Center / Public | 只能看单 portal、单文章,无法验证多语言和分类切换 | portal 1+、categories 2+、articles 5+、locales 2+ |
|
||
| Campaigns | 只能看页面框架,无法验证状态流转和调度 | live chat / sms / whatsapp campaigns 各 1+ |
|
||
| Captain / Copilot / AI | 只能验证静态渲染或 provider disabled 提示,不能验证真实生成链路 | copilot config 1 套、assistant 1+、FAQ 5+、documents 3+、scenarios 2+、guidelines/guardrails 各 2+、custom tools 1+、`fake:ai` |
|
||
|
||
## 9. 数据补齐建议
|
||
|
||
按投入产出比,建议这样补:
|
||
|
||
### 9.1 执行前一次性准备
|
||
|
||
- 管理员 1 个
|
||
- agent 2 个
|
||
- custom role 用户 1 个
|
||
- `fake_01` inbox
|
||
- website inbox
|
||
- 至少 6 条不同状态会话
|
||
- 至少 8 个联系人、3 个公司、5 个标签、2 个团队
|
||
|
||
### 9.2 执行过程中顺手创建
|
||
|
||
- canned responses
|
||
- macros
|
||
- automation rules
|
||
- custom attributes
|
||
- help center portal / categories / articles
|
||
|
||
### 9.3 执行前最好补成假数据或脚本造数
|
||
|
||
- 报表连续日期数据
|
||
- CSAT responses
|
||
- SLA 命中/超时样本
|
||
- notifications / audit logs
|
||
- AI 相关对象
|
||
|
||
### 9.4 建议的数据补齐顺序
|
||
|
||
为了尽快进入“可持续追加证据”的阶段,建议按下面顺序准备:
|
||
|
||
1. 先确认 smoke seed 基线可登录、可见。
|
||
2. 在 GoChat 内补出 `fake_01` inbox,并和当前 fake 平台 webhook 对齐。
|
||
3. 再补第二个 agent、teams、labels、6~12 条多状态会话。
|
||
4. 接着补 CRM 列表数据、canned responses、macros、automation rules。
|
||
5. 最后补报表连续数据、notifications / audit logs、以及 `fake:ai` 相关 AI fixtures。
|
||
|
||
### 9.5 建议的数据来源与造数方式
|
||
|
||
为了避免后续执行时一边测一边猜“这条数据该怎么补”,这里把推荐来源固定下来:
|
||
|
||
| 数据 / 对象 | 优先来源 | 推荐方式 | 备注 |
|
||
|---|---|---|---|
|
||
| 管理员、website inbox、基础 smoke company/contact/conversation、help center 初始对象 | `cmd/gochat seed` | `cd backend && go run ./cmd/gochat seed` | 作为最小可登录与可见基线 |
|
||
| `fake_01` inbox 建档 | GoChat 后台 UI | Settings → Inboxes → Add Inbox → Fake | `pnpm fake:start` 只启动外部 fake 平台,不会自动在 GoChat 内建 inbox |
|
||
| fake 会话 / 客户消息 / 回复回流 | `channels/fake` | `POST /api/send`、`POST /api/reply`、`POST /api/close`、`POST /api/typing` | 适合造 open/pending/resolved/snoozed 前的消息样本 |
|
||
| agent 在线/离线观测样本 | `channels/fake` | `POST /api/agent/online`、`POST /api/agent/offline` | 主要用于 presence/UI 观测,不替代真实坐席登录 |
|
||
| 第二个 agent、custom-role user | GoChat 后台 UI 或 seed 扩容 | Settings → Agents / Roles | 若要稳定回归,后续更适合补进 seed |
|
||
| teams、labels、custom attributes、canned responses、macros、automation | GoChat 后台 UI | 直接通过设置页创建 | 这样既补数据,也顺手覆盖 CRUD |
|
||
| contacts、companies 丰富样本 | 优先 UI,必要时 seed 扩容 | CRM 页面新增;批量时可走 seed | 少量样本适合 UI,批量搜索/分页样本适合 seed |
|
||
| 多状态会话池 | fake 平台 + GoChat UI 操作 | 先 fake 造会话,再通过 UI 做 assign/resolve/snooze/label/team | 最贴近真实用户行为,也最利于回放 |
|
||
| notifications、audit logs、连续报表事件 | 定向脚本 / seed 扩容 / 真实操作回灌 | 不建议纯手工补齐 | 这些数据量大、时间维度强,最好脚本化 |
|
||
| FAQ、documents、scenarios、guardrails、custom tools | Captain UI + `fake:ai` | 先配 Copilot,再在 Captain 内创建 | 没有 `fake:ai` 时只能测渲染或 disabled fallback |
|
||
| Copilot provider 配置 | Settings → Copilot | 指向本地 `fake:ai` | 建议 chat / embedding 都走 `openai_compatible` |
|
||
|
||
补充建议:
|
||
|
||
- fake 平台现成可用的观测接口包括 `GET /api/messages`、`GET /api/status`、`POST /api/reset`,适合在 CDP 操作前后核对消息链路是否闭环。
|
||
- 如果某一类数据预计需要长期复用,优先考虑补进 `seed` 或专用 bootstrap,而不是依赖人工临时点出来。
|
||
- 若某页面的验证目标本身就是“创建对象”,那一类对象不需要在执行前全量准备,只需要留一个最小可进入基线即可。
|
||
|
||
## 10. `fake:ai` 支撑方案
|
||
|
||
AI 相关页面如果继续依赖真实外部模型,会让本地 CDP 测试变成“不稳定、不可重复、不可回放”。这里建议直接仿照 `channels/fake` 新增一个本地 `fake:ai`。
|
||
|
||
### 10.1 设计目标
|
||
|
||
`fake:ai` 的目标不是伪装“聪明模型”,而是提供一个:
|
||
|
||
- 本地可启动
|
||
- 响应确定
|
||
- 可人为切换成功/失败/限流/慢响应
|
||
- 能记录最近请求
|
||
- 能兼容 GoChat 当前 `openai_compatible` provider 的最小实现
|
||
|
||
### 10.2 现有代码约束
|
||
|
||
当前仓库里:
|
||
|
||
- 根 `package.json` 已有 `fake:start`,但还没有 `fake:ai`
|
||
- `pnpm-workspace.yaml` 当前只包含 `frontend` 和 `channels/fake`
|
||
- `backend/internal/llm/openai_provider.go` 会向 `baseURL + /chat/completions` 和 `baseURL + /embeddings` 发请求
|
||
- `provider_manager.go` 已支持 `openai_compatible`
|
||
- `backend/internal/llm/openai_provider.go` 已实现 `ChatCompletionStream`
|
||
|
||
这意味着:
|
||
|
||
- 不需要先改 GoChat 的 provider 抽象
|
||
- 只需要补一个本地 OpenAI-compatible 假服务
|
||
- 若 `fake:ai` 监听 `9110`,GoChat 里的 `base_url` 应配置成 `http://127.0.0.1:9110/v1`
|
||
- 如果 `Captain Playground` 或会话回复框的 AI 路径走流式输出,`fake:ai` 不能只实现非流式 JSON 返回
|
||
|
||
### 10.3 最小接口面
|
||
|
||
首批必须有:
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| `GET` | `/health` | 健康检查 |
|
||
| `POST` | `/v1/chat/completions` | Captain/Copilot 文本生成 |
|
||
| `POST` | `/v1/embeddings` | 文档索引、检索、语义功能 |
|
||
| `POST` | `/api/scenario` | 切换响应模式 |
|
||
| `GET` | `/api/requests` | 查看最近请求,便于断言 |
|
||
| `POST` | `/api/reset` | 清空内存状态 |
|
||
|
||
建议首批也支持:
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| `GET` | `/v1/models` | provider 测试或后续扩展 |
|
||
| `POST` | `/v1/chat/completions` with `stream=true` | 覆盖流式生成路径 |
|
||
|
||
建议补一个最小场景切换请求体,便于后续浏览器测试直接复用:
|
||
|
||
```json
|
||
{
|
||
"scenario": "ok",
|
||
"delay_ms": 0,
|
||
"response_text": "[fake:ai][scenario=ok] hello from fake ai"
|
||
}
|
||
```
|
||
|
||
### 10.3.1 建议直接固定的 OpenAI-compatible 契约
|
||
|
||
为了避免后续 `fake:ai` 做出来以后,还要反复因为字段不对去排查 GoChat provider,这里建议第一版就固定成下面这组最小契约。
|
||
|
||
`POST /v1/chat/completions` 最低接受:
|
||
|
||
```json
|
||
{
|
||
"model": "fake-gpt-4o-mini",
|
||
"messages": [
|
||
{ "role": "system", "content": "You are a QA fake." },
|
||
{ "role": "user", "content": "Say hello" }
|
||
],
|
||
"temperature": 0,
|
||
"stream": false
|
||
}
|
||
```
|
||
|
||
非流式成功响应建议至少返回:
|
||
|
||
```json
|
||
{
|
||
"id": "chatcmpl_fake_001",
|
||
"object": "chat.completion",
|
||
"created": 1784332800,
|
||
"model": "fake-gpt-4o-mini",
|
||
"choices": [
|
||
{
|
||
"index": 0,
|
||
"message": {
|
||
"role": "assistant",
|
||
"content": "[fake:ai][scenario=ok] hello from fake ai"
|
||
},
|
||
"finish_reason": "stop"
|
||
}
|
||
],
|
||
"usage": {
|
||
"prompt_tokens": 12,
|
||
"completion_tokens": 8,
|
||
"total_tokens": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
如果 `stream=true`,建议返回最小 SSE 片段序列:
|
||
|
||
```text
|
||
data: {"id":"chatcmpl_fake_002","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"[fake:ai]"},"finish_reason":null}]}
|
||
|
||
data: {"id":"chatcmpl_fake_002","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" hello from fake ai"},"finish_reason":null}]}
|
||
|
||
data: {"id":"chatcmpl_fake_002","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
|
||
|
||
data: [DONE]
|
||
```
|
||
|
||
`POST /v1/embeddings` 最低接受:
|
||
|
||
```json
|
||
{
|
||
"model": "fake-text-embedding-3-small",
|
||
"input": "hello from fake embedding"
|
||
}
|
||
```
|
||
|
||
成功响应建议至少返回:
|
||
|
||
```json
|
||
{
|
||
"object": "list",
|
||
"data": [
|
||
{
|
||
"object": "embedding",
|
||
"index": 0,
|
||
"embedding": [0.01, 0.02, 0.03, 0.04]
|
||
}
|
||
],
|
||
"model": "fake-text-embedding-3-small",
|
||
"usage": {
|
||
"prompt_tokens": 4,
|
||
"total_tokens": 4
|
||
}
|
||
}
|
||
```
|
||
|
||
注意点:
|
||
|
||
- 第一版 embedding 建议直接返回与 GoChat 配置一致的固定维度,默认优先按 `1536` 实现。原因有两个:一是当前 `CopilotConfigService.Test()` 会校验返回向量长度是否等于配置里的 `dimensions`;二是 `captain_assistant_responses.embedding` 仍是 `vector(1536)`。虽然 `article_embeddings.vector_embedding` 已改成动态维度,但如果 `fake:ai` 先返回 4 维之类的短向量,本地 Copilot 健康检查和部分 Captain 索引路径会先失败。
|
||
- 如果后续明确把 Copilot 配置里的 `dimensions` 改成其他值,再同步让 `fake:ai` 返回同维度向量;不要把“接口能通”和“维度真实兼容”混为一谈。
|
||
- 所有响应里的 `model` 建议回显请求中的模型名,便于在 QA 证据里确认当前页面到底打到了哪条配置。
|
||
- `created`、`id`、`usage` 不要求真实,但建议稳定、可预测,避免前端因为缺字段误判为 provider 异常。
|
||
|
||
### 10.4 `fake:ai` 与页面功能点映射
|
||
|
||
`fake:ai` 不是单纯给 Captain playground 用的,它至少要覆盖下面这些实际测试点:
|
||
|
||
| 页面/功能 | 依赖能力 | 没有 `fake:ai` 会发生什么 |
|
||
|---|---|---|
|
||
| 设置 → Copilot 配置 → 测试/保存 | `POST /v1/chat/completions`、`POST /v1/embeddings` | 只能停留在表单渲染,无法验证 provider 配置真可用 |
|
||
| Captain Playground | chat completions,最好支持 stream | 只能测输入框和 loading,不能测回答内容与失败提示 |
|
||
| Captain FAQ / response 生成 | chat completions | 无法验证生成 FAQ、approve/reject 前后的主链路 |
|
||
| Captain Documents 同步 / 处理 | embeddings | 无法验证文档处理、索引、状态从 syncing 到 synced |
|
||
| Copilot rewrite / suggest replies / summarize / translate | chat completions,部分路径建议 stream | 只能验证按钮存在,无法验证生成文本回填 |
|
||
| 会话里的 label suggestion / follow-up / participant insights | chat completions | 只能验证入口或 provider disabled fallback |
|
||
| AI 错误回归 | `error` / `rate_limit` / `slow` scenario | 无法稳定复现错误提示、重试、超时 UI |
|
||
|
||
补充约束:
|
||
|
||
- `fake:ai` 必须接受 `Authorization: Bearer ...` 头,即使服务端不真的校验,也要保证请求不会因为缺少解析而失败。
|
||
- `/api/requests` 返回的观测数据必须脱敏 `Authorization`、`api_key`、`base_url` 之外的秘密字段,避免把本地测试密钥直接写进 QA 证据。
|
||
- chat completion 成功响应建议固定带 `[fake:ai][scenario=...]` 前缀,这样 CDP 报告里能一眼看出当前结果来自本地假服务,而不是误连到了外部模型。
|
||
|
||
## 11. `fake:ai` 场景模式
|
||
|
||
至少支持下面几类 scenario:
|
||
|
||
| scenario | 行为 | 主要用途 |
|
||
|---|---|---|
|
||
| `ok` | 固定成功返回 | 基础页面通过 |
|
||
| `slow` | 延迟 2~5 秒后成功 | loading、取消、超时 UI |
|
||
| `error` | 500 错误体 | 错误提示、重试 |
|
||
| `rate_limit` | 429 错误体 | 限流提示 |
|
||
| `empty` | 成功但内容为空 | 空建议、空生成态 |
|
||
| `tool_call_stub` | 返回可预测 tool call 结构 | 未来 custom tools 联调 |
|
||
|
||
### 11.1 返回内容约束
|
||
|
||
为了让断言稳定,建议所有成功响应都带可识别前缀,例如:
|
||
|
||
- chat completion 返回:`[fake:ai][scenario=ok] ...`
|
||
- embedding 返回固定长度向量,例如 1536 维
|
||
|
||
这样可以在:
|
||
|
||
- Copilot 设置页的验证请求
|
||
- Captain playground
|
||
- 会话回复框 rewrite/suggestion
|
||
- 文档 embedding 索引
|
||
|
||
里快速判断链路是否走到了本地 `fake:ai`。
|
||
|
||
### 11.2 流式返回建议
|
||
|
||
由于 GoChat 当前 provider 代码已经实现 `ChatCompletionStream`,`fake:ai` 最好首批就支持 SSE chunk 流式返回,避免后续 Playground 或 Copilot 某些路径只能测非流式。
|
||
|
||
推荐最小流式行为:
|
||
|
||
- `Content-Type: text/event-stream`
|
||
- 至少返回 2~3 个 `data:` chunk
|
||
- 末尾返回 `[DONE]`
|
||
|
||
## 12. `fake:ai` 的仓库落地建议
|
||
|
||
建议直接对齐 `channels/fake` 的组织方式:
|
||
|
||
| 项 | 建议 |
|
||
|---|---|
|
||
| 目录 | `channels/fake-ai` |
|
||
| 启动脚本 | 根 `package.json` 增加 `fake:ai` / `fake:ai:dev` / `fake:ai:test` |
|
||
| workspace | `pnpm-workspace.yaml` 增加 `channels/fake-ai` |
|
||
| 默认端口 | `9110` |
|
||
| 默认模型名 | `fake-gpt-4o-mini`、`fake-text-embedding-3-small` |
|
||
| 观测接口 | `/api/requests`、`/api/reset`、`/api/scenario` |
|
||
|
||
### 12.1 目录与脚本骨架建议
|
||
|
||
建议 `fake:ai` 第一版直接复用 `channels/fake` 的组织习惯,这样后续维护和理解成本最低:
|
||
|
||
```text
|
||
channels/fake-ai/
|
||
├── package.json
|
||
├── tsconfig.json
|
||
├── README.md
|
||
├── src/
|
||
│ ├── index.ts
|
||
│ ├── server.ts
|
||
│ ├── types.ts
|
||
│ ├── scenarios.ts
|
||
│ └── store/
|
||
│ └── memory-store.ts
|
||
└── tests/
|
||
└── integration.test.ts
|
||
```
|
||
|
||
根目录建议补这些脚本:
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"fake:ai": "cd channels/fake-ai && tsx src/index.ts",
|
||
"fake:ai:dev": "cd channels/fake-ai && tsx watch src/index.ts",
|
||
"fake:ai:test": "pnpm --dir channels/fake-ai test"
|
||
}
|
||
}
|
||
```
|
||
|
||
`pnpm-workspace.yaml` 也建议同步补:
|
||
|
||
```yaml
|
||
packages:
|
||
- frontend
|
||
- channels/fake
|
||
- channels/fake-ai
|
||
```
|
||
|
||
这样做的好处很直接:
|
||
|
||
- `fake:start` 与 `fake:ai` 的心智模型一致,后续谁来接手都容易理解。
|
||
- message fake 和 AI fake 都可以保留自己的 `/health`、`/api/reset`、`/api/requests`,不会互相污染。
|
||
- 后续如果要把 `dev:all` 扩成包含 AI 的本地联调模式,也只是在根脚本上追加一个并发进程,不需要重构现有 fake channel。
|
||
|
||
建议默认启动命令:
|
||
|
||
```bash
|
||
FAKE_AI_PORT=9110 pnpm fake:ai
|
||
```
|
||
|
||
在 GoChat Copilot 配置里建议填:
|
||
|
||
| 配置项 | 建议值 |
|
||
|---|---|
|
||
| chat provider | `openai_compatible` |
|
||
| chat base_url | `http://127.0.0.1:9110/v1` |
|
||
| chat model | `fake-gpt-4o-mini` |
|
||
| embedding provider | `openai_compatible` |
|
||
| embedding base_url | `http://127.0.0.1:9110/v1` |
|
||
| embedding model | `fake-text-embedding-3-small` |
|
||
|
||
## 13. 完成定义
|
||
|
||
后续要对外说“CDP 全量功能测试完成”,至少要满足下面条件:
|
||
|
||
1. 第 6 节所有页面组都已有一条最终结论。
|
||
2. 每个页面组都留下点击链路和关键 API 证据。
|
||
3. 第 8 节的数据缺口已补齐,或在报告里明确标注哪些仍是 `blocked`。
|
||
4. fake 会话主链路已完成真实闭环。
|
||
5. AI 页面不再依赖真实外部 Key,而是通过 `fake:ai` 完成稳定回归。
|
||
6. 结果统一沉淀在既有 QA report 中,而不是散落在聊天记录里。
|
||
|
||
## 14. 本轮建议的直接下一步
|
||
|
||
建议按下面顺序推进:
|
||
|
||
1. 先补齐 `fake:ai` 的文档与实现计划。
|
||
2. 先准备最小可用测试数据:管理员、2 个 agent、`fake_01`、website inbox、6~12 条会话、8 个联系人、3 个公司。
|
||
3. 再继续按本计划做 click-only CDP 覆盖,并把证据追加到既有 report。
|