62 KiB
2026-07-19 GoChat CDP 全量用户功能测试计划
创建日期:2026-07-19
最后更新:2026-07-20(Monday, July 20, 2026)
适用仓库:/home/rogee/Projects/gochat
当前基线:你已手动启动backend + frontend + fake channel,下一步要基于 CDP 做真实用户点击路径验收
关联文档:
说明:
- 本文件是截至 Monday, July 20, 2026 这轮 GoChat CDP 用户功能验收的当前唯一主计划。
- 2026-07-15 / 2026-07-17 / 2026-07-18 三份文档保留为历史演进稿与执行上下文,不再作为新的主执行基线。
这份文档作为 2026-07-19 之后这轮 CDP 用户验收的当前执行基线。目标不是再写一份泛泛 QA 说明,而是把三件事一次定清楚:
- 哪些页面和子页面必须纳入点击式测试。
- 每个页面至少要验证哪些特性功能点,不能只看“能打开”。
- 哪些数据和 AI 测试支撑不补齐前,不能宣称“全量实际功能测试完成”。
0. 本轮直接执行摘要
为了让后续接 CDP 和逐页实测时不需要再从全文里二次提炼,这里先把本轮结论压成一页:
0.1 现在就能开始做的
- 复用你当前已经启动的
backend + frontend + fake channel。 - 先接入 Chrome CDP,按真实点击路径做 dashboard 内部页面验收。
- 非 AI 页面先做
可达 / 可见 / 可载 / 可用 / 可回 / 可观测六项检查。 - 证据统一沉淀到:
0.2 这轮不能混淆的边界
- 当前三服务足够支撑:
- 登录
- dashboard 主壳
- fake 会话主链路
- 联系人 / 公司 / settings 首轮点击验收
- widget / help center / campaigns 首屏与入口检查
- 当前三服务还不够支撑:
- Captain / Copilot / Playground / Embeddings 的真实 AI 成功链路
- 报表、CSAT、SLA、Audit 的完整实际功能验证
- 多坐席协作、mentions、团队分配、容量策略等需要额外数据的场景
- 另有一类问题不能混进“缺数据”:
- 如果页面主链路 API 已稳定出现
429 - 或
/cable握手持续429,导致全局离线的 - 这类要优先记为运行时/限流/鉴权缺陷,而不是简单记成“样本不够”
- 如果页面主链路 API 已稳定出现
0.3 开始“全量实际功能测试”前必须补齐的东西
fake_01inbox 与 fake webhook 回流必须真正打通- 至少 1 个额外可登录 agent
- 一组多状态会话池(open / pending / resolved / snoozed / assigned)
- 一组非空 CRM / labels / teams / attributes 数据
- 一套本地 deterministic
fake:ai
0.4 fake:ai 的本轮定位
- 参考现有
channels/fake的工程组织方式新增channels/fake-ai - 不先改 GoChat provider 抽象,直接复用现有
openai_compatible - 首版只要优先打通:
POST /v1/chat/completionsPOST /v1/embeddingsGET /health- 基础请求观测接口
- 但流式 SSE 不能省,否则 Copilot / Playground / 会话内 AI task 仍只能算半测
1. 当前已知运行前提
你已经手动启动:
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 页面 |
| backend | http://127.0.0.1:3000 |
API / webhook / websocket / AI 任务后端 |
| fake channel | http://127.0.0.1:9100 |
外部客户消息模拟、GoChat 出站消息回收、auto reply 回流 |
| Chrome CDP | http://127.0.0.1:9222 |
浏览器接管与点击式取证 |
当前仓库里已经确认的事实:
| 项 | 当前状态 | 说明 |
|---|---|---|
| 根脚本 | 已有 fake:start / fake:dev / fake:test |
fake message 平台已可运行 |
| workspace | 仅包含 frontend 与 channels/fake |
目前没有 channels/fake-ai |
| fake webhook 接口 | 已有 /webhooks/fake/:identifier |
fake channel 可以回流到 GoChat |
| LLM provider | 已支持 openai_compatible |
可直接接本地 OpenAI-compatible 假服务 |
| AI 请求路径 | {baseURL}/chat/completions、{baseURL}/embeddings |
fake:ai 不需要先改 provider 抽象 |
因此本轮测试边界要分成两层:
- 非 AI 功能:现在就可以开始做 click-only CDP 实测。
- AI 功能:先补
fake:ai,再进入“全量实际功能测试”。
1.1 本轮已复核的 checkout 事实
为了避免计划继续沿用旧假设,这里把这次实际对过代码和脚本的结论单独固定下来:
| 类别 | 已复核事实 | 结论 |
|---|---|---|
| 根脚本 | package.json 当前只有 fake:start / fake:dev / fake:test,dev:all 也只并发 backend + frontend + fake |
目前仓库里还没有现成的 fake:ai 脚本,需要新增 |
| fake channel 形态 | fake message 平台已经独立在 channels/fake |
适合作为 channels/fake-ai 的工程骨架参考 |
| fake channel 默认 webhook | channels/fake/src/index.ts 默认指向 http://127.0.0.1:3000/webhooks/fake/fake_inbox_1 |
本轮若使用 fake_01,必须显式通过环境变量或 POST /api/config 覆盖,否则会出现 fake 健康正常但 GoChat 不建会话的假失败 |
| fake channel 控制面 | 已有 POST /api/send、GET /api/messages、GET /api/status、POST /api/reset、POST /api/config、GET /health、POST /receive |
会话 E2E、出站回收、自动回流、批量造数都可以围绕现有 fake control surface 设计,不需要再额外补一套消息注入工具 |
| OpenAI-compatible provider | backend/internal/llm/openai_provider.go 当前会把 baseURL 去掉尾部 /,然后实际调用 POST {baseURL}/chat/completions、流式 POST {baseURL}/chat/completions、POST {baseURL}/embeddings |
fake:ai 只要实现 OpenAI-compatible 最小面即可,不需要先改 GoChat provider 抽象 |
| 流式能力 | 当前 provider 已有 ChatCompletionStream,按 SSE 解析 chunk |
如果会话回复框、Playground 或 Copilot 走流式,fake:ai 不能只做非流式 JSON |
| Captain / Copilot 路由面 | 当前后端已存在 assistants / responses / documents / scenarios / custom_tools / copilot_threads / tasks 等 Captain API | AI 页面覆盖可以按真实页面族拆,不需要先补路由 |
1.1.1 本轮计划涉及到的关键代码锚点
为了让后面补数据、接 fake:ai、接 CDP 时都能直接落到代码位置,而不是继续靠口头记忆,这里把本轮最关键的 checkout 锚点再固定一遍:
| 主题 | 代码位置 | 本轮用途 |
|---|---|---|
| 根脚本入口 | package.json |
确认当前只有 fake:start / fake:dev / fake:test,还没有 fake:ai 启动脚本 |
| workspace 成员 | pnpm-workspace.yaml |
确认当前 workspace 只纳入 frontend 与 channels/fake,后续若落地 channels/fake-ai 需要补到这里 |
| fake 默认 webhook | channels/fake/src/index.ts |
确认默认仍是 http://127.0.0.1:3000/webhooks/fake/fake_inbox_1,不是这轮要测的 fake_01 |
| fake 控制面 | channels/fake/src/server.ts |
对照现有 POST /api/send、POST /api/config、POST /api/reset、GET /api/status、GET /api/messages 是否足够支撑造数与回流观察 |
| OpenAI-compatible provider 入口 | backend/internal/llm/provider_manager.go |
确认当前 chat / embedding provider 已接受 openai_compatible |
| chat/embedding 实际请求路径 | backend/internal/llm/openai_provider.go |
确认 fake:ai 至少要兼容 POST /v1/chat/completions、流式 POST /v1/chat/completions、POST /v1/embeddings |
| smoke seed 对象 | backend/cmd/gochat/main.go |
确认当前 seed 已准备 smoke account、website inbox、help center、crm、sla、captain 等基线对象 |
| smoke feature flags | backend/cmd/gochat/main.go |
确认 campaigns、captain_integration_v2、help_center、reports、team_management、channel_email、channel_voice 等入口默认应处于开启基线 |
1.2 当前 smoke seed 能直接提供的基线
执行前如果本地数据过脏或过空,仍然建议先跑一次:
cd backend
go run ./cmd/gochat seed
按当前 backend/cmd/gochat/main.go 的 smoke seed,实现上已经会直接准备出下面这些基线对象:
| 类别 | 当前 seed 已覆盖 | 适合先验证什么 |
|---|---|---|
| 管理员与账户 | admin@gochat.local / changeme、Test Account |
登录、dashboard 主壳、General/Profile/Account 基线 |
| Website inbox | Test Website Inbox,含 website_token、欢迎语、CSAT、email collect |
widget、pre-chat、campaign、website inbox settings |
| Voice inbox | Smoke Voice Inbox(当前为 twilio_sms 型 smoke inbox) |
voice/twilio 相关设置页、降级态、渠道多样性 |
| CRM 基线 | Smoke Customer、Smoke Company |
联系人/公司详情、会话侧栏联动 |
| 会话与消息 | 1 条 open conversation,含 incoming / outgoing / CSAT template 消息 | 会话详情基线、消息渲染基线、CSAT 展示基线 |
| Help Center 基线 | Smoke Help Center、1 个 category、1 篇 published article |
portal、article、public help center 基线 |
| SLA / 权限基线 | 1 条 Smoke SLA、1 条 custom role、1 条 capacity policy |
SLA 页面、权限页面、assignment policy 基线 |
| Captain 基线 | 1 个 Smoke Captain assistant、1 条 Captain message、1 个 agent bot |
Captain 列表/详情首屏、conversation 内 Captain 渲染 |
这组 smoke seed 足够让我们先开始“页面能否挂载、入口是否通、基础 CRUD 是否可点”的第一轮 CDP 检查;但它还不够支撑“全量实际功能测试完成”。后文第 6 节列出的缺口,默认都是在这组 seed 基线上继续补的,而不是从零开始。
另外有两个这次已经对过代码、执行时很容易误判的点,建议直接记住:
- 当前 smoke account 会一次性打开大量 feature flags,包括
campaigns、captain_integration_v2、custom_tools、help_center、inbox_view、reports、sla、team_management、channel_email、channel_voice等,所以首轮 CDP 的目标应是验证“这些入口是否真的可挂载、可加载、可操作”,而不是先怀疑入口没显示是产品未开功能。 - 当前 smoke conversation 的
labels只是会话表上的字符串值vip,不是完整的 labels 配置数据集;因此如果标签列表页、标签筛选器或标签报表看起来“有一个标签能显示”,也不能把它算作 labels 功能已完成真实验证。
1.3 当前可立即开测 vs 必须补前置
为了让后续执行不至于一上来就把 AI/报表/高级后台全部点成一片 blocked,建议先把页面族按“现在就能开始”和“必须补前置”拆清楚:
| 页面族 | 当前状态 | 说明 |
|---|---|---|
| 登录 / dashboard 主壳 / 一级导航稳定性 | 可立即开测 | 现有 backend + frontend 已满足 |
| 会话主链路(列表、详情、回复、fake 入站/出站/auto reply) | 可立即开测,但依赖 fake_01 inbox 建档 |
如果 fake 配置仍指向默认 fake_inbox_1,要先纠正 |
| 联系人 / 公司 / 搜索 / 通知 | 可开始首屏与基础跳转 | 但若 contacts/companies 太少,分页/搜索/合并只能记 partial 或 blocked |
| Settings / Agents / Teams / Labels / Attributes / Inboxes | 可开始首屏与基础 CRUD | 多数页面可先测渲染与保存;成员绑定、团队联动依赖第二个 agent |
| Reports / CSAT / SLA / Audit | 需要更多真实数据后再做“全量实际功能” | 没有 metrics 样本时只能做挂载验证 |
| Campaigns / Widget / Public Help Center | 需要 website inbox 与 portal 内容更完整 | launcher 可测不等于用户链路已通过 |
| Captain / Copilot / Playground / Embeddings | 需要 fake:ai 后再进入真实功能测试 |
当前最多只能做页面渲染、表单、错误态 |
建议首轮执行顺序固定为:
- 登录与 dashboard 主壳
- fake 会话主链路
- 联系人 / 公司 / 搜索 / 通知
- Settings 基础 CRUD
- 补数据
- Reports / Campaigns / Widget / Help Center
fake:ai接入后再跑 Captain / Copilot / Playground / Embeddings
2. 强约束
2.1 导航约束
- 登录页、widget/public 根入口允许直接打开。
- 登录后的 GoChat 内部页面一律通过真实 UI 点击进入。
- 不允许把
/app/accounts/:id/...深链当成页面通过证据。 - 如果只能靠手输 URL 才能进入,记为入口或路由组织问题,不算通过。
2.2 页面判定约束
每个页面至少同时满足以下 6 项,才可判为 pass:
- 可达:通过真实 UI 路径点击进入。
- 可见:主区域不是空壳,不是只变 URL。
- 可载:关键 API 2xx,首屏数据成功加载。
- 可用:至少 1~3 个核心操作真实执行成功。
- 可回:返回列表、刷新、再次进入时状态一致。
- 可观测:console、network、runtime exception 已留证。
以下情况不能算通过:
- URL 改了,但主区域没切换。
- 主区域只显示
离线的、空白、Vue update error、Unhandled promise error。 - 页面主链路接口 4xx/5xx,且无明确降级提示。
3. 执行前检查
| 检查项 | 动作 | 通过标准 |
|---|---|---|
| backend health | GET /health |
200 |
| frontend login | 打开 /app/login |
登录页正常渲染 |
| fake health | GET http://127.0.0.1:9100/health |
status=ok |
| seed 基线 | 必要时执行 cd backend && go run ./cmd/gochat seed |
至少能登录并看到 smoke 基础对象 |
| fake config 对齐 | POST http://127.0.0.1:9100/api/config 或读取当前 fake 状态 |
确认 webhook 实际指向 /webhooks/fake/fake_01;不要沿用代码默认的 fake_inbox_1 |
| fake inbox 绑定 | 确认 GoChat 内存在 fake_01 对应 fake inbox |
fake 入站能建会话 |
| CDP attach | GET http://127.0.0.1:9222/json/version |
能拿到 webSocketDebuggerUrl |
| Node tooling | command -v npx |
npx 可用 |
| 登录态 | 通过 UI 登录 | 能进入 dashboard |
| websocket | 登录后观察 /cable |
无持续 401/403/重连风暴 |
| 报告落点 | 确认 report 文件存在 | 本轮证据统一追加到既有 report |
3.1 基于当前 fake channel 的最小造数配方
当前这轮不需要先新写消息注入脚本。channels/fake 已经提供了足够的控制面,可以直接拿来准备 CDP 首轮数据:
| fake 接口 | 作用 | 适合准备什么 |
|---|---|---|
POST /api/send |
模拟客户发首条消息到 GoChat | 批量建 open 会话、补联系人最近消息 |
POST /api/reply |
模拟客户针对某条消息回复 | 验证 reply chain、引用回复、同会话回流 |
POST /api/close |
模拟渠道侧结束会话 | 验证会话结束事件、关闭后的 UI 状态 |
POST /api/typing |
模拟客户输入中 | 验证 typing indicator |
POST /api/agent/online / POST /api/agent/offline |
模拟坐席在线状态观测 | 在线状态、presence、分配辅助验证 |
GET /api/messages |
查看 GoChat 出站消息是否回流 fake | 验证 agent 回复、自动回复、模板出站 |
POST /api/reset |
清空 fake 内存态 | 每批次回归前重置观察面板 |
GET /api/status |
查看 fake 当前状态与计数 | 开测前确认平台不是脏态 |
建议固定先跑一次:
curl -X POST http://127.0.0.1:9100/api/reset
curl http://127.0.0.1:9100/api/status
然后至少灌入一条首消息,确认 fake_01 主链路已通:
curl -X POST http://127.0.0.1:9100/api/send \
-H 'Content-Type: application/json' \
-d '{
"inbox_identifier":"fake_01",
"sender_id":"cdp_customer_001",
"sender_name":"CDP Customer 001",
"content":"你好,这是一条 CDP 首轮基线消息"
}'
再用 dashboard 回复一次后,通过:
curl http://127.0.0.1:9100/api/messages
确认 fake 已收到 GoChat 出站消息。这样可以先锁定“入站、坐席回复、fake 回收出站”三段链路都成立,再继续更大范围页面测试。
需要注意:
- fake channel 最适合先批量造
open会话基线。 pending / resolved / snoozed / assigned / labeled更适合在 dashboard 里通过真实 UI 操作流转出来,这样数据准备本身也能顺手成为 CDP 功能验证的一部分。- 如果
GET /api/messages始终空,而 dashboard 看起来“已经回复成功”,优先回查 fake inbox 建档、webhook identifier、以及当前 fake config 是否仍指向默认fake_inbox_1。
3.2 当前已知运行时风险(不要误记为缺数据)
这部分用于约束后续报告判定口径。以下现象如果在 Monday, July 20, 2026 这一轮继续复现,应优先按“产品缺陷”记账,而不是按“缺数据”处理:
| 风险项 | 当前已见现象 | 影响页面族 | 推荐判定 |
|---|---|---|---|
| websocket 握手异常 | /cable 持续 429,主壳或子页伴随 离线的 |
会话、通知、Copilot、所有依赖实时状态的页面 | fail 或 partial pass with runtime issue |
| Contacts 主链路异常 | GET /api/v1/accounts/:id/contacts* => 429 |
联系人列表、active/segment/label 子页 | fail,不要记成“只是联系人太少” |
| Companies 主链路异常 | GET /api/v1/accounts/:id/companies* => 429 |
公司列表与详情入口 | fail |
| Reports 主链路异常 | /api/v2/accounts/:id/reports*、/live_reports*、/agents、/cache_keys 出现 429 |
报告总览、agent/team/label/inbox 子页 | fail,不要误记成“指标样本不足” |
| Campaigns 主链路异常 | GET /api/v1/accounts/:id/campaigns => 429 |
live chat / sms / whatsapp campaigns | fail |
| Help Center 主链路异常 | GET /api/v1/accounts/:id/portals => 429 |
portal、articles、categories、settings | fail |
| Copilot Config 主链路异常 | GET /api/v1/accounts/:id/copilot/config => 429 |
Copilot 配置、provider 保存前置读取 | 至少记 partial pass,不能算真实配置链路通过 |
执行时统一按下面规则处理:
- 如果页面只是空态,但关键 API 是
200,且当前数据确实不足,可记blocked: dataset missing。 - 如果页面首屏关键 API 是
429/4xx/5xx,即使 UI 壳层还在,也优先记fail或partial pass with runtime issue。 - 如果 URL 已切换,但主区叠加
离线的、空白壳、Vue update error,且同时伴随/cable或主链路 API429,优先归类为壳层/运行时缺陷。
4. CDP 统一取证格式
每个页面或子页至少记录:
- page group
- click path
- url
- expected
- observed
- api
- console
- verdict
每个页面族默认至少要有:
- 1 个首屏加载用例
- 1~3 个核心操作用例
- 1 个刷新/返回一致性用例
- 1 个异常、空态或边界态用例
4.1 每个页面都要套用的测试切面
为了避免后面执行时只测“能打开”,这里再把页面级测试切面固定下来。后续不管是 dashboard、settings、help center 还是 Captain 页面,都至少按下面维度套一次:
| 页面类型 | 必测切面 |
|---|---|
| 列表页 | 首屏加载、筛选、搜索、分页、排序、空态、列表项跳转 |
| 详情页 | 详情字段、关联对象、返回路径、刷新回显、跨模块跳转 |
| 表单页 | 必填校验、默认值、保存、错误提示、再次进入回显 |
| 配置页 | toggle / select / textarea / secret 输入、保存成功 toast、刷新后仍生效 |
| 弹窗/抽屉 | 打开、关闭、遮罩点击、取消、确认、成功后列表或详情联动 |
| 实时页 | websocket 更新、无需刷新出现新内容、重复事件不应脏写 |
| 文件/附件页 | 上传、失败提示、删除、二次进入状态一致 |
| AI 结果页 | loading、成功文本、超时、重试、错误态、可观测请求摘要 |
| 受限页 | 无权限时的降级态、禁用态、引导文案,而不是静默空白 |
建议执行时,每个页面至少从下面 10 个问题里勾掉 6 个以上:
- 入口是否只能靠真实点击进入?
- 首屏是否加载了正确 API,而不是只切 URL?
- 页面主文案、主按钮、主列表是否真实出现?
- 至少 1 个新增/编辑/删除/保存类核心动作是否成功?
- 成功后 toast、列表、详情或计数是否同步更新?
- 失败时是否给出明确错误,而不是静默失败?
- 刷新或返回后状态是否保持一致?
- 是否出现
离线的、空白壳、Unhandled promise、Vue update error? - 关键网络请求是否是预期方法与路径,且返回 2xx?
- 这个页面是否仍缺少数据,导致“看起来能用,实际上没测到功能”?
4.2 页面类型到最小动作的收口模板
上面的测试切面是在问“这个页面有没有活过来”;这里再补一层“不同类型页面至少该跑什么动作”,避免后续只做打开检查,没有把真实功能点跑实。
| 页面类型 | 至少要跑的动作 |
|---|---|
| 列表页 | 首屏加载、搜索、筛选、排序(若有)、分页/加载更多、点行进入详情、空态、错误态、刷新一致性 |
| 详情页 | 基础信息、关联对象、从详情发起编辑、返回列表、跨模块跳转回来、刷新回显一致 |
| 新建/编辑表单页 | 必填校验、格式校验、默认值、保存成功、保存失败提示、取消后不脏写、再次打开回显 |
| 弹窗/抽屉 | 打开、关闭、Esc/遮罩关闭、提交后主页面同步、失败后输入不丢失、重复打开不残留旧状态 |
| 消息/实时页 | 入站、出站、typing、状态流转、附件/富消息、掉线降级、刷新前后同一对象状态一致 |
| 配置/集成页 | 当前配置回显、secret 遮罩、保存、测试连接(若有)、错误配置提示、刷新后仍生效 |
| 报表/图表页 | 时间范围切换、维度/筛选切换、图表与列表同步、drilldown、导出/下载(若有)、空态/非空态 |
| Public / Widget 页 | 首屏渲染、入口打开、表单校验、提交、dashboard 回流验证、重新进入恢复路径 |
| AI 页 | success、timeout、rate_limit、malformed、stream、retry、历史恢复、请求观测接口回收 |
执行时建议按下面顺序收口:
- 先用第 4.1 节确认页面已经真实挂载。
- 再用本节确认这个页面类型对应的关键动作已经测到。
- 如果关键动作因为缺数据或缺
fake:ai跑不起来,直接记blocked,不要把“页面能打开”记成pass。
5. 页面覆盖矩阵
5.0 页面覆盖与源码落点对照
为了避免执行过程中只按左侧导航肉眼扫,而漏掉某些实际已存在的页面族,后续 CDP 执行时建议同时对照下面这些前端路由源文件:
| 页面组 | 主要路由文件 / 模块落点 | 说明 |
|---|---|---|
| Dashboard 主壳 | frontend/app/javascript/dashboard/routes/index.js |
登录后统一路由入口与保护逻辑 |
| 会话工作台 | frontend/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js |
包含 home、inbox、label、team、mentions、unattended、participating、custom view/folder 等主链路 |
| Inbox View | frontend/app/javascript/dashboard/routes/dashboard/inbox/routes.js |
inbox-view 列表与详情双栏视图 |
| 联系人 | frontend/app/javascript/dashboard/routes/dashboard/contacts/routes.js |
contacts、segments、labels、active、detail |
| 公司 | frontend/app/javascript/dashboard/routes/dashboard/companies/routes.js |
companies 列表与详情 |
| Campaigns | frontend/app/javascript/dashboard/routes/dashboard/campaigns/campaigns.routes.js |
ongoing、one_off、live_chat、sms、whatsapp |
| Help Center | frontend/app/javascript/dashboard/routes/dashboard/helpcenter/ |
portals、articles、categories、settings、search |
| Settings / Attributes | frontend/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js |
custom attributes 三类定义 |
| Settings / Canned | frontend/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js |
canned responses |
| Settings / SLA | frontend/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js |
SLA policy 配置页 |
| Settings / Automation | frontend/app/javascript/dashboard/routes/dashboard/settings/automation/ |
automation 规则条件与动作编排 |
| Captain | frontend/app/javascript/dashboard/routes/dashboard/captain/、frontend/app/javascript/dashboard/routes/dashboard/settings/captain/ |
assistants、documents、responses、scenarios、playground、provider config |
5.1 登录与 dashboard 主壳
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| 登录页 | /app/login |
邮箱/密码输入、回车提交、错误密码提示、loading、登录成功跳转 |
| dashboard 主壳 | 登录后默认页 | 左侧菜单、顶部栏、账号上下文、主区切换、刷新恢复 |
| 壳层稳定性 | 一级菜单切换 | URL 与主区同步更新,不出现 离线的/空白壳 |
5.2 会话工作台
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| 会话总览 | 左侧“会话” | open/pending/resolved/snoozed 列表、计数、分页、切换 |
| Inbox 维度会话 | 会话侧栏 inbox 分组 | inbox 过滤、列表切换、详情联动 |
| Label 维度会话 | 会话侧栏 label 分组 | 标签过滤、计数、详情打开 |
| Team 维度会话 | 会话侧栏 team 分组 | 团队过滤、分配联动 |
| Custom View / Folder 维度会话 | 会话侧栏自定义视图 | 视图过滤、保存视图、从视图进入详情后返回一致性 |
| Mentions / Unattended / Participating | 左侧特殊入口 | 对应列表、计数、切换稳定性 |
| 单会话详情 | 从列表点进会话 | 时间线、状态、优先级、标签、assignee、team、联系人/公司侧栏 |
| 回复能力 | 会话编辑区 | 发文本、private note、resolve/reopen、snooze、assign agent、assign team、加标签 |
| 富消息能力 | 会话编辑区 | 附件、预览、粘贴、模板或富消息渲染 |
| 实时链路 | fake channel + 会话页 | fake 入站、客服回复、fake 回收出站、auto reply 回流、无刷新更新 |
5.3 Inbox View
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Inbox View 列表 | Inbox View 入口 | 空态/非空态、筛选切换、主列表渲染 |
| Inbox View 详情 | 从 Inbox View 打开会话 | 列表与详情同步、返回路径稳定、主区真实切换 |
5.4 联系人与公司
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| 联系人列表 | 左侧“联系人” | 列表加载、搜索、分页、segment/label/active 过滤 |
| 联系人详情 | 列表点进详情 | 基础资料、自定义属性、标签、最近会话、最近活动 |
| 联系人操作 | 联系人页按钮/弹窗 | 新建、编辑、删除、合并、加标签 |
| 公司列表 | 左侧“公司” | 列表、搜索、分页、计数 |
| 公司详情 | 列表点进详情 | 基本信息、关联联系人、会话、备注、自定义属性 |
| CRM 联动 | 会话 ↔ 联系人 ↔ 公司 | 从会话侧栏跳联系人/公司,再回会话,状态不丢 |
5.5 全局搜索与通知
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| 全局搜索 | 顶部搜索入口 | conversations/messages/contacts/articles tab 切换、关键词高亮、跳转 |
| 搜索异常态 | 搜索接口异常时 | 有错误提示,不静默失败 |
| 通知中心 | 右上通知入口 | 列表加载、已读/未读、跳回目标会话或页面 |
5.6 Reports
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Overview | 左侧“报告”默认页 | 指标卡、筛选器、时间范围 |
| Conversations / Agents / Teams / Labels / Inboxes | 报告各子页 | 图表、筛选、列表、drilldown |
| CSAT | 报告 → CSAT | metrics、分布、评论、空态/非空态 |
| SLA | 报告 → SLA | metrics、列表、筛选、下载 |
| Bot / Live Reports | 报告相关子页 | feature gate、空态、列表或图表渲染 |
5.7 Settings:账户、组织、权限
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| General / Account | 设置 → General | 账户名、语言、时区、保存与刷新回显 |
| Profile | 设置 → Profile | 昵称、签名、头像、通知偏好 |
| Security / MFA / SSO | 设置相关子页 | 表单渲染、保存校验、受限能力降级提示 |
| Agents | 设置 → Agents | 列表、创建/邀请、编辑、重置密码、状态 |
| Teams | 设置 → Teams | 列表、新建、编辑、成员绑定 |
| Custom Roles | 设置 → Custom Roles | 列表、权限矩阵、创建/编辑、绑定用户 |
| Assignment Policy | 设置 → Assignment Policy | policy 列表、创建、编辑、inbox/agent 绑定 |
| Agent Capacity | Assignment Policy 子页 | 容量策略创建、编辑、保存回显 |
5.8 Settings:Inbox 与渠道
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Inbox 列表 | 设置 → Inboxes | 列表完整、类型徽标、入口稳定 |
| Website inbox | 具体 inbox 设置页 | 基础配置、欢迎语、营业时间、CSAT、预聊天表单、锁单会话 |
| Email inbox | Email inbox 设置页 | provider/SMTP/IMAP 表单、校验、降级态 |
| API inbox | API inbox 设置页 | token、endpoint、复制、回显 |
| Voice/Twilio | 对应 inbox 设置页 | voice 配置、缺配置时错误提示或降级态 |
| Fake inbox | fake inbox 设置页 | identifier/webhook 回显、channel 健康联动 |
| Inbox members / collaborators | inbox 成员页 | agent 绑定、移除、回显 |
5.9 Settings:提效工具与规则编排
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Labels | 设置 → Labels | 列表、创建、编辑、删除 |
| Custom Attributes | 设置 → Attributes | contact/conversation/company 三类定义 CRUD |
| Canned Responses | 设置 → Canned Responses | 列表、创建、编辑、插入编辑器 |
| Macros | 设置 → Macros | 列表、创建、编辑、执行宏后会话变化 |
| Automation | 设置 → Automation | event/condition/action 表单、create/edit/clone/delete |
| Conversation Workflow | 设置相关页 | 配置项渲染、保存、回显 |
| SLA Policies | 设置 → SLA | 列表、创建、编辑、删除、命中展示 |
5.10 Settings:Integrations、Audit、Billing
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Integrations Root | 设置 → Integrations | 卡片渲染、入口可点 |
| Webhooks | Integrations → Webhooks | 列表、创建、编辑、删除、测试 |
| Dashboard Apps | Integrations → Apps | 列表、创建、删除、iframe 装载 |
| Slack / Linear / Notion / Shopify 等 | 对应子页 | 配置页可见、错误态、保存/测试 |
| Audit Logs | 设置 → Audit Logs | 列表、筛选、真实操作写入可见 |
| Billing | 设置 → Billing | 页面加载、配额、enterprise 降级态 |
5.11 Campaigns、Help Center、Widget、Public
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Live Chat / SMS / WhatsApp Campaigns | 左侧“Campaigns” | 列表、创建、编辑、启停、依赖 inbox 校验 |
| Portal 列表 | 左侧“帮助中心” | portal 列表、切换、空态 |
| Articles | portal 内文章页 | 列表、tab、过滤、进入编辑 |
| New/Edit Article | 文章新建/编辑入口 | 新建、编辑、保存、预览 |
| Categories | portal 分类页 | 列表、新建、编辑、排序 |
| Locales | portal locales 页 | locale 列表、切换、多语言入口 |
| Portal Settings | portal settings 页 | 设置项加载、保存、异常态 |
| Widget Init | website widget 根入口 | 首屏渲染、launcher 打开 |
| Pre-chat form | widget 内流程 | 字段展示、必填校验、提交建会话 |
| Widget Messaging | widget 会话页 | 客户发首条消息、客服回复、回流验证 |
| Public CSAT | public csat 链接 | 页面可打开、评分提交、后台有回流证据 |
| Public Help Center | public portal 链接 | portal 首页、分类、文章、搜索 |
5.12 Captain / Copilot / AI 页面
| 页面组 | 入口 | 必测功能点 |
|---|---|---|
| Captain Config | 设置 → Captain / Copilot Config | provider 配置、feature toggle、model 保存、test config |
| Assistants | Captain 助手列表 | 列表、创建、编辑、删除 |
| Assistant Settings | 单助手 settings 页 | 基础信息、guardrails、response guidelines、保存回显 |
| Assistant Inboxes | 助手 inboxes 页 | 绑定/解绑 inbox |
| Documents | 助手 documents 页 | URL/PDF 创建、sync 状态、失败态、删除 |
| Responses / FAQs | 助手 responses 页 | 列表、pending 审核、approve/reject、搜索 |
| Scenarios | 助手 scenarios 页 | 列表、创建、编辑、启停、示例导入 |
| Custom Tools | 工具页 | 列表、创建、测试、启用禁用 |
| Playground | 助手 playground 页 | 发 prompt、接收稳定响应、错误态 |
| Conversation 内 AI Tasks | 会话页 AI 入口 | summarize、rewrite、reply suggestion、label suggestion、follow_up |
| Copilot Threads | Copilot 面板 | 创建 thread、发消息、接收回复、刷新恢复历史 |
说明:
- 在没有
fake:ai前,上面这些页面只能做“路由、表单、空态、错误态”验证。 - 只有接入本地 deterministic AI provider 后,才能把 Playground、Tasks、Copilot、Document Embedding 记为真实功能通过。
6. 还需要补充的、会影响全量实际测试的数据
6.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 |
本地 fake:ai |
1 套可观测 openai_compatible 假服务 |
Captain / Copilot / Playground / Embedding |
6.2 P1:不补就只能看空态或半成品态
| 缺口 | 最低要求 | 直接影响 |
|---|---|---|
| Contacts | 8~12 条 | CRM 列表、搜索、分页、合并 |
| Companies | 3~5 条 | 公司列表、详情、关联联系人 |
| Labels | 5 条以上 | 过滤、标签设置、报表 |
| Teams | 2 条以上 | 团队分配、团队报表 |
| Custom attributes | 三类各 2 条定义 | 表单、筛选、详情侧栏 |
| Canned responses | 3 条 | 编辑器插入、列表 CRUD |
| Macros | 3 条 | 会话执行宏 |
| Automation rules | 3 条 | 列表、编辑、条件动作校验 |
| Notifications | 5 条以上 | 通知列表与跳转 |
| Audit logs | 5 条以上 | 审计页真实内容 |
6.3 P2:不补就无法完成高级页验证
| 缺口 | 最低要求 | 直接影响 |
|---|---|---|
| Email inbox | 1 个 | email channel 配置页 |
| API inbox | 1 个 | API channel 页面与 token 展示 |
| Campaign 样本 | live chat / sms / whatsapp 各 1 条 | campaign 列表、编辑、启停 |
| Help Center 丰富数据 | categories 2+、articles 5+、locales 2+ | 多语言与分类切换 |
| CSAT responses | 5 条以上 | CSAT 页面、public submit 回流 |
| Applied SLA data | 3 条以上 | SLA metrics / download |
| Dashboard app | 1 个 | iframe app 页面 |
6.4 建议一次性补齐的数据包
| 数据包 | 推荐下限 |
|---|---|
| 管理员 | 1 |
| 普通 agent | 2 |
| custom role 用户 | 1 |
| fake inbox | 1 (fake_01) |
| website inbox | 1 |
| api inbox | 1 |
| email inbox | 1 |
| voice/twilio inbox | 1 |
| open 会话 | 4 |
| pending 会话 | 2 |
| resolved 会话 | 2 |
| snoozed 会话 | 2 |
| unattended / participating / mention 命中会话 | 各 1 |
| 附件消息 | 2 |
| private note | 2 |
| labels | 5 |
| teams | 2 |
| contacts | 10 |
| companies | 4 |
| canned responses | 3 |
| macros | 3 |
| automation rules | 3 |
| custom attributes | 三类各 2 |
| notifications | 5 |
| audit logs | 5 |
| csat responses | 5 |
| applied sla | 3 |
| help center portal | 1 |
| categories | 2 |
| published articles | 3~5 |
| campaigns | live chat / sms / whatsapp 各 1 |
| captain assistant | 1 |
| captain documents | 3(syncing / synced / failed) |
| captain responses | 5 |
| captain scenarios | 2 |
| captain custom tools | 1 |
6.5 页面组与数据依赖速查表
| 页面组 | 至少需要的数据 | 不满足时常见假象 |
|---|---|---|
| 登录 / dashboard 主壳 | 1 个可登录管理员 | 只能停在登录页,后续页面全部 blocked |
| 会话工作台 | fake_01 inbox、8+ 会话、不同 status、2 个 agent |
列表能开但过滤、分配、实时链路都是空壳 |
| 联系人 / 公司 | 10 contacts、4 companies、labels、custom attributes | 页面能进,但搜索、分页、联动、详情都接近空态 |
| 搜索 / 通知 | conversations、contacts、articles、notifications | 搜索永远空结果,通知中心只有空态 |
| Reports | 多状态会话、teams、labels、csat、applied sla | 图表能渲染但没有真实指标,无法验证 drilldown |
| Settings / Agents / Teams / Roles | 2 agents、2 teams、1 custom role 用户 | 列表可见但无法验证成员绑定、权限边界 |
| Settings / Inboxes / Channels | fake / website / api / email / voice inbox 各至少 1 套 | 只能看到部分渠道页,无法覆盖配置差异 |
| 自动化与提效工具 | canned responses、macros、automation rules、custom attributes | CRUD 可测性不足,执行链路难以验证 |
| Help Center / Public | 1 portal、2 categories、3+ published articles、2 locales | public 页可打开,但分类、多语言、搜索都不成立 |
| Widget / Campaigns | website inbox、campaign 样本、基础 contact / conversation | widget 只能看 launcher,无法验证建会话与触达 |
| Captain / Copilot / AI | assistant、documents、responses、scenarios、custom tools、fake:ai |
页面只剩渲染/空态,不能证明 AI 主链路可用 |
6.6 数据补齐来源建议
为了避免后续一边跑 CDP 一边临时决定“这批数据到底该怎么造”,建议按下面的来源优先级准备:
| 数据/能力 | 推荐来源 | 原因 | 备注 |
|---|---|---|---|
| 管理员、基础 account、website inbox、help center smoke 对象 | cd backend && go run ./cmd/gochat seed |
当前仓库已有最稳定的 smoke 基线 | 适合作为第一层底座,不建议手工从零建;但要记得它只给 1 条 open conversation,且标签只是字符串 vip |
fake_01 inbox |
GoChat 后台 UI 建档 | 需要和当前 GOCHAT_WEBHOOK_URL=/webhooks/fake/fake_01 精确对齐 |
要实际核对 identifier、channel type、回流是否打通 |
| 多状态 conversations / messages | pnpm fake:start + fake 平台批量发消息 |
最贴近真实入站链路,也最利于 CDP 留证 | 建议按 open / pending / resolved / snoozed 分批造数 |
| 第二个 agent、teams、custom role 用户 | GoChat 后台 UI 创建 | 这些本身就是待测功能的一部分 | 既能补数据,也能顺便验证 CRUD |
| contacts / companies / labels / canned responses / macros / custom attributes | GoChat 后台 UI 为主 | 列表、表单、回显、搜索都需要真实跑一遍 | 数量不够时再考虑补 seed/脚本 |
| notifications / audit logs / csat / applied sla | 真实操作回灌优先 | 这类页面最怕“有数据但来源不真实” | 可在前面批次执行时顺手沉淀 |
| campaigns 样本 | GoChat 后台 UI 创建 | 能同时覆盖依赖校验、表单保存、列表回显 | 至少 live chat / sms / whatsapp 各 1 条 |
| help center categories / articles / locales | GoChat 后台 UI 创建 | 页面入口、编辑器、public 渲染都要验证 | smoke seed 只够首屏,不够全量切换 |
| Captain assistant / documents / responses / scenarios / tools | Captain UI 创建 | 能顺便验证 AI 后台页面本身 | 真实成功链路仍依赖 fake:ai |
fake:ai |
新增 channels/fake-ai |
这是本轮唯一建议新增的测试底座 | 不建议继续把 AI 假服务塞进 channels/fake |
补齐顺序建议固定成:
seedfake_01inbox- 第二个 agent + teams
- fake channel 批量 conversations
- CRM / labels / canned / macros / attributes
- reports / csat / sla / audit 补回灌
fake:ai
其中第 2 步建议直接显式做一次 fake 配置对齐,避免把默认值带进测试:
curl -X POST http://127.0.0.1:9100/api/config \
-H 'Content-Type: application/json' \
-d '{
"webhook_url":"http://127.0.0.1:3000/webhooks/fake/fake_01",
"auto_reply":true
}'
然后再通过 fake 平台发一条测试消息,确认当前 inbox identifier 真的是 fake_01,而不是代码默认的 fake_inbox_1。
6.7 开始“全量实际功能测试”前的阻断清单
下面这张表建议直接作为开测前 checklist 使用。凡是标记为 blocked 的项,如果没补齐,就不要把对应页面族记成“真实功能已通过”:
| 检查项 | 最低标准 | 未满足时应如何标记 |
|---|---|---|
| 管理员登录 | 能稳定登录 admin@gochat.local 或等价管理员账号 |
blocked: auth baseline missing |
| 第二个 agent | 至少 1 个额外可登录 agent | blocked: collaboration baseline missing |
fake_01 inbox |
fake webhook 建会话、agent 回复回 fake、auto reply 回同会话 | blocked: message e2e baseline missing |
| 会话池 | 至少覆盖 open / pending / resolved / snoozed | blocked: conversation state coverage missing |
| CRM 数据 | contacts 8+、companies 3+ | blocked: crm dataset too thin |
| 标签/团队/属性 | labels 5+、teams 2+、三类 attributes 各 2+ | blocked: filtering and settings dataset missing |
| website inbox | widget/pre-chat 能真实建会话 | blocked: widget baseline missing |
| reports 数据 | CSAT、SLA、notifications、audit 至少有可见样本 | blocked: reports dataset missing |
| Help Center 数据 | portal/category/article/locale 至少各有 1 组真实对象 | blocked: help-center dataset missing |
fake:ai |
/v1/chat/completions、/v1/embeddings 可调用,且有请求观测接口 |
blocked: ai runtime baseline missing |
建议执行时把页面 verdict 分成三种,而不是只写 pass/fail:
pass:页面和核心功能已完成真实链路验证。fail:页面或功能本身有缺陷。blocked:页面本身未必坏,但因为缺前置数据/假服务,当前不能判定真实功能通过。
6.8 不要误判成“缺数据”的现有缺陷族
为了避免后续越测越乱,这里再把当前已经暴露出的非数据类问题单独列一次。它们不是靠补 contacts、companies、articles 或 fake:ai 就能自然消失的:
| 缺陷族 | 当前表现 | 为什么不能算“缺数据” |
|---|---|---|
/cable 全局 429 |
登录后多个页面都可能带 离线的 覆盖层 |
这是实时连接或限流问题,不是样本数量问题 |
contacts / companies / reports / campaigns / portals / copilot config 请求 429 |
页面能切路由,但主区同时出现空态、残留壳层或异常文案 | 关键 API 已经失败,说明当前是运行时或鉴权/限流问题 |
| Vue update error / Unhandled promise | URL 已更新但主区未真实挂载 | 这是壳层、store、router 或异常处理缺陷,不是数据不足 |
| “空态和非空态同时出现” | 列表卡片渲染了,但空态提示也保留在同页 | 这是前端状态管理或条件渲染问题,不是单纯缺少样本 |
因此后续报告里建议把“缺数据”与“运行时缺陷”拆开写:
- 缺数据:
blocked: dataset missing - 假服务未就绪:
blocked: ai runtime baseline missing - 运行时问题:
fail: runtime 429/fail: websocket degraded/fail: shell mount error
7. 数据补齐策略
7.1 先用 seed 打底
cd backend
go run ./cmd/gochat seed
7.2 再补 fake channel 所需真实 inbox
最少需要把 fake_01 这个 webhook 标识对应到 GoChat 内的 fake inbox 配置,确保:
- fake 发出的入站消息能建会话
- dashboard 发出的出站消息能回到
/receive - auto reply 回来的消息能附着到同一会话
7.3 把数据分三类准备
| 类别 | 数据 | 建议方式 |
|---|---|---|
| 主链路数据 | admin / 2 agents / fake inbox / website inbox / 基础 conversations | 执行前一次性准备 |
| CRUD 数据 | labels / teams / macros / canned / custom attributes | 在 CDP 首轮过程中边测边创建 |
| 报表数据 | csat / applied_sla / notifications / audit logs | 定向 seed 或通过真实操作回灌 |
8. AI 测试支撑:fake:ai
8.1 为什么需要单独补 fake:ai
当前仓库的 AI 运行时已支持 openai_compatible provider,实际会打:
/chat/completions/embeddings
所以不需要先改 GoChat 的 provider 抽象,优先补一个本地 OpenAI-compatible 假服务即可。
如果没有本地 deterministic AI provider,Captain/Copilot 测试会卡在:
- 依赖真实第三方 key
- 响应不可复现
- 超时、429、stream 中断、tool call 失败无法稳定覆盖
8.2 fake:ai 的建议工程形态
建议新增 channels/fake-ai,并与现有 channels/fake 保持同构:
| 项 | 建议 |
|---|---|
| 目录 | channels/fake-ai |
| 根脚本 | fake:ai、fake:ai:dev、fake:ai:test |
| workspace | 把 channels/fake-ai 纳入 pnpm-workspace.yaml |
| 控制面 | /health、/api/config、/api/reset、/api/status、/api/requests |
| 核心接口 | POST /v1/chat/completions、POST /v1/embeddings |
建议后续本地服务矩阵统一成:
pnpm dev:backend
pnpm dev:frontend
pnpm fake:start
pnpm fake:ai
8.3 fake:ai 的最小接口与兼容约束
| 方法 | 路径 | 用途 |
|---|---|---|
GET |
/health |
健康检查 |
POST |
/v1/chat/completions |
Playground / Copilot / AI task;同时要支持普通 JSON 返回与 stream=true 的 SSE chunk 返回 |
POST |
/v1/embeddings |
document embedding / reindex |
这里不建议把流式支持当成“后面再加”的可选项。原因是当前 backend/internal/llm/openai_provider.go 已经实现了 ChatCompletionStream,所以只做非流式 JSON 会让 Playground、Copilot 或会话内 AI task 的一部分路径继续停留在“未真实验证”状态。
embedding 第一版也建议直接返回与当前 GoChat 默认配置兼容的固定维度向量,优先按 1536 实现。这样能避免出现“/v1/embeddings 已可调用,但 Copilot config test、Captain document sync 或向量入库仍因维度不匹配而失败”的假 blocker。
同时建议把流式返回格式也固定下来,避免后面 fake:ai 已经在返回 SSE,但 GoChat 仍然解析不到有效 chunk:
- 返回头至少包含
Content-Type: text/event-stream - 每个 chunk 使用标准 SSE
data: ...行 data内容直接放 OpenAI-compatible JSON chunk- 结束时发送
data: [DONE]
也就是说,fake:ai 的流式接口要兼容当前 provider 对下面这种结构的预期:
data: {"choices":[{"index":0,"delta":{"content":"hello"}}]}
data: {"choices":[{"index":0,"delta":{"content":" world"}}]}
data: [DONE]
如果后续只返回自定义 event name、只返回纯文本 token,或缺少 [DONE],那么本地服务虽然“看起来有流式输出”,但在 GoChat 里仍会表现成 Copilot/Playground 一直 pending 或最终空结果。
8.3.1 建议直接固定的最小响应样例
为了让 fake:ai 的实现与后续 CDP 验证都尽量少走弯路,建议把最小返回样例也直接固定下来。
普通 chat completion 建议至少返回:
{
"id": "chatcmpl-fake-001",
"object": "chat.completion",
"created": 1784428800,
"model": "fake-gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "这是一个稳定的 fake:ai 响应。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 10,
"total_tokens": 22
}
}
流式 chat completion 建议至少返回:
data: {"id":"chatcmpl-fake-002","object":"chat.completion.chunk","created":1784428801,"model":"fake-gpt-4o-mini","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-fake-002","object":"chat.completion.chunk","created":1784428801,"model":"fake-gpt-4o-mini","choices":[{"index":0,"delta":{"content":"这是"},"finish_reason":null}]}
data: {"id":"chatcmpl-fake-002","object":"chat.completion.chunk","created":1784428801,"model":"fake-gpt-4o-mini","choices":[{"index":0,"delta":{"content":"流式回复。"},"finish_reason":null}]}
data: {"id":"chatcmpl-fake-002","object":"chat.completion.chunk","created":1784428801,"model":"fake-gpt-4o-mini","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
embedding 建议至少返回:
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [0.001, 0.002, 0.003]
}
],
"model": "fake-text-embedding-3-small",
"usage": {
"prompt_tokens": 8,
"total_tokens": 8
}
}
注意:
- 第一版文档里示例向量可以只写 3 个值,但实际
fake:ai实现建议按配置生成固定维度,例如1536。 message.content、流式delta.content、usage、finish_reason都建议保留,避免 Captain / Copilot / Playground 某条路径因为字段缺失而出现“服务已通但前端仍不可用”的假失败。- 如果后续要覆盖 tool call,建议在
tool_call场景里额外返回tool_calls字段,而不是污染success_text的默认响应。
8.4 fake:ai 推荐场景开关
| 场景 | 用途 |
|---|---|
| success_text | 正常文本回复 |
| success_stream | 正常流式输出 |
| tool_call | 验证 custom tool / search_documentation |
| empty | 空回复降级 |
| malformed | 非法结构错误提示 |
| timeout | loading / cancel / retry |
| rate_limit | 429 提示 |
| unauthorized | provider 配置错误提示 |
| embedding_success | 正常 embedding |
| embedding_fail | reindex / document failed 态 |
8.5 推荐控制接口
| 方法 | 路径 | 用途 |
|---|---|---|
POST |
/api/scenario |
切换当前场景 |
POST |
/api/reset |
清空调用历史 |
GET |
/api/requests |
观察收到的 prompt / embedding 请求 |
GET |
/api/status |
当前模式、计数、最近错误 |
POST |
/api/config |
默认模型、延迟、stream 开关、默认场景 |
GET /api/requests 建议至少记录:
- timestamp
- route
- scenario
- model
- messages / input 摘要
- response status
- latency
- tool calls / stream chunk 数
- 最近一次 error
8.6 推荐接入模板
建议默认约定:
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
FAKE_AI_EMBED_DIMENSIONS=1536
然后在 Copilot/Captain 配置中:
- provider 选
openai_compatible - base URL 指向
http://127.0.0.1:9110/v1 - API key 填固定占位值即可
8.7 fake:ai 与现有 fake channel 的关系
为了降低心智负担,建议 fake:ai 直接复用 channels/fake 的工程组织思路:
| 维度 | channels/fake |
建议中的 channels/fake-ai |
|---|---|---|
| 角色 | 模拟外部消息渠道 | 模拟外部 LLM / embedding provider |
| 目标 | 让消息主链路可重复、可观测 | 让 AI 主链路可重复、可观测 |
| 健康检查 | /health |
/health |
| 配置入口 | /api/config |
/api/config |
| 状态/观测 | /api/status、回流消息观察 |
/api/status、/api/requests |
| 重置能力 | 可重置消息状态 | 可重置请求历史与场景 |
| 回放价值 | 复现客户入站/客服出站/auto reply | 复现 success / timeout / 429 / malformed / tool_call |
这样后面无论是人工调试还是 CDP 自动验收,都可以把两类假服务当作同一风格的本地测试底座:
fake channel负责“消息是否真的通”fake:ai负责“AI 调用是否真的通”
8.8 AI 页面与 fake:ai 场景对照表
为了让后续执行不是“把 AI 页点一遍就算过”,这里把建议场景和页面绑定起来:
| AI 页面/链路 | 至少要跑的 fake:ai 场景 |
通过标准 |
|---|---|---|
| Captain provider config | success_text、unauthorized |
保存成功;错误 key 时有明确失败提示 |
| Assistant Playground | success_text、timeout、rate_limit |
能看到成功回复、超时 loading/重试、429 提示 |
| Copilot thread / message | success_text、success_stream、malformed |
新 thread 可收到回复;流式时逐步渲染;坏结构时有错误态 |
| Conversation AI Tasks | success_text、rate_limit、timeout |
summarize / rewrite / suggestion 有结果或明确失败提示 |
| Document create + sync | embedding_success、embedding_fail |
文档状态可从 syncing 到 synced/failed,并有可见错误 |
| Responses / FAQ approve flow | success_text |
AI 生成结果可见,审批/拒绝后列表回显正确 |
| Custom tool chain | tool_call、malformed |
工具调用结果可见;坏工具结果不应打崩页面 |
| Scenario / auto reply 验证 | success_text、empty |
命中特定场景时会产生可解释输出;空响应有降级路径 |
建议 fake:ai 每个场景都支持固定响应模板,这样同一条 CDP 用例多次重跑时,页面文案、状态流转、请求摘要都能稳定复现。
8.9 fake:ai 首版完成标准
为了避免后续 fake:ai 做成“接口存在,但 GoChat 还是测不起来”的半成品,建议首版直接以下面标准验收:
| 验收项 | 最低标准 |
|---|---|
| 健康检查 | GET /health 返回 200 |
| OpenAI-compatible chat | POST /v1/chat/completions 支持普通 JSON |
| OpenAI-compatible stream | stream=true 时返回标准 SSE chunk,并以 [DONE] 结束 |
| OpenAI-compatible embeddings | POST /v1/embeddings 返回固定维度向量,默认建议 1536 |
| 场景切换 | 可通过控制接口切到 success_text / success_stream / timeout / rate_limit / unauthorized / malformed / embedding_success / embedding_fail / tool_call |
| 观测能力 | GET /api/requests 至少能看到 route、scenario、model、status、latency、请求摘要 |
| 重置能力 | POST /api/reset 可清空历史,便于重复跑同一条 CDP 用例 |
| GoChat 接入 | Captain/Copilot 选 openai_compatible,把 base_url 指向本地 http://127.0.0.1:9110/v1 后,可稳定完成至少 1 条 Playground 成功回复和 1 条 Embedding 成功请求 |
如果只满足“能回一个普通 JSON 文本”,但还没有流式、embedding、观测接口,那么它最多算 fake:ai 原型,不建议把 AI 页面族记为“可开始全量实际功能测试”。
9. 推荐执行批次
批次 A:主壳与消息链路
- 登录
- dashboard 主壳
- 会话列表 / 详情
- fake 入站 / 出站 / auto reply
- contacts / companies / search / notifications
批次 B:settings 与后台页面
- agents / teams / custom roles
- inbox / labels / attributes / canned / macros
- automation / 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
9.1 每个批次的进入 / 退出标准
为了避免后续执行时“上一批次根本没打稳,就继续往下点”,建议给每个批次加一个最小 gate:
| 批次 | 进入条件 | 退出标准 |
|---|---|---|
| A:主壳与消息链路 | backend / frontend / fake channel 正常;管理员可登录;fake_01 inbox 已建档 |
一级导航点击后主区真实切换;至少 1 条 fake 入站建会话成功;至少 1 条 agent 出站被 fake 回收;至少 1 条 auto reply 回附到同会话 |
| B:settings 与后台页面 | A 已通过;第二个 agent、teams、labels、contacts/companies 基础数据已补齐 | Agents / Teams / Inboxes / Labels / Attributes / Assignment Policy / Reports 至少都完成首屏 + 1 个核心操作验证 |
| C:widget / public | website inbox、portal/category/article 至少各有 1 套真实对象 | widget 能从 pre-chat 建会话;public help center 可完成 portal → category → article 点击链路;public CSAT 可提交 |
| D:AI | fake:ai 已启动;Captain/Copilot 使用 openai_compatible 指向本地 base_url;至少 1 个 assistant 已配置 |
Playground、Copilot、至少 2 个 conversation AI task、1 个 document embedding 链路完成 success/error 双场景验证 |
如果某一批次的进入条件没满足,报告里建议优先写成 blocked,而不是继续堆积大量“页面空态/无数据/接口没配置”的伪失败。
10. 本轮结论
如果目标是“每个页面的特性功能点都做详细测试”,建议按下面的定义推进:
- 这轮先以当前文档为 CDP 主计划。
- 先用
seed + fake channel打通非 AI 主流程。 - 先补齐
fake_01 inbox + 第二个 agent + 多状态会话 + CRM/标签/团队数据。 - 优先把当前已知的
/cable与多模块429问题从“缺数据”里剥离出来,按运行时缺陷单独记录。 - 单独补一个
fake:ai,通过openai_compatible接到当前 Copilot/Captain。 - 在
fake:ai未接入前,AI 页面只能算“渲染级验证”,不能算“全量实际功能通过”。
11. 下一步建议
建议按性价比最高的顺序继续:
- 先补
fake_01 inbox + 第二个 agent + 多状态 conversations - 开始批次 A 前,先把当前已知
429风险作为单独运行时检查项 - 再开始批次 A 的 click-only CDP 实测
- 同时立一个小实现项:落地
fake:ai - 后续所有证据统一追加到 docs/qa/reports/2026-07-15-cdp-user-function-report.md
12. 建议直接拆出的前置准备工单
为了避免后续 CDP 执行时一边点一边发现基础数据不够,建议先把缺口直接拆成下面几类工单:
| 工单 | 目标产出 | 完成标准 |
|---|---|---|
| 数据基线包 | admin / 2 agents / custom role user / contacts / companies / labels / teams / 会话池 | 登录后关键页面都不是纯空态,至少能覆盖列表、详情、筛选、分配 |
| fake inbox 工单 | fake_01 inbox 已在 GoChat 内建档并可稳定回流 |
fake 入站建会话、坐席回复回 fake、auto reply 附着同一会话 |
| website/widget 工单 | 1 套可用 website inbox + pre-chat 配置 | widget 能真实建会话,不只是 launcher 可见 |
| 报表回灌工单 | csat / sla / audit logs / notifications / campaigns 样本 | reports、audit、campaign 页不是空壳,能验证 drilldown/筛选 |
| Help Center 内容包 | portal / categories / articles / locales | public portal、文章搜索、分类、多语言可实际点击验证 |
fake:ai 工单 |
本地 OpenAI-compatible 假服务 + 观测接口 | Captain/Copilot/Playground/Embeddings 可以做真实主链路测试 |
如果要进一步压缩首轮准备量,推荐按下面顺序执行:
fake_01 inbox- 第二个 agent
- 多状态 conversations + contacts/companies
- website inbox + widget
fake:ai- reports / help center / campaigns 补样本
12.1 建议直接排期的执行清单
为了让这份计划文档能直接转成实施顺序,下面把建议拆成 7 个最小前置项。后续无论是继续让我补数据、补 fake:ai,还是直接开始 CDP 点击验收,都建议按这个顺序推进:
| 顺序 | 前置项 | 产出物 | 不完成时会卡住什么 |
|---|---|---|---|
| 1 | 对齐 fake_01 inbox |
GoChat 内有 1 个真实 fake inbox,identifier 与 GOCHAT_WEBHOOK_URL=/webhooks/fake/fake_01 一致 |
fake 入站会话、agent 出站回流、auto reply 链路都会变成假失败 |
| 2 | 准备第二个 agent | 至少 1 个额外可登录 agent 账号 | mentions、assign、participating、team 协作、在线状态无法做真实验证 |
| 3 | 补多状态会话池 | open/pending/resolved/snoozed 各有真实样本 | 会话筛选、报表、通知、SLA 大量页面只能看到空态 |
| 4 | 补 CRM 与筛选数据 | contacts、companies、labels、teams、custom attributes、notifications 至少达到本计划下限 | contacts/companies/search/filters 看起来能打开,但其实没有测到真实能力 |
| 5 | 补 website/widget 基线 | 1 套完整 website inbox + pre-chat 配置 + 至少 1 条真实 widget 建会话样本 | widget、campaign、public CSAT 只能做渲染级检查 |
| 6 | 补 reports/help center 样本 | csat、applied sla、audit logs、portal/category/article/locale、campaign 样本 | reports/help center 只能停留在空态或首屏壳层 |
| 7 | 落地 fake:ai |
本地 channels/fake-ai 服务,至少支持 /v1/chat/completions、/v1/embeddings、/api/requests |
Captain/Copilot/Playground/Embeddings 不能算真实 E2E |
12.2 fake:ai 首版建议验收口径
为了避免后续把 fake:ai 做成“接口在,但页面还是测不起来”的半成品,建议直接按下面口径验收首版:
| 验收项 | 最低标准 |
|---|---|
| Chat completion | POST /v1/chat/completions 同时支持普通 JSON 与 stream=true 的 SSE |
| Embeddings | POST /v1/embeddings 返回固定维度向量,默认建议 1536 |
| 场景切换 | 至少可切 success_text、success_stream、timeout、rate_limit、unauthorized、embedding_success、embedding_fail |
| 请求观测 | GET /api/requests 能看到最近请求摘要、响应状态、延迟、场景 |
| 配置切换 | POST /api/config 可调整默认模型、默认场景、是否流式、人工延迟 |
| 重跑能力 | POST /api/reset 能清掉历史请求,便于重复跑同一条 CDP 用例 |
| GoChat 接通证明 | Copilot/Captain 以 openai_compatible 指向本地 base_url 后,至少能稳定完成 1 条 Playground 成功响应和 1 条 embedding 成功请求 |