Files
gochat/docs/qa/2026-07-18-cdp-click-only-full-test-plan.md
T
2026-07-27 15:50:18 +08:00

44 KiB
Raw Blame History

2026-07-18 GoChat CDP 点击式全量功能测试计划

创建日期:2026-07-18
最后更新:2026-07-20
适用范围:/home/rogee/Projects/gochat
执行方式:连接已手动启动的本地 GoChat 服务,通过 Chrome DevTools Protocol 做真实点击路径测试
关联文档:

这份文档截至 2026-07-20 仍作为当前这轮 CDP 点击式全量测试的主执行基线;2026-07-152026-07-17 两份文档保留为补充参考,不再作为当前主执行稿。

1. 目标

这轮不是再写一个泛泛的 QA 说明,而是把后续 CDP 执行真正需要的三件事一次定清楚:

  1. 用点击式路径把 GoChat 当前可见的用户页面全部纳入测试范围。
  2. 把每类页面必须验证的功能点拆细,避免只看“能打开”。
  3. 明确哪些测试数据和哪些假能力没有补齐前,不能宣称“全量实际功能测试完成”。

2. 当前执行前提

用户已手动启动以下 3 个服务:

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 均已记录。

以下情况直接记 failpartial pass,不能算通过:

  • URL 改了,但 main 区域没切换。
  • 只看到 离线的、空白主区、Unhandled error during execution of component updateUncaught (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 / changemeTest Website InboxSmoke CompanySmoke 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.jsM03

页面组 真实入口 需验证的特性功能点
会话总览 左侧“会话” 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.jscompanies/routes.jsM04

页面组 真实入口 需验证的特性功能点
联系人列表 左侧“联系人” 列表加载、分页、搜索、active/segment/label 过滤
联系人详情 联系人列表点进详情 基本资料、自定义属性、标签、最近活动、可用操作
联系人操作 联系人页按钮/弹窗 新建、编辑、删除、合并、加标签
联系人与会话联动 从会话侧栏进入联系人,再返回 联动跳转正确、状态不丢
公司列表 左侧“公司” 列表、分页、搜索、计数
公司详情 公司列表点进详情 基本信息、关联联系人、历史记录、备注、自定义属性
公司与联系人联动 公司详情子 tab 添加联系人、关联联系人详情跳转

6.5 全局搜索

来源:modules/search/search.routes.js

页面组 真实入口 需验证的特性功能点
搜索总页 顶部搜索入口 默认页渲染、recent searches、空态
搜索结果 输入关键词后回车或选择结果 conversations/messages/contacts/articles tab 切换、高亮、跳转
错误态 搜索接口异常时 UI 错误提示、非静默失败、不会误显示空结果

6.6 通知中心

来源:notifications/routes.jsM08

页面组 真实入口 需验证的特性功能点
通知列表 右上或设置包装后的通知入口 列表加载、已读/未读、分页或增量加载
通知动作 列表项按钮 标为已读、全部已读、删除、跳转回目标页面
snooze/恢复 有对应入口时 snooze 后状态变化、恢复后计数变化

6.7 报表

来源:settings/reports/reports.routes.jsM07

页面组 真实入口 需验证的特性功能点
总览报表 左侧“报告”默认页 实时指标、筛选、时间范围
会话报表 报告 → 会话 指标卡、图表、筛选条件
客服概览/详情 报告 → 客服 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:人员、角色、组织

来源:agentsteamscustomRolesassignmentPolicyagentBots

页面组 真实入口 需验证的特性功能点
Agents 设置 → Agents 列表、新建/邀请、编辑、状态、重置密码
Teams 设置 → Teams 列表、新建、编辑、成员管理
Custom Roles 设置 → Custom Roles 角色列表、权限矩阵、创建/编辑、绑定用户
Assignment Policy 设置 → Assignment Policy 规则列表、创建、编辑、Inbox 绑定
Agent Bots 设置 → Agent Bots 列表、创建、编辑、绑定 inbox、token/配置可见性

6.10 SettingsInbox 与渠道

来源: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:标签、属性、模板、自动化

来源:labelsattributescannedmacrosautomationconversationWorkflowsla

页面组 真实入口 需验证的特性功能点
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 设置

来源:integrationsauditlogsbillingsettings/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.jsM07

页面组 真实入口 需验证的特性功能点
Live Chat Campaigns 左侧/菜单进入 Campaigns ongoing 列表、创建、编辑、启停
SMS Campaigns Campaigns 子页 one-off 列表、创建、schedule、受众
WhatsApp Campaigns Campaigns 子页 feature flag、列表、创建、错误态/空态

6.14 Help Center

来源:helpcenter.routes.jsM09

页面组 真实入口 需验证的特性功能点
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.jssettings/copilotM10

页面组 真实入口 需验证的特性功能点
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/sendPOST /api/replyPOST /api/closePOST /api/typing 适合造 open/pending/resolved/snoozed 前的消息样本
agent 在线/离线观测样本 channels/fake POST /api/agent/onlinePOST /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/messagesGET /api/statusPOST /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 当前只包含 frontendchannels/fake
  • backend/internal/llm/openai_provider.go 会向 baseURL + /chat/completionsbaseURL + /embeddings 发请求
  • provider_manager.go 已支持 openai_compatible
  • backend/internal/llm/openai_provider.go 已实现 ChatCompletionStream

这意味着:

  • 不需要先改 GoChat 的 provider 抽象
  • 只需要补一个本地 OpenAI-compatible 假服务
  • fake:ai 监听 9110GoChat 里的 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 覆盖流式生成路径

建议补一个最小场景切换请求体,便于后续浏览器测试直接复用:

{
  "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 最低接受:

{
  "model": "fake-gpt-4o-mini",
  "messages": [
    { "role": "system", "content": "You are a QA fake." },
    { "role": "user", "content": "Say hello" }
  ],
  "temperature": 0,
  "stream": false
}

非流式成功响应建议至少返回:

{
  "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 片段序列:

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 最低接受:

{
  "model": "fake-text-embedding-3-small",
  "input": "hello from fake embedding"
}

成功响应建议至少返回:

{
  "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 证据里确认当前页面到底打到了哪条配置。
  • createdidusage 不要求真实,但建议稳定、可预测,避免前端因为缺字段误判为 provider 异常。

10.4 fake:ai 与页面功能点映射

fake:ai 不是单纯给 Captain playground 用的,它至少要覆盖下面这些实际测试点:

页面/功能 依赖能力 没有 fake:ai 会发生什么
设置 → Copilot 配置 → 测试/保存 POST /v1/chat/completionsPOST /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 返回的观测数据必须脱敏 Authorizationapi_keybase_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 代码已经实现 ChatCompletionStreamfake: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-minifake-text-embedding-3-small
观测接口 /api/requests/api/reset/api/scenario

12.1 目录与脚本骨架建议

建议 fake:ai 第一版直接复用 channels/fake 的组织习惯,这样后续维护和理解成本最低:

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

根目录建议补这些脚本:

{
  "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 也建议同步补:

packages:
  - frontend
  - channels/fake
  - channels/fake-ai

这样做的好处很直接:

  • fake:startfake:ai 的心智模型一致,后续谁来接手都容易理解。
  • message fake 和 AI fake 都可以保留自己的 /health/api/reset/api/requests,不会互相污染。
  • 后续如果要把 dev:all 扩成包含 AI 的本地联调模式,也只是在根脚本上追加一个并发进程,不需要重构现有 fake channel。

建议默认启动命令:

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。