1091 lines
53 KiB
Markdown
1091 lines
53 KiB
Markdown
# 2026-07-17 GoChat CDP 用户功能全量测试计划
|
||
|
||
> 创建:2026-07-17
|
||
> 最后更新:2026-07-19
|
||
> 目标:基于已手动启动的 `backend + frontend + fake channel`,通过 CDP 按真实用户点击路径完成 GoChat 各页面功能验收,并明确补齐哪些数据与 `fake:ai` 能力后,才能做“全量实际功能测试”。
|
||
|
||
## 1. 本轮输入前提
|
||
|
||
你已经手动启动:
|
||
|
||
```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`
|
||
- backend: `http://127.0.0.1:3000`
|
||
- fake channel: `http://127.0.0.1:9100`
|
||
- Chrome CDP: 优先复用现有 `127.0.0.1:9222`
|
||
|
||
关联资产:
|
||
|
||
- 既有计划:[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/reports/2026-07-15-cdp-user-function-report.md](/home/rogee/Projects/gochat/docs/qa/reports/2026-07-15-cdp-user-function-report.md)
|
||
|
||
这份文档的角色不是重复旧计划,而是把“页面级功能点覆盖”和“全量测试所缺数据/AI 桩能力”整理成可直接执行的版本。
|
||
|
||
### 1.1 本轮文档直接产出
|
||
|
||
| 产出 | 文件/位置 | 用途 |
|
||
|---|---|---|
|
||
| CDP 全量测试执行计划 | 当前文档 | 作为后续 click-only 页面验收的唯一执行基线 |
|
||
| 页面级执行报告 | `docs/qa/reports/2026-07-15-cdp-user-function-report.md` | 持续追加 pass/fail/blocked 证据 |
|
||
| 全量测试缺口清单 | 第 8 节、第 12.4 节 | 明确哪些数据/能力不补就不能宣称“全量实际功能测试完成” |
|
||
| AI 测试支撑方案 | 第 10 节、第 11 节 | 约束 `fake:ai` 的最小落地面和接入方式 |
|
||
|
||
### 1.2 全量测试 blocker 速览
|
||
|
||
先把最影响实际执行的缺口压缩成一页,避免后续翻全文:
|
||
|
||
| 优先级 | 缺口 | 最低要求 | 不补会卡住什么 |
|
||
|---|---|---|---|
|
||
| P0 | 第二个可登录 agent | 1 个 | 分配、协作、mentions、参与者、在线状态 |
|
||
| P0 | `fake_01` inbox 建档 + webhook 回流 | 1 套 | fake 入站、客服回复、auto reply 主链路 |
|
||
| P0 | 多状态会话池 | 至少 6 条,不同 status | 会话列表、过滤、报表、回归验证 |
|
||
| P0 | CRM 非空数据 | contacts 8+、companies 3+ | 联系人/公司列表、搜索、分页、联动 |
|
||
| P0 | 标签与团队数据 | labels 5+、teams 2+ | 标签过滤、team assign、报表 |
|
||
| P0 | 本地 AI 假服务 | `fake:ai` 可用 | Captain / Copilot 只能停留在 render-only |
|
||
| P1 | 回复提效对象 | canned responses 3、macros 3、automation 3 | 回复框、宏执行、自动化页面 |
|
||
| P1 | 自定义属性 | 三类对象各 2 个 | 详情表单、筛选、自动化条件 |
|
||
| P1 | 通知 / 审计 / CSAT / SLA | notifications 5、audit logs 5、csat 5、applied sla 3 | 通知中心、审计、报表 drilldown |
|
||
| P2 | API / Email / Campaign / Help Center 丰富数据 | 各 1 套以上 | 集成配置页、campaign、locale、多语言公共页 |
|
||
|
||
### 1.3 `fake:ai` 最小落地结论
|
||
|
||
结合当前仓库的 `openai_compatible` provider 能力,这轮不需要先改 GoChat 的 provider 抽象,直接补一个本地 OpenAI-compatible 假服务即可:
|
||
|
||
| 项 | 结论 |
|
||
|---|---|
|
||
| 放置位置 | 建议新建 `channels/fake-ai`,与 `channels/fake` 维持同构 |
|
||
| 接入方式 | Captain / Copilot 配置为 `openai_compatible` + 本地 `base_url` |
|
||
| 当前代码必需接口 | `POST /v1/chat/completions`、`POST /v1/embeddings` |
|
||
| 可选补充接口 | `GET /v1/models`(便于后续扩展,但不是当前 GoChat 接入链路的必需项) |
|
||
| 最小控制面 | `GET /health`、`POST /api/scenario`、`GET /api/requests` |
|
||
| 最少模式 | `ok`、`error`、`slow`、`rate_limit` |
|
||
| 最少证据 | 记录最近请求摘要,但必须脱敏 `Authorization` / `api_key` |
|
||
|
||
### 1.4 当前代码核对结论(2026-07-18)
|
||
|
||
这部分是为了确保计划文档和当前仓库实现保持一致,不靠假设推进:
|
||
|
||
| 核对项 | 当前状态 | 对计划的影响 |
|
||
|---|---|---|
|
||
| 根 `package.json` | 只有 `fake:start` / `fake:dev` / `fake:test` | 说明 message fake 已经可跑,`fake:ai` 还没有统一启动入口 |
|
||
| `pnpm-workspace.yaml` | 只包含 `frontend` 与 `channels/fake` | 说明 `channels/fake-ai` 目前尚未纳入 workspace |
|
||
| `channels/fake-ai/` 目录 | 当前不存在 | 说明 `fake:ai` 是待新增测试支撑,而不是已有能力 |
|
||
| `backend/internal/llm/openai_provider.go` | 请求路径是 `{baseURL}/chat/completions` 与 `{baseURL}/embeddings` | 说明如果本地 `fake:ai` 监听 `9110`,GoChat 配置里的 `base_url` 应填写为 `http://127.0.0.1:9110/v1` |
|
||
| `backend/internal/llm/provider_manager.go` | 已支持 `openai_compatible` chat + embedding | 说明不需要先改 provider 抽象,优先补本地 OpenAI-compatible 假服务即可 |
|
||
|
||
### 1.5 本轮服务矩阵与待补支撑(2026-07-19)
|
||
|
||
基于本轮手工启动情况,当前可直接进入 CDP 点击测试的服务矩阵如下:
|
||
|
||
| 服务 | 当前状态 | 启动方式 | 用途 |
|
||
|---|---|---|---|
|
||
| backend | 已启动 | `pnpm dev:backend` | API、webhook、WebSocket、Captain/Copilot 后端逻辑 |
|
||
| frontend | 已启动 | `pnpm dev:frontend` | dashboard / widget / public 页面点击验收 |
|
||
| fake channel | 已启动 | `GOCHAT_WEBHOOK_URL=http://127.0.0.1:3000/webhooks/fake/fake_01 FAKE_AUTO_REPLY=true pnpm fake:start` | 外部客户消息模拟、客服出站回收、auto reply 回流 |
|
||
| fake:ai | 未启动(当前仓库也尚未提供) | 待新增 `pnpm fake:ai` | Captain / Copilot / Playground / Embedding 的可重复 AI 测试支撑 |
|
||
|
||
因此本轮测试边界应明确分成两层:
|
||
|
||
1. 非 AI 页面与消息主链路:可以立刻开始做 click-only CDP 实测。
|
||
2. AI 相关页面与任务链路:先按本计划补齐 `fake:ai`,再进入“全量实际功能测试”。
|
||
|
||
这也意味着:
|
||
|
||
- 当前三服务已足够支持会话、联系人、公司、settings、widget、public、help center 等非 AI 主链路验收。
|
||
- Captain / Copilot 在没有 `fake:ai` 前,只能做页面渲染、路由、表单、空态、错误态层面的验证,不能把结果记为 AI 功能完整通过。
|
||
|
||
## 2. 测试原则
|
||
|
||
### 2.1 导航原则
|
||
|
||
- dashboard 内部页面只允许通过真实点击进入。
|
||
- 不允许把 `/app/accounts/:id/...` deep-link 当作“通过证据”。
|
||
- 仅允许直接打开:
|
||
- 登录页 `/app/login`
|
||
- widget/public 根入口
|
||
- fake / fake:ai 观测接口
|
||
|
||
### 2.2 每个页面的统一断言
|
||
|
||
每个页面至少验证这 6 类内容:
|
||
|
||
1. 可达:能通过真实入口点击进入。
|
||
2. 可见:主区域、左导航、顶部操作区能正常渲染,不是空白壳。
|
||
3. 可载:关键 API 返回 2xx,首屏数据成功加载。
|
||
4. 可用:页面 1~3 个核心操作可以实际执行。
|
||
5. 可回:刷新或回到列表后状态保持一致。
|
||
6. 可观测:console / network / runtime exception 有据可查。
|
||
|
||
额外加一条壳层门槛:
|
||
|
||
7. 如果顶部或左侧导航点击后 URL 已变化,但主区域仍只显示 `离线的`、空白壳、Vue update error 或没有新的首屏 API,请先把它记成“壳层/挂载失败”,并暂停把后续子页算作通过。
|
||
|
||
### 2.3 缺陷分级
|
||
|
||
| 级别 | 定义 |
|
||
|---|---|
|
||
| P0 | 登录失败、主工作台不可用、消息链路断、权限越界、数据保存丢失 |
|
||
| P1 | 页面主 CRUD 不可用、关键列表/详情不加载、核心操作失败 |
|
||
| P2 | 子功能失败、边界态错误、局部入口断、错误提示缺失 |
|
||
| P3 | 文案/i18n/样式/非阻断 warning |
|
||
|
||
## 3. 执行顺序
|
||
|
||
建议按“先打通主壳,再铺页面,再补 AI”的顺序执行:
|
||
|
||
1. 环境与 CDP 连接基线
|
||
2. 登录与 dashboard 主壳
|
||
3. 会话主链路与 fake channel E2E
|
||
4. CRM 与检索
|
||
5. Settings 全量页面
|
||
6. Campaign / Help Center / Widget / Public
|
||
7. Captain / Copilot / AI 任务
|
||
8. 权限、刷新、异常态、回归重走
|
||
|
||
原因很直接:如果主壳更新、侧栏路由、主区挂载本身有问题,后面的页面覆盖会出现大片假失败。
|
||
|
||
## 4. 预检查清单
|
||
|
||
| 检查项 | 动作 | 通过标准 |
|
||
|---|---|---|
|
||
| backend health | `GET /health` | 200 |
|
||
| frontend login | 打开 `/app/login` | 登录页可见 |
|
||
| fake channel | `GET http://127.0.0.1:9100/health` | `status=ok` |
|
||
| fake 配置 | `POST /api/config` | webhook 指向 `fake_01`,auto reply 生效 |
|
||
| CDP | `GET http://127.0.0.1:9222/json/version` | 可拿到 `webSocketDebuggerUrl` |
|
||
| 管理员账号 | 实际登录 | 成功进入 account dashboard |
|
||
| websocket | 登录后观察 `/cable` | 不持续 401/403/重连风暴 |
|
||
| report sink | 确认报告文件 | 本轮证据统一追加到同一份 QA 报告 |
|
||
|
||
### 4.1 建议的 CDP 最小命令集
|
||
|
||
为了把“计划”直接衔接到后续点击执行,这里固定一套最小命令集。默认复用当前已经在本机验证过的 CDP CLI:
|
||
|
||
```bash
|
||
CDP=/home/rogee/.npm/_npx/15c61037b1978c83/node_modules/chrome-devtools-mcp/build/src/bin/chrome-devtools.js
|
||
```
|
||
|
||
建议按下面顺序做基线连接:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:9222/json/version
|
||
node "$CDP" list_pages
|
||
node "$CDP" select_page 5
|
||
node "$CDP" take_snapshot
|
||
node "$CDP" evaluate_script '() => ({ url: location.href, title: document.title, body: document.body.innerText.slice(0,1200) })'
|
||
node "$CDP" list_console_messages --pageSize 20
|
||
node "$CDP" list_network_requests --pageSize 20
|
||
```
|
||
|
||
后续进入逐页点击测试时,统一使用这 4 类动作:
|
||
|
||
| 动作 | 示例 | 用途 |
|
||
|---|---|---|
|
||
| 页面快照 | `node "$CDP" take_snapshot` | 记录当前导航树、主区、按钮文案 |
|
||
| 可见文本核对 | `node "$CDP" evaluate_script '() => document.body.innerText.slice(0,1200)'` | 判断是否是空壳、离线态、错误页 |
|
||
| 点击 | `node "$CDP" click <uid> --includeSnapshot` | 严格按真实点击进入下一页 |
|
||
| 证据回收 | `node "$CDP" list_console_messages --pageSize 20` / `node "$CDP" list_network_requests --pageSize 20` | 回收 console、API、websocket 证据 |
|
||
|
||
执行约束:
|
||
|
||
- 只把 `click` 触发的内部导航视为页面覆盖证据。
|
||
- 如果 URL 变了但主区域仍然只是 `离线的`、空白壳或 runtime error,记为失败,不算通过。
|
||
- 每切一个页面组,都至少补一次 snapshot、一次 console、一次 network。
|
||
|
||
建议额外固定一个 Gate-0:
|
||
|
||
- 从登录后的干净 dashboard 壳,至少点击 `会话 / 联系人 / 公司 / 报告 / Captain / 帮助中心 / 设置` 各 1 次。
|
||
- 只有当这些一级入口里,大多数页面都满足“主区真正换页且有对应 API 请求”时,才继续做更细颗粒的页面深测。
|
||
- 如果一级入口已经普遍出现“只变 URL、不换主区”,后续工作以定位 shell/router/store 挂载问题为先。
|
||
|
||
## 5. 页面覆盖矩阵
|
||
|
||
下面按“真实用户会走到的页面组”来拆。
|
||
|
||
### 5.1 登录与主工作台壳
|
||
|
||
| 页面组 | 入口 | 关键功能点 |
|
||
|---|---|---|
|
||
| 登录页 | `/app/login` | 登录、错误密码、输入校验、回车提交、loading 态 |
|
||
| dashboard 主壳 | 登录后默认页 | 左导航渲染、顶部搜索、当前用户、账号切换/状态、路由切换后主区更新 |
|
||
| 刷新恢复 | 任一已进入页面 | 刷新后仍在当前页,用户态不丢失 |
|
||
|
||
### 5.2 会话工作台
|
||
|
||
来源:`conversation.routes.js` 与 M03 对话/消息需求。
|
||
|
||
| 页面组 | 关键路径 | 关键功能点 |
|
||
|---|---|---|
|
||
| Dashboard 会话总览 | 会话 → 默认列表 | open/pending/resolved/snoozed 列表、分页、筛选、计数 |
|
||
| 单会话详情 | 从列表点进会话 | 消息时间线、联系人侧栏、公司侧栏、标签、优先级、分配 |
|
||
| Inbox 维度会话 | 会话 → inbox 过滤 | inbox 切换、列表过滤、单会话打开 |
|
||
| Label / Team / Mention / Unattended / Participating 视图 | 左侧子导航 | 各维度列表、计数、切换后详情 |
|
||
| 会话操作 | 详情页操作区 | 回复、private note、resolve/reopen、snooze、assign agent、assign team、add/remove label、priority |
|
||
| 消息能力 | 编辑区/附件区 | 发送文本、表情、附件、canned response、macro、reply suggestion/rewrite(后续接 fake:ai) |
|
||
| 实时性 | fake channel + dashboard | 新消息推送、已读状态、typing、auto reply 回流、无刷新更新 |
|
||
|
||
### 5.3 Inbox View / 视图切换
|
||
|
||
| 页面组 | 入口 | 关键功能点 |
|
||
|---|---|---|
|
||
| Inbox View | `inbox-view` | 按 inbox 聚合视图、切换后列表与详情同步 |
|
||
| 视图切换稳定性 | 左侧不同会话入口之间来回切换 | 子导航清理、面包屑/主区同步、无残留导航状态 |
|
||
|
||
### 5.4 联系人与公司
|
||
|
||
来源:`contacts/routes.js`、`companies/routes.js`、M04 CRM 需求。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| 联系人列表 | 列表加载、搜索、分页、segment/label/active 过滤 |
|
||
| 联系人详情 | 基础资料、公司关联、标签、自定义属性、最近会话 |
|
||
| 联系人操作 | 新建、编辑、合并、添加电话/邮箱、打标签 |
|
||
| 公司列表 | 列表、搜索、分页 |
|
||
| 公司详情 | 公司信息、关联联系人、关联会话 |
|
||
| CRM 联动 | 从会话侧栏跳到联系人/公司,再回会话 |
|
||
|
||
### 5.5 全局搜索与通知
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| 全局搜索 | conversations / messages / contacts / articles 结果切换、关键词高亮、空态 |
|
||
| 通知中心 | 列表加载、已读/未读、点击跳转回目标会话或页面 |
|
||
|
||
### 5.6 Settings 全量页面
|
||
|
||
来源:`settings.routes.js`。
|
||
|
||
#### A. 账户与个人设置
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| General / Account | 账户名、语言、时区、自动设置、保存与刷新回显 |
|
||
| Profile | 个人资料、显示名、签名、通知偏好 |
|
||
| Security / MFA / SSO | 可见性、表单渲染、保存校验、受限能力的降级提示 |
|
||
|
||
#### B. 人员与权限
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Agents | 列表、邀请/创建、编辑、重置密码、激活状态 |
|
||
| Teams | 列表、新建、编辑、成员绑定 |
|
||
| Custom Roles | 列表、权限矩阵、创建/编辑、角色绑定 |
|
||
|
||
#### C. Inbox 与渠道
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Inbox 列表 | 类型徽标、入口可点、列表完整 |
|
||
| Website inbox | 基础配置、欢迎语、营业时间、CSAT、预聊天表单、锁单会话 |
|
||
| Email inbox | 配置表单、校验提示、降级态 |
|
||
| API inbox | 创建、token/endpoint 展示 |
|
||
| Voice/Twilio 类 inbox | voice 页面、降级配置、保存校验 |
|
||
| Inbox members / collaborators | agent 绑定、移除、回显 |
|
||
|
||
#### D. 标签、属性、提效工具
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Labels | 列表、创建、编辑、删除 |
|
||
| Custom Attributes | contact / conversation / company 三类定义 CRUD |
|
||
| Canned Responses | 列表、创建、编辑、插入消息编辑器 |
|
||
| Macros | 列表、创建、编辑、执行宏后会话变化 |
|
||
|
||
#### E. 规则与编排
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Automation | event/condition/action 表单、create/edit/clone/delete、校验 |
|
||
| Conversation Workflow | 自动流程与配置项渲染、保存回显 |
|
||
| Assignment Policy | assignment/capacity 两类策略的列表、创建、编辑、绑定 inbox / agent |
|
||
| SLA | 策略列表、创建、编辑、删除、会话命中展示 |
|
||
|
||
#### F. 集成与审计
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Integrations | Slack / Webhook / Dashboard Apps / 其他集成卡片渲染 |
|
||
| Webhook hooks | 列表、创建、编辑、删除、测试 |
|
||
| Dashboard Apps | iframe app 列表、创建、删除 |
|
||
| Audit Logs | 列表、筛选、关键操作写入可见 |
|
||
| Billing | 页面加载、enterprise feature 与配额信息展示 |
|
||
|
||
#### G. Reports
|
||
|
||
来源:`reports.routes.js` 与 M07 报表需求。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Overview | 指标卡、筛选器、日期切换 |
|
||
| Conversations / Agents / Teams / Labels / Inbox | 各页数据加载、筛选、切换 |
|
||
| CSAT | 列表、metrics、空态与有数据态 |
|
||
| SLA | 列表、metrics、下载 |
|
||
| Bot / Live reports | 页面可见、筛选器工作 |
|
||
|
||
### 5.7 Campaigns
|
||
|
||
来源:`campaigns.routes.js`。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Live chat campaigns | 列表、创建、编辑、启停、依赖 website inbox |
|
||
| SMS campaigns | 列表、创建、编辑 |
|
||
| WhatsApp campaigns | feature flag 下渲染、创建页校验 |
|
||
|
||
### 5.8 Help Center 后台
|
||
|
||
来源:`helpcenter.routes.js`。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Portal 列表 | portal 列表、入口跳转 |
|
||
| Articles | 列表、筛选、创建、编辑、发布状态 |
|
||
| Categories | 列表、创建、排序、关联文章 |
|
||
| Locales | locale 列表、切换、多语言文章入口 |
|
||
| Portal settings | 基础设置、logo/domain/config |
|
||
| Article preview | preview 跳转与渲染 |
|
||
|
||
### 5.9 Widget / Public Surface
|
||
|
||
这部分允许从根入口直接打开,但内部仍应按真实点击验证。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Widget config/init | `website_token` 可用、首屏渲染、launcher 打开 |
|
||
| Pre-chat form | 字段展示、必填校验、提交建会话 |
|
||
| Widget messaging | 客户发首条消息、客服回复、fake 回流 |
|
||
| Public CSAT | 评分页可打开、提交后报表可见 |
|
||
| Public Help Center | portal 首页、分类页、文章页、搜索 |
|
||
|
||
### 5.10 Captain / Copilot / AI Surface
|
||
|
||
来源:`dashboard/captain/*.routes.js`、`settings/copilot`、`captain/tasks.js`。
|
||
|
||
| 页面组 | 关键功能点 |
|
||
|---|---|
|
||
| Captain Settings / Copilot Config | provider 配置、feature toggle、model 选择、test config、embedding reindex |
|
||
| Assistants | 列表、创建、编辑、删除 |
|
||
| Assistant Settings | 基础信息、guardrails、guidelines、behavior 保存 |
|
||
| Assistant Inboxes | 绑定/解绑 inbox |
|
||
| Documents | URL/PDF 创建、sync 状态、失败态、删除 |
|
||
| Responses / FAQs | 列表、pending 审核、approve/reject、搜索 |
|
||
| Scenarios | 列表、创建、编辑、启用禁用 |
|
||
| Custom Tools | 列表、创建、测试、启用禁用 |
|
||
| Playground | 发送 prompt、得到稳定回复、错误态可见 |
|
||
| Conversation 内 AI 任务 | summarize / rewrite / reply suggestion / label suggestion / follow_up |
|
||
| Copilot threads | 创建 thread、发消息、接收回复、刷新恢复历史 |
|
||
|
||
### 5.11 页面组与数据依赖矩阵
|
||
|
||
这张表的目的不是重复功能点,而是提前说明“为什么某些页面现在只能看渲染,不能算完整通过”。
|
||
|
||
| 页面组 | 最低依赖数据/能力 | 不足时的结果 |
|
||
|---|---|---|
|
||
| 登录 / dashboard 主壳 | 1 个管理员、1 个有效 account | 直接 P0 |
|
||
| 会话列表 / 详情 | `fake_01` inbox、6+ 会话、3+ 消息类型 | 只能看空态或单条 smoke 会话 |
|
||
| 分配 / 团队 / mentions | 第 2 个 agent、2 个 team | 无法验证协作与在线状态 |
|
||
| 联系人 / 公司 | 8+ contacts、3+ companies | 搜索、分页、合并、关联验证失真 |
|
||
| Labels / Attributes / Filters | 5+ labels、三类 attributes 定义 | 过滤器与详情侧栏大面积空态 |
|
||
| Canned / Macros / Automation | 各 3 条以上配置对象 | 只能验页面挂载,不能验执行链路 |
|
||
| Reports / CSAT / SLA | applied SLA、CSAT、通知、审计日志 | 只能验空态,不能验指标和 drilldown |
|
||
| Campaign / Widget / Public | website inbox、portal、campaign 样本 | 无法完成触发和回流验证 |
|
||
| Captain / Copilot | fake:ai、assistant/documents/responses/scenarios/tools | 只能验路由与表单渲染,不能算 AI 功能通过 |
|
||
|
||
### 5.12 每个页面组的执行粒度
|
||
|
||
为了避免“页面打开了就算测过”,每个页面组默认至少拆成下面 4 类用例:
|
||
|
||
1. 首屏加载:入口点击、首屏渲染、关键 API、空态/有数据态。
|
||
2. 核心操作:创建 / 编辑 / 删除 / 应用 / 发送 / 跳转中的 1~3 个主操作。
|
||
3. 状态回写:保存后列表回显、刷新恢复、再次进入详情一致。
|
||
4. 异常分支:缺字段、接口失败、无权限、空返回、超时或 loading 收敛。
|
||
|
||
如果某页当前只有空态数据,也仍要记录:
|
||
|
||
- 该页是否能稳定挂载;
|
||
- 空态是否符合预期;
|
||
- 哪个具体数据缺口阻止了继续深测;
|
||
- 它属于 `blocked` 还是 `partial pass`。
|
||
|
||
### 5.13 按前端路由拆分的执行清单
|
||
|
||
这部分专门回答“每个页面的特性功能点都要详细测试”这个要求。它不是要求首轮一次性全部跑完,而是把后续 CDP 点击清单拆成不会漏页的颗粒度。
|
||
|
||
| 路由族 | 页面/子页 | 至少覆盖的动作 |
|
||
|---|---|---|
|
||
| 会话工作台 | `home`、`inbox_dashboard`、`inbox_conversation`、`label_conversations`、`team_conversations`、`conversation_mentions`、`conversation_unattended`、`conversation_participating` | 列表切换、打开会话、发送消息、切换 assignee/team/label、刷新恢复 |
|
||
| Inbox View | `inbox_view`、`inbox_view_conversation` | inbox 聚合视图切换、从列表进入详情、回到列表、子导航清理 |
|
||
| 联系人 | `contacts_dashboard_index`、segments、labels、active、`contacts_edit` | 搜索、分页、筛选、进入详情、编辑、标签/属性回显 |
|
||
| 公司 | `companies_dashboard_index`、`companies_dashboard_show` | 列表加载、搜索、进入公司详情、回联系人/会话联动 |
|
||
| 搜索 | `search` | 不同 tab 切换、关键词搜索、结果跳转回原页面 |
|
||
| Campaigns | ongoing、one_off、live_chat、sms、whatsapp | 列表渲染、创建/编辑入口、启停、依赖 inbox 校验 |
|
||
| Help Center | portals index/new、articles index/new/edit/preview、categories、locales、settings | portal 创建、文章 CRUD、分类排序、多语言切换、preview/public 联动 |
|
||
| Settings-General/Profile | general、profile settings、mfa | 保存回显、校验、受限功能降级、刷新后仍一致 |
|
||
| Settings-Agents/Teams/Roles | agents、teams list/new/edit/finish/members、custom roles | 人员创建/编辑、团队成员绑定、角色矩阵保存、权限边界 |
|
||
| Settings-Inbox | inbox list、新建 channel、website/api/email/voice/fake channel 设置、collaborators、CSAT、business hours | 列表、创建、配置保存、成员绑定、公开侧联动 |
|
||
| Settings-效率工具 | labels、custom attributes、canned responses、macros、agent bots | CRUD、会话内实际使用、保存回显 |
|
||
| Settings-规则编排 | automation、conversation workflow、assignment policy、agent capacity、SLA | create/edit/delete、条件动作校验、绑定 inbox/agent、命中回显 |
|
||
| Settings-Integrations | integrations root、dashboard apps、webhook、slack、linear、notion、shopify | 卡片可见、hook CRUD、dashboard app 装载、第三方配置错误态 |
|
||
| Settings-Audit/Billing | audit logs、billing | 列表、筛选、配额/套餐信息、enterprise 降级态 |
|
||
| Reports | overview、agents、inboxes、labels、teams、csat、sla、bot/live reports | 日期筛选、指标卡、钻取、下载、空态与有数据态 |
|
||
| Captain/Copilot 设置 | copilot settings、provider test、embedding reindex、feature/model 保存 | 保存、测试连接、错误提示、配置持久化 |
|
||
| Captain 资源页 | assistants、assistant settings、assistant inboxes、documents、responses、scenarios、custom tools | CRUD、绑定、sync/test、审核、启停、状态回写 |
|
||
| AI 交互页 | playground、copilot threads、会话内 summarize/rewrite/reply suggestion/label suggestion/follow_up | 请求发出、稳定响应、stream、错误态、刷新恢复 |
|
||
| Widget/Public | widget init、pre-chat、public csat、public help center | 公开入口可打开、提交/搜索/评分成功、后台有回流证据 |
|
||
|
||
建议执行时,把上表每一行视为一个“页面族批次”,每个批次至少产出:
|
||
|
||
1. 入口点击链路;
|
||
2. 1 个加载用例;
|
||
3. 1~3 个核心操作用例;
|
||
4. 1 个刷新/返回一致性用例;
|
||
5. 1 个异常或空态用例。
|
||
|
||
### 5.13.1 路由来源文件对照
|
||
|
||
为了避免后续执行时只盯着左侧菜单、却漏掉某些子页,这里把当前前端实际路由来源文件也固定下来。后续如果某个页面组出现“菜单存在但主区没挂载”或“子页残留/串页”,可以直接回到对应 routes 文件做对照。
|
||
|
||
| 页面族 | 主要路由来源文件 |
|
||
|---|---|
|
||
| dashboard 主壳 / 一级容器 | `frontend/app/javascript/dashboard/routes/dashboard/dashboard.routes.js` |
|
||
| 会话工作台 | `frontend/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js` |
|
||
| Inbox View | `frontend/app/javascript/dashboard/routes/dashboard/inbox/routes.js` |
|
||
| 联系人 | `frontend/app/javascript/dashboard/routes/dashboard/contacts/routes.js` |
|
||
| 公司 | `frontend/app/javascript/dashboard/routes/dashboard/companies/routes.js` |
|
||
| 全局搜索 | `frontend/app/javascript/dashboard/modules/search/search.routes.js` |
|
||
| 通知 | `frontend/app/javascript/dashboard/routes/dashboard/notifications/routes.js` |
|
||
| Campaigns | `frontend/app/javascript/dashboard/routes/dashboard/campaigns/campaigns.routes.js` |
|
||
| Help Center | `frontend/app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js` |
|
||
| Captain 主区 | `frontend/app/javascript/dashboard/routes/dashboard/captain/captain.routes.js` |
|
||
| Settings 根路由 | `frontend/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js` |
|
||
| Settings / Account | `frontend/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js` |
|
||
| Settings / Profile | `frontend/app/javascript/dashboard/routes/dashboard/settings/profile/profile.routes.js` |
|
||
| Settings / Security | `frontend/app/javascript/dashboard/routes/dashboard/settings/security/security.routes.js` |
|
||
| Settings / Agents | `frontend/app/javascript/dashboard/routes/dashboard/settings/agents/agent.routes.js` |
|
||
| Settings / Teams | `frontend/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js` |
|
||
| Settings / Custom Roles | `frontend/app/javascript/dashboard/routes/dashboard/settings/customRoles/customRole.routes.js` |
|
||
| Settings / Inboxes | `frontend/app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js` |
|
||
| Settings / Labels | `frontend/app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js` |
|
||
| Settings / Attributes | `frontend/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js` |
|
||
| Settings / Canned Responses | `frontend/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js` |
|
||
| Settings / Macros | `frontend/app/javascript/dashboard/routes/dashboard/settings/macros/macros.routes.js` |
|
||
| Settings / Agent Bots | `frontend/app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js` |
|
||
| Settings / Automation | `frontend/app/javascript/dashboard/routes/dashboard/settings/automation/automation.routes.js` |
|
||
| Settings / Conversation Workflow | `frontend/app/javascript/dashboard/routes/dashboard/settings/conversationWorkflow/conversationWorkflow.routes.js` |
|
||
| Settings / Assignment Policy | `frontend/app/javascript/dashboard/routes/dashboard/settings/assignmentPolicy/assignmentPolicy.routes.js` |
|
||
| Settings / SLA | `frontend/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js` |
|
||
| Settings / Integrations | `frontend/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js` |
|
||
| Settings / Audit Logs | `frontend/app/javascript/dashboard/routes/dashboard/settings/auditlogs/audit.routes.js` |
|
||
| Settings / Billing | `frontend/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js` |
|
||
| Reports | `frontend/app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js` |
|
||
| Settings / Captain 配置页 | `frontend/app/javascript/dashboard/routes/dashboard/settings/captain/captain.routes.js` |
|
||
|
||
### 5.14 页面级测试用例模板
|
||
|
||
为了避免后续执行时每页都重新想“要点什么、验什么”,这里固定一个页面级模板。后面每个页面族至少套一次。
|
||
|
||
| 用例类型 | 最低动作 | 最低断言 |
|
||
|---|---|---|
|
||
| 首屏加载 | 从上一级页面真实点击进入 | URL 变化、主区有业务内容、首屏 API 2xx、console 无阻断异常 |
|
||
| 列表操作 | 搜索 / 筛选 / tab 切换 / 分页 / 排序 至少 1 项 | 列表内容变化、计数变化或空态正确、network 有对应请求 |
|
||
| 详情操作 | 从列表进入详情,再返回列表 | 详情数据完整,返回后列表状态未丢失 |
|
||
| 表单操作 | create / edit / save 至少 1 项 | 校验提示正确、保存后 toast/列表/详情回显一致 |
|
||
| 破坏性操作 | delete / disable / remove / close 至少 1 项 | 二次确认、结果可见、刷新后仍生效 |
|
||
| 联动操作 | 从 A 页跳 B 页再回 A 页 | breadcrumb/side nav/main area 同步更新,无旧页面残留 |
|
||
| 权限/异常 | 缺字段 / 失败响应 / 无数据态 至少 1 项 | 错误提示明确,不出现空白壳或静默失败 |
|
||
| 刷新恢复 | F5 或重新进入当前页 | 当前位置、列表筛选、详情对象或最近状态能恢复 |
|
||
|
||
建议把每个页面族都落成下面这种最小结构:
|
||
|
||
```text
|
||
页面族:Settings > Labels
|
||
- load: 从 设置 -> 标签 进入,列表成功加载
|
||
- core action 1: 新建标签
|
||
- core action 2: 编辑标签
|
||
- destructive: 删除标签
|
||
- refresh: 刷新后标签仍存在/已删除
|
||
- exception: 提交空名称时出现校验
|
||
```
|
||
|
||
如果一个页面当前只能跑到空态,也要按同样结构记录:
|
||
|
||
```text
|
||
页面族:Reports > CSAT
|
||
- load: 页面可挂载
|
||
- blocked: 缺少 5 条以上 CSAT response
|
||
- exception: 空态文案正确
|
||
```
|
||
|
||
## 6. 证据采集规范
|
||
|
||
每条页面用例至少记录:
|
||
|
||
- 起始入口与点击路径
|
||
- 结束 URL
|
||
- 关键可见文案
|
||
- 发出的关键 API
|
||
- console / runtime exception
|
||
- 是否需要刷新后复核
|
||
- 结果:pass / fail / blocked
|
||
|
||
建议输出继续统一沉淀到:
|
||
|
||
- [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)
|
||
|
||
如果要单开新报告,可使用:
|
||
|
||
- `docs/qa/reports/2026-07-17-cdp-user-function-report.md`
|
||
|
||
## 7. 当前仓库已具备的数据基线
|
||
|
||
从 `backend/cmd/gochat seed` 与 `backend/scripts/parity_frontend_smoke.sh` 看,当前 smoke seed 已能提供:
|
||
|
||
| 类别 | 当前基线 |
|
||
|---|---|
|
||
| 管理员 | 1 个 `admin@gochat.local / changeme` |
|
||
| Account | 1 个 smoke account |
|
||
| Website inbox | 1 个 `web_widget` inbox,带 `website_token` |
|
||
| Voice-like inbox | 1 个 `twilio_sms` 型 smoke inbox |
|
||
| Contact / Company | 各 1 条 |
|
||
| Conversation | 1 条 open conversation |
|
||
| Messages | 3 条左右基础消息 |
|
||
| Help Center | 1 portal + 1 category + 1 article |
|
||
| SLA | 1 条 smoke policy |
|
||
| Custom Role | 1 条 |
|
||
| Capacity Policy | 1 条 |
|
||
| Captain | 1 个 assistant + 少量 smoke fixture |
|
||
|
||
这足够跑 smoke,但不够支撑“每个页面的特性功能点都详细测试”。
|
||
|
||
## 8. 还需要补充的、会影响全量实际测试的数据
|
||
|
||
### 8.1 P0:不补就会大面积 blocked
|
||
|
||
| 缺口 | 最低要求 | 直接影响 |
|
||
|---|---|---|
|
||
| 第二个可登录 agent | 1 个 | 分配、协作、在线状态、mentions、跨坐席实时 |
|
||
| `fake_01` inbox 真正建档 | 1 个 | 当前 fake webhook 主链路、消息回流 |
|
||
| 多状态会话 | 至少 8 条 | open / pending / resolved / snoozed / unattended / assigned 视图 |
|
||
| 更丰富消息类型 | 至少覆盖 text/private note/attachment/template | 会话详情、时间线、编辑器、下载 |
|
||
| website inbox 真实配置 | 1 套完整配置 | widget / pre-chat / live chat campaign |
|
||
|
||
### 8.2 P1:不补就只能看空态或半成品态
|
||
|
||
| 缺口 | 最低要求 | 直接影响 |
|
||
|---|---|---|
|
||
| Contacts | 8~12 条 | CRM 列表、搜索、分页、合并 |
|
||
| Companies | 3~5 条 | 公司列表、详情、关联联系人 |
|
||
| Labels | 5 条以上 | 过滤、标签设置、报表 |
|
||
| Teams | 2 条以上 | 团队分配、团队报表 |
|
||
| Custom attributes | contact/conversation/company 各 2 条定义 | 表单、筛选、详情侧栏 |
|
||
| Canned responses | 3 条 | 编辑器插入、列表 CRUD |
|
||
| Macros | 3 条 | 会话执行宏 |
|
||
| Automation rules | 3 条 | 列表、编辑、条件动作校验 |
|
||
| Notifications | 5 条以上 | 通知列表与跳转 |
|
||
| Audit logs | 5 条以上 | 审计页是否有真实内容 |
|
||
|
||
### 8.3 P2:不补就无法完成高级页验证
|
||
|
||
| 缺口 | 最低要求 | 直接影响 |
|
||
|---|---|---|
|
||
| Email inbox | 1 个 | email channel 配置页与表单 |
|
||
| API inbox | 1 个 | API channel 页面与 token 展示 |
|
||
| Campaign 样本 | live chat / sms / whatsapp 各 1 条 | campaign 列表、编辑、启停 |
|
||
| 多 locale help center | 至少 2 个 locale | locales / article 多语言验证 |
|
||
| CSAT responses | 5 条以上 | CSAT 列表、metrics、public submit 回流 |
|
||
| Applied SLA data | 3 条以上 | SLA metrics / download |
|
||
| Dashboard app | 1 个 | iframe app 页面 |
|
||
|
||
### 8.4 建议一次性补齐的数据包
|
||
|
||
如果目标是“尽快进入全量点击测试”,最省事的方式不是边点边发现缺数据,而是先凑齐一包能覆盖主链路的数据。
|
||
|
||
推荐一次性补到这个下限:
|
||
|
||
| 数据包 | 推荐下限 | 覆盖的页面/动作 |
|
||
|---|---:|---|
|
||
| 管理员 | 1 | 登录、settings、reports、captain |
|
||
| 普通 agent | 2 | 会话分配、协作、在线状态、team、mentions |
|
||
| custom role 用户 | 1 | 权限边界、受限菜单、禁用按钮 |
|
||
| fake inbox | 1 (`fake_01`) | fake 入站、客服回复、auto reply 回流 |
|
||
| website inbox | 1 | widget、pre-chat、campaign、公开面 |
|
||
| api inbox | 1 | inbox 配置页、token 展示 |
|
||
| email inbox | 1 | email provider / SMTP / IMAP 页 |
|
||
| voice/twilio inbox | 1 | voice 页面与降级态 |
|
||
| open 会话 | 4 | 会话主列表、详情、分配、标签 |
|
||
| pending 会话 | 2 | pending tab、bot handoff、assign |
|
||
| resolved 会话 | 2 | resolved tab、reopen、报表 |
|
||
| snoozed 会话 | 2 | snooze 视图、恢复 |
|
||
| unattended / participating / mention 命中会话 | 各 1 | 左侧特殊视图 |
|
||
| 附件消息 | 2 | 下载、预览、时间线渲染 |
|
||
| private note | 2 | 私有备注时间线、过滤 |
|
||
| labels | 5 | 标签页、过滤、报表、自动化 |
|
||
| teams | 2 | 团队页、team assign、team report |
|
||
| contacts | 10 | CRM 列表、搜索、分页、合并 |
|
||
| companies | 4 | 公司列表、详情、联系人关联 |
|
||
| canned responses | 3 | 回复框插入、settings CRUD |
|
||
| macros | 3 | 执行宏、状态回写 |
|
||
| automation rules | 3 | 自动化页 create/edit/delete |
|
||
| custom attributes | 三类各 2 | 详情表单、筛选、自动化条件 |
|
||
| notifications | 5 | 通知中心列表、跳转 |
|
||
| audit logs | 5 | 审计页内容与筛选 |
|
||
| csat responses | 5 | CSAT 页面、public csat 回流 |
|
||
| applied sla | 3 | SLA 指标、drilldown、download |
|
||
| help center portal | 1 | public/help center 后台 |
|
||
| categories | 2 | article 分类、排序 |
|
||
| published articles | 3 | article 列表、搜索、public article |
|
||
| campaigns | live chat / sms / whatsapp 各 1 | campaign 列表、编辑、启停 |
|
||
| captain assistant | 1 | AI 页面根对象 |
|
||
| captain documents | 3 | syncing/synced/failed |
|
||
| captain responses | 5 | FAQ / pending / 审核 |
|
||
| captain scenarios | 2 | 场景列表、启停 |
|
||
| captain custom tools | 1 | tool test / tool call |
|
||
|
||
执行策略建议:
|
||
|
||
1. `seed` 只负责兜底,不负责把列表型页面喂饱。
|
||
2. fake channel 负责会话、消息、实时链路造数。
|
||
3. settings/UI 首轮执行中,顺手创建 labels / teams / canned / macros / attributes。
|
||
4. 报表、通知、审计、SLA 这类“结果数据”,要么走定向 seed,要么走真实操作回灌。
|
||
|
||
### 8.5 按当前三服务拆分的可测范围
|
||
|
||
基于你现在已经手工启动的三项服务:
|
||
|
||
```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
|
||
```
|
||
|
||
后续执行时建议明确分成两层,不要把“已经能做的页面验收”和“仍缺本地 AI 支撑的页面”混在一起。
|
||
|
||
| 范围 | 当前能否直接进入 CDP 实测 | 说明 |
|
||
|---|---|---|
|
||
| 登录 / dashboard 主壳 | 可以 | 只依赖 backend + frontend |
|
||
| 会话列表 / 会话详情 / fake 入站出站 / auto reply | 可以 | 但前提是 GoChat 里已有 `fake_01` 对应 inbox |
|
||
| 联系人 / 公司 / 搜索 / 通知 | 可以 | 深测仍取决于 contacts / companies / notifications 数据量 |
|
||
| Settings 非 AI 页面 | 可以 | 适合一边点击一边补 labels / teams / macros / attributes 等对象 |
|
||
| Campaigns / Widget / Public / Help Center | 可以 | 依赖 website inbox、portal、campaign 样本是否已补齐 |
|
||
| Reports / Audit / CSAT / SLA | 可以 | 页面能测,但“有数据态”仍取决于结果型数据是否已回灌 |
|
||
| Captain / Copilot 的路由、表单、开关、空态、错误态 | 可以 | 在没有 `fake:ai` 前,只能算 render/config/error-path 验证 |
|
||
| Captain Playground / Documents / Responses / Copilot threads / 会话内 AI 任务成功链路 | 暂不建议宣称完整通过 | 需要 `fake:ai` 才能把 success / stream / timeout / 429 / embedding 等路径测全 |
|
||
|
||
因此推荐执行顺序不要反过来:
|
||
|
||
1. 先用当前三服务完成非 AI 页面与消息主链路的 click-only 全量覆盖。
|
||
2. 把数据缺口补到足以支撑有数据态验证。
|
||
3. 再补 `fake:ai`,最后收 Captain / Copilot 的成功链路与失败链路。
|
||
|
||
## 9. 数据补齐建议
|
||
|
||
### 9.1 先用 seed 打底
|
||
|
||
先执行一次:
|
||
|
||
```bash
|
||
cd backend
|
||
go run ./cmd/gochat seed
|
||
```
|
||
|
||
### 9.2 再补 fake channel 所需真实 inbox
|
||
|
||
最少需要把 `fake_01` 这个 webhook 标识对应到 GoChat 内的 fake inbox 配置,确保:
|
||
|
||
- fake 发出的入站消息能建会话
|
||
- dashboard 发出的出站消息能回到 `/receive`
|
||
- auto reply 回来的消息能附着到同一会话
|
||
|
||
### 9.3 把“列表型数据”与“功能型数据”分开准备
|
||
|
||
建议分三类造数:
|
||
|
||
| 类别 | 数据 | 建议方式 |
|
||
|---|---|---|
|
||
| 主链路数据 | admin / 2 agents / fake inbox / website inbox / 基础 conversations | 执行前一次性准备 |
|
||
| CRUD 数据 | labels / teams / macros / canned / custom attributes | 直接在 CDP 首轮过程中边测边创建 |
|
||
| 报表数据 | csat / applied_sla / notifications / audit logs | 定向 seed 或通过 API/fake 回灌 |
|
||
|
||
### 9.4 建议的数据准备责任矩阵
|
||
|
||
这张表的目的,是把“哪些数据要先准备好、哪些可以在点测时顺手造出来”定死,避免后面执行过程中频繁停下来补环境。
|
||
|
||
| 数据/能力 | 推荐准备方式 | 最好何时完成 | 主要服务谁 |
|
||
|---|---|---|---|
|
||
| 管理员账号 | `go run ./cmd/gochat seed` 打底 | 执行前 | 登录、settings、reports、captain |
|
||
| 第二个 agent | 后台创建或补定向 seed | 执行前 | 分配、协作、在线状态、mentions |
|
||
| custom role 用户 | 后台创建 | 执行前或批次 B 开始前 | 权限边界、受限入口 |
|
||
| `fake_01` inbox | 后台建 fake inbox,并把 webhook 标识对到 `fake_01` | 执行前 | fake 入站、出站、auto reply 主链路 |
|
||
| website inbox | seed 打底后在 settings 补齐配置 | 执行前 | widget、pre-chat、campaign、public 面 |
|
||
| API inbox / Email inbox / Voice inbox | settings 页面内创建或补 seed | 批次 B 前 | inbox 类型页、provider 配置页 |
|
||
| open/pending/resolved/snoozed 会话池 | `channels/fake` 批量造数 | 执行前 | 会话列表、筛选、报表、刷新恢复 |
|
||
| private note / attachment / template 消息 | UI 操作 + fake 回灌混合 | 批次 A 过程中 | 会话时间线、附件预览、编辑器能力 |
|
||
| contacts / companies | UI 创建为主,必要时补 seed | 批次 A 前半段 | CRM 列表、搜索、分页、关联 |
|
||
| labels / teams | UI 创建 | 批次 B 过程中 | 标签过滤、team assign、team report |
|
||
| canned responses / macros / automation | UI 创建 | 批次 B 过程中 | 回复提效、宏执行、自动化规则 |
|
||
| custom attributes | UI 创建 | 批次 B 过程中 | 详情表单、筛选、自动化条件 |
|
||
| notifications / audit logs / csat / applied sla | 真实操作回灌优先,不足再补定向 seed | 批次 B 或 C 前 | 通知、审计、CSAT/SLA 报表 |
|
||
| help center portal / categories / articles | seed 打底后在 UI 补多语言/多分类 | 批次 B 或 C 前 | help center 后台与 public |
|
||
| campaigns 样本 | UI 创建 | 批次 C 前 | live chat / sms / whatsapp campaigns |
|
||
| `fake:ai` 服务 | 新增 `channels/fake-ai` 并接到 `openai_compatible` | 批次 D 前 | Captain / Copilot / Playground / Embedding |
|
||
| captain assistant / docs / responses / scenarios / tools | settings / captain 页面内创建,必要时配合定向 seed | 批次 D 前半段 | AI 子页 CRUD、状态流转、工具调用 |
|
||
|
||
建议执行节奏:
|
||
|
||
1. 先把执行前必需项一次性补到位,再开始点击主链路。
|
||
2. 把适合“边测边造”的对象留在对应页面里创建,顺便验证页面 CRUD。
|
||
3. 结果型数据尽量通过真实操作自然回灌,这样后面的报表和审计验证会更可信。
|
||
|
||
## 10. AI 测试为什么需要单独补 `fake:ai`
|
||
|
||
当前仓库的 AI 运行时是通过 `llm.Provider` 抽象接入的,最关键的 3 个能力是:
|
||
|
||
- `ChatCompletion`
|
||
- `CreateEmbedding`
|
||
- `ChatCompletionStream`
|
||
|
||
同时,平台配置页和 AI 功能页都围绕这些能力工作:
|
||
|
||
- `/platform/api/v1/copilot/config`
|
||
- `/platform/api/v1/copilot/config/test`
|
||
- `/platform/api/v1/copilot/embeddings/reindex`
|
||
- `/api/v1/accounts/:id/captain/tasks/*`
|
||
- `/api/v1/accounts/:id/captain/assistants/:assistant_id/playground`
|
||
- `/api/v1/accounts/:id/captain/copilot_threads/*`
|
||
|
||
并且当前后端已经支持 `openai_compatible` provider:
|
||
|
||
- `ProviderManager` 接受 `openai_compatible`
|
||
- chat 侧请求会打到 `/chat/completions`
|
||
- embedding 侧请求会打到 `/embeddings`
|
||
|
||
这意味着 `fake:ai` 不需要先改 GoChat provider 矩阵,优先做成一个本地 OpenAI-compatible 假服务即可。
|
||
|
||
如果没有本地 deterministic AI provider,Captain/Copilot 相关测试会卡在:
|
||
|
||
- 依赖真实第三方 key
|
||
- 响应不可复现
|
||
- 无法稳定覆盖超时/429/stream 中断/工具调用失败
|
||
|
||
所以这部分不应继续复用 message fake,而应该新增一条独立的 `fake:ai` 测试通道。
|
||
|
||
## 11. `fake:ai` 的建议形态
|
||
|
||
### 11.1 最小落地方向
|
||
|
||
推荐直接新增成 `channels/fake-ai`,尽量与现有 `channels/fake` 保持同构:
|
||
|
||
- 同样走独立目录
|
||
- 同样通过根 `package.json` 暴露启动脚本
|
||
- 同样提供健康检查、控制接口、历史请求观测
|
||
|
||
并让 GoChat Copilot/Captain 用 `openai_compatible` 模式直连它。
|
||
|
||
这样不需要改动 `ProviderManager` 的支持矩阵,只需要在平台配置里填本地地址。
|
||
|
||
如果希望复用现有 fake channel 的使用习惯,建议 `fake:ai` 也采用同样的“观测 + 场景切换 + 历史查询”风格:
|
||
|
||
- `GET /health`
|
||
- `POST /api/config`
|
||
- `POST /api/reset`
|
||
- `GET /api/status`
|
||
- `GET /api/requests`
|
||
|
||
这样 CDP 脚本切换消息 fake 与 AI fake 时,控制面会非常一致。
|
||
|
||
### 11.1.1 当前仓库已确认的实现缺口
|
||
|
||
基于当前仓库实际检查,`fake:ai` 现在还不是“已有能力”,而是明确待补的测试支撑项:
|
||
|
||
| 项 | 当前状态 | 结论 |
|
||
|---|---|---|
|
||
| 根脚本 `fake:start / fake:dev / fake:test` | 已存在 | `channels/fake` 现成可用 |
|
||
| 根脚本 `fake:ai / fake:ai:dev / fake:ai:test` | 不存在 | 需要新增 |
|
||
| workspace 包 `channels/fake` | 已纳入 `pnpm-workspace.yaml` | 现有 fake message 平台可直接运行 |
|
||
| workspace 包 `channels/fake-ai` | 不存在 | 需要新增目录并纳入 workspace |
|
||
| OpenAI-compatible provider 支持 | 已存在 | 可直接复用当前 `openai_compatible` 配置链路 |
|
||
|
||
因此这轮计划里提到的 `fake:ai`,应理解为:
|
||
|
||
1. 新增 `channels/fake-ai`
|
||
2. 根 `package.json` 增加 `fake:ai*` 脚本
|
||
3. `pnpm-workspace.yaml` 纳入 `channels/fake-ai`
|
||
4. 暴露最小 OpenAI-compatible 接口与控制/观测接口
|
||
|
||
### 11.1.2 建议直接补齐的工程脚手架
|
||
|
||
为了让 `fake:ai` 能像当前 `fake:start` 一样被稳定复用,建议第一步先补齐下面这些工程入口:
|
||
|
||
| 文件 | 建议新增项 | 目的 |
|
||
|---|---|---|
|
||
| 根 `package.json` | `fake:ai`、`fake:ai:dev`、`fake:ai:test` | 与现有 `fake:start` 使用习惯保持一致,方便人工与 CDP 脚本统一调用 |
|
||
| `pnpm-workspace.yaml` | `channels/fake-ai` | 让依赖安装、脚本执行、后续 CI 接入保持一致 |
|
||
| `channels/fake-ai/package.json` | `dev/start/test` 脚本 | 独立维护 fake:ai 的本地服务与测试 |
|
||
| `channels/fake-ai/README.md` | 启动方式、接口、scenario 用法 | 给后续 QA/CDP 执行者直接复用 |
|
||
| `channels/fake-ai/src/*` | `health`、OpenAI-compatible 路由、控制接口、请求观测 | 支撑 AI 页面联调与失败场景编排 |
|
||
|
||
建议默认启动命令直接约定成这种风格:
|
||
|
||
```bash
|
||
pnpm fake:ai
|
||
pnpm fake:ai:dev
|
||
pnpm fake:ai:test
|
||
```
|
||
|
||
这样后续本地全量测试的服务矩阵就会比较稳定:
|
||
|
||
```bash
|
||
pnpm dev:backend
|
||
pnpm dev:frontend
|
||
pnpm fake:start
|
||
pnpm fake:ai
|
||
```
|
||
|
||
### 11.2 最小接口
|
||
|
||
`fake:ai` 最少实现:
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| `GET` | `/health` | 健康检查 |
|
||
| `POST` | `/v1/chat/completions` | 普通对话 / playground / copilot / tasks |
|
||
| `POST` | `/v1/embeddings` | 文档 embedding / reindex |
|
||
|
||
如果要完整覆盖流式任务,再加:
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| `POST` | `/v1/chat/completions?stream=true` 或同一路由 SSE 输出 | summarize/rewrite/coproilot stream |
|
||
|
||
### 11.3 建议的测试场景开关
|
||
|
||
`fake:ai` 不应只返回固定 “OK”,而应支持 scenario 切换:
|
||
|
||
| 场景 | 用途 |
|
||
|---|---|
|
||
| success_text | 正常文本回复 |
|
||
| success_stream | 正常流式输出 |
|
||
| tool_call | 返回 function call,验证 custom tool / search_documentation |
|
||
| empty | 空回复,验证 UI 降级 |
|
||
| malformed | 非法结构,验证错误提示 |
|
||
| timeout | 超时,验证 loading / cancel / retry |
|
||
| rate_limit | 429,验证限流提示 |
|
||
| unauthorized | 401/403,验证 provider 配置错误提示 |
|
||
| embedding_success | 正常 embedding |
|
||
| embedding_fail | embedding 失败,验证 reindex / document 状态 |
|
||
|
||
### 11.4 推荐的控制接口
|
||
|
||
为了让 CDP 用例可编排,建议再加:
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
|---|---|---|
|
||
| `POST` | `/api/scenario` | 切换当前场景 |
|
||
| `POST` | `/api/reset` | 清空调用历史 |
|
||
| `GET` | `/api/requests` | 查看收到的 prompts / embeddings 请求 |
|
||
| `GET` | `/api/status` | 当前模式、计数、最近错误 |
|
||
| `POST` | `/api/config` | 统一配置默认模型、延迟、stream 开关、默认 scenario |
|
||
|
||
建议 `GET /api/requests` 至少记录这些字段,方便我们之后做断言与排错:
|
||
|
||
- timestamp
|
||
- route (`/v1/chat/completions` or `/v1/embeddings`)
|
||
- scenario
|
||
- model
|
||
- messages / input 摘要
|
||
- response status
|
||
- latency
|
||
- tool calls / stream chunk 数
|
||
- 最近一次 error
|
||
|
||
### 11.5 这样能覆盖哪些 AI 页面
|
||
|
||
接上 `fake:ai` 后,以下页面就能稳定做真功能测试,而不只是“页面能打开”:
|
||
|
||
- Copilot Config 页面:test config / provider health / embedding reindex
|
||
- Captain Settings:feature toggle / model 选择 / 保存回显
|
||
- Assistant Playground:发 prompt 得到确定性回复
|
||
- Documents:创建后进入 syncing / synced / failed 三种状态
|
||
- Responses / FAQs:生成、审核、过滤
|
||
- Custom Tools:tool_call 成功与失败
|
||
- 会话里的 summarize / rewrite / reply suggestion / label suggestion / follow_up
|
||
- Copilot threads:多轮上下文与刷新恢复
|
||
|
||
### 11.6 推荐先覆盖的 fake:ai 场景集
|
||
|
||
第一版不需要追求“大而全”,但至少要覆盖下面这 8 种:
|
||
|
||
| 场景 | 主要验证页 |
|
||
|---|---|
|
||
| success_text | playground、copilot 普通回复、assistant response 生成 |
|
||
| success_stream | reply suggestion、rewrite、copilot thread streaming |
|
||
| tool_call | custom tools、documentation/search 类能力 |
|
||
| timeout | provider test、rewrite、copilot panel loading/timeout |
|
||
| rate_limit | provider test、inline AI task 错误提示 |
|
||
| unauthorized | copilot config test、provider save 后再试用 |
|
||
| embedding_success | document sync / reindex / faq embedding |
|
||
| embedding_fail | documents failed 状态、reindex 失败回显 |
|
||
|
||
### 11.7 `fake:ai` 与当前 fake channel 的职责边界
|
||
|
||
这两者建议保持分工明确,避免后面观测混乱:
|
||
|
||
| 组件 | 负责什么 | 不负责什么 |
|
||
|---|---|---|
|
||
| `channels/fake` | 模拟外部客户消息、回收 GoChat 出站消息、auto reply | 不模拟 LLM、embedding、tool calling |
|
||
| `fake:ai` | 模拟 chat completion、stream、embedding、tool call、AI 失败场景 | 不模拟客户消息、不承载会话 webhook |
|
||
|
||
建议最终执行时把两条链路串起来看:
|
||
|
||
1. `channels/fake` 负责造出真实会话和客服回复链路。
|
||
2. `fake:ai` 负责让同一会话内的 Copilot/Captain 操作可重复、可观测、可断言。
|
||
|
||
### 11.8 推荐的接入方式与配置模板
|
||
|
||
为了减少对 GoChat 现有 ProviderManager 的侵入,`fake:ai` 最好直接伪装成一个本地 OpenAI-compatible 服务。
|
||
|
||
推荐接法:
|
||
|
||
1. 启动 `fake:ai`,例如监听 `http://127.0.0.1:9110`
|
||
2. 在 Copilot Config 页面把 chat provider 与 embedding provider 都设为 `openai_compatible`
|
||
3. chat base URL 指向 `http://127.0.0.1:9110/v1`
|
||
4. embedding base URL 指向 `http://127.0.0.1:9110/v1`
|
||
5. API key 可填固定占位值,如 `fake-ai-key`
|
||
|
||
建议在文档或实现里直接约定这组默认值:
|
||
|
||
```text
|
||
FAKE_AI_PORT=9110
|
||
FAKE_AI_BASE_URL=http://127.0.0.1:9110/v1
|
||
FAKE_AI_API_KEY=fake-ai-key
|
||
FAKE_AI_DEFAULT_MODEL=fake-gpt-4o-mini
|
||
FAKE_AI_DEFAULT_EMBED_MODEL=fake-text-embedding-3-small
|
||
```
|
||
|
||
这样后续 CDP 用例可以固定验证:
|
||
|
||
- config test 成功
|
||
- save 后再次进入 settings 仍回显本地 fake 配置
|
||
- playground / tasks / copilot threads 的请求都能在 `fake:ai` 侧被观测到
|
||
|
||
### 11.9 推荐的最小响应契约
|
||
|
||
为了让前端和后端都能稳定消费,`fake:ai` 第一版至少要保证返回结构长得像 OpenAI。
|
||
|
||
普通 completion 最小返回可约定为:
|
||
|
||
```json
|
||
{
|
||
"id": "chatcmpl_fake_001",
|
||
"object": "chat.completion",
|
||
"created": 1784332800,
|
||
"model": "fake-gpt-4o-mini",
|
||
"choices": [
|
||
{
|
||
"index": 0,
|
||
"message": {
|
||
"role": "assistant",
|
||
"content": "这是 fake:ai 的确定性回复"
|
||
},
|
||
"finish_reason": "stop"
|
||
}
|
||
],
|
||
"usage": {
|
||
"prompt_tokens": 12,
|
||
"completion_tokens": 8,
|
||
"total_tokens": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
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
|
||
}
|
||
}
|
||
```
|
||
|
||
流式返回建议直接走 SSE,每个 chunk 保持 OpenAI 风格:
|
||
|
||
```text
|
||
data: {"id":"chatcmpl_fake_stream_001","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"你好"},"finish_reason":null}]}
|
||
|
||
data: {"id":"chatcmpl_fake_stream_001","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":",这里是"},"finish_reason":null}]}
|
||
|
||
data: {"id":"chatcmpl_fake_stream_001","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" fake:ai"},"finish_reason":null}]}
|
||
|
||
data: {"id":"chatcmpl_fake_stream_001","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
|
||
|
||
data: [DONE]
|
||
```
|
||
|
||
如果要支持 tool call,可在 `choices[0].message.tool_calls` 或 stream delta 里返回固定结构;第一版不需要复杂执行器,只要能让 GoChat 和前端正确进入“收到了 tool call”分支即可。
|
||
|
||
## 12. 推荐执行批次
|
||
|
||
### 批次 A:主壳与消息链路
|
||
|
||
- 登录
|
||
- dashboard
|
||
- 会话列表/详情
|
||
- fake 入站/出站/auto reply
|
||
- contacts / companies / search / notifications
|
||
|
||
### 批次 B:settings 与后台页面
|
||
|
||
- agents / teams / custom roles
|
||
- inbox / labels / attributes / canned / macros
|
||
- automations / assignment policy / sla / reports
|
||
- integrations / audit / billing / help center
|
||
|
||
### 批次 C:widget / public
|
||
|
||
- widget config
|
||
- pre-chat
|
||
- public csat
|
||
- public help center
|
||
- campaign 触达验证
|
||
|
||
### 批次 D:AI
|
||
|
||
- 先接 `fake:ai`
|
||
- 再跑 captain settings / assistants / documents / responses / scenarios / tools / playground / copilot / task actions
|
||
|
||
## 13. 本轮建议结论
|
||
|
||
这轮如果要真正做到“每个页面特性功能点详细测试”,我建议按下面的定义推进:
|
||
|
||
1. 先把已有 CDP 计划升级为“页面矩阵 + 数据缺口 + AI 桩方案”。
|
||
2. 先以 `seed + fake channel` 打通非 AI 的主流程。
|
||
3. 把缺失的真实数据补到能覆盖列表、详情、筛选、报表,而不是只停留在 smoke 空态。
|
||
4. 单独补一个 `fake:ai`,通过 `openai_compatible` 接到当前 Copilot/Captain 运行时。
|
||
5. AI 不接 fake 之前,只能做“页面渲染级”验证,不能算“全量实际功能测试完成”。
|
||
|
||
## 14. 建议下一步
|
||
|
||
按性价比最高的顺序,下一步建议是:
|
||
|
||
1. 先补 `fake_01 inbox + 第二个 agent + 多状态 conversations`
|
||
2. 再开始批次 A 的 CDP 实测
|
||
3. 同时排一个小实现项:落地 `fake:ai`
|