Files
wecom_it_smart_desk/docs/02-技术文档/技术架构/技术方案-REQ-坐席-007-分诊排查系统-v1.0.md
T

596 lines
26 KiB
Markdown
Raw Normal View History

# 技术方案 - 分诊排查系统(一体两面:Troubleshooting + Triage
> **REQ编号**: REQ-坐席-007
> **版本**: v1.1
> **日期**: 2026-07-28
> **状态**: [待评审]
> **作者**: 宋献
> **关联文档**:
> - PRD: `../../01-产品文档/04-坐席工作台/PRD-REQ-坐席-007-分诊排查系统-v1.0.md`v1.3
> - 原型: `../../01-产品文档/04-坐席工作台/原型-REQ-坐席-007-分诊排查系统-v1.0.html`v1.3
> - 功能测试: `../../03-测试文档/03-功能测试用例/TC-坐席-007-分诊排查系统.md`v1.0,54 条用例,已补齐)
---
## 一、方案概述
### 1.1 建设目标
将现有“排查流程图管理”从进程内 Mock 数据和客户端本地状态,改造为具备**模板持久化、草稿发布、版本隔离、会话级执行、跨端同步、权限审计和可观测性**的生产闭环。
### 1.2 当前实现基线
| 层级 | 已有实现 | 主要问题 |
|---|---|---|
| 管理端 | `Flowcharts.vue`、JSON 编辑/预览、CRUD 客户端 | 列表契约错位;无发布、版本、审计;导入只做基础字段校验 |
| 后端 API | 5 个 REST 接口和 8 套 Mock 模板 | CRUD 只修改 `MOCK_TEMPLATES`,重启丢失;无管理员 RBAC |
| 数据模型 | `troubleshooting_templates` SQLAlchemy 模型 | API 未使用;字段不足以支持草稿、版本、负责人和员工可见范围 |
| 坐席端 | `TroubleshootBar.vue` 可选择模板和手动推进 | 状态在组件内,不绑定会话,不持久化,不同步 H5 |
| 员工 H5 | 自助列表、详情、流程和进度组件 | 页面未正式接入路由;执行事件和转人工上下文未闭环 |
| 数据契约 | `flowchart``path_steps`、种子数据 `root_node` | 多套结构并存,导入导出不兼容 |
| 测试 | 未发现独立功能用例和 E2E 验收 | 无上线质量闸门 |
### 1.3 技术原则
1. **服务端唯一状态源**:模板版本和执行进度均以数据库为准,客户端仅展示与发起命令。
2. **版本不可变**:发布后不允许原地修改;执行实例固定绑定版本快照。
3. **命令与事件分离**:客户端发送“完成节点/选择分支”等命令,后端校验后产生状态事件。
4. **契约统一**:管理端、坐席端、H5、种子文件和导入导出使用同一 JSON Schema。
5. **增量兼容**:保留现有 5 个基础路径的兼容层,但生产接口逐步切到 `/admin``/executions` 分域。
6. **最小权限与全审计**:维护、发布、执行、查看日志权限分离。
---
## 二、总体架构
```mermaid
flowchart LR
A[管理后台] -->|草稿维护/发布| B[Template API]
C[坐席工作台] -->|启动/推进/结束| D[Execution API]
E[员工 H5] -->|自助执行/转人工| D
B --> F[(PostgreSQL)]
D --> F
D --> G[WebSocket Manager\n单 worker]
G --> C
G --> E
H[AI/Dify 路由] -. 推荐模板 .-> D
I[审计与指标] <-->|事件/查询| F
```
### 2.1 模块边界
| 模块 | 职责 |
|---|---|
| Template Service | 模板元数据、草稿、版本、结构校验、发布、停用、回滚 |
| Execution Service | 创建实例、合法节点推进、暂停恢复、结束、转人工摘要 |
| Sync Service | 将执行事件推送给坐席连接池和员工连接池,支持断线恢复 |
| Audit Service | 记录模板管理操作和关键执行操作 |
| Metrics Service | 聚合采用率、完成率、解决率、退出节点和异常率 |
---
## 三、统一模板契约
### 3.1 JSON Schema v1
```json
{
"schema_version": "1.0",
"purpose": "troubleshooting",
"code": "vpn-remote-connection",
"name": "VPN 远程办公连接失败",
"category": "vpn",
"description": "远程办公 VPN 故障标准排查",
"estimated_minutes": 8,
"difficulty": 2,
"tags": ["VPN", "远程办公"],
"visibility": {
"agent": true,
"employee": true,
"departments": []
},
"root_node_id": "start-1",
"nodes": [
{
"id": "start-1",
"type": "step",
"title": "确认故障现象",
"employee_text": "请确认报错内容和发生时间",
"agent_text": "记录报错码、网络环境和客户端版本",
"next_node_id": "decision-1"
},
{
"id": "decision-1",
"type": "decision",
"title": "是否能打开互联网网站",
"options": [
{"key": "yes", "label": "可以", "next_node_id": "check-version"},
{"key": "no", "label": "不可以", "next_node_id": "end-network"}
]
},
{
"id": "end-network",
"type": "end",
"title": "转入网络排查",
"result": "redirect",
"linked_template_code": "network-connectivity"
}
]
}
```
> `purpose` 字段为 v1.1 新增,必填,值域 `troubleshooting` / `triage`。`code` 为业务稳定编码,便于跨版本引用、跨模板跳转和路由兜底。
#### 3.1.1 问诊模板(Triage)示例
```json
{
"schema_version": "1.0",
"purpose": "triage",
"code": "triage_intake",
"name": "问诊对话",
"category": "intake",
"description": "路由无匹配时的兜底问诊模板",
"estimated_minutes": 2,
"difficulty": 1,
"tags": ["triage", "intake"],
"visibility": {"agent": true, "employee": true, "departments": []},
"root_node_id": "triage-1",
"nodes": [
{
"id": "triage-1",
"type": "step",
"title": "请选择最贴近的故障现象",
"employee_text": "请选择最贴近的故障现象",
"agent_text": "等待员工自选",
"next_node_id": "triage-end"
},
{"id": "triage-end", "type": "end", "title": "回到标准模板选择", "result": "redirect"}
]
}
```
> Triage 模板走相同 Schema、相同版本、相同执行 API;由 §3.3 的 per-purpose 校验规则保证其节点数与结构可控。
### 3.2 节点类型
| 类型 | 必填字段 | 说明 |
|---|---|---|
| `step` | `id,type,title,next_node_id` | 操作或信息确认步骤 |
| `decision` | `id,type,title,options[]` | 至少 2 个选项,每个选项指向下一节点 |
| `end` | `id,type,title,result` | `resolved/unresolved/redirect/cancelled` |
### 3.3 校验规则
校验入口按 `purpose` 加载对应规则集。
**通用规则**(所有 purpose):
1. `schema_version` 必须为支持版本。
2. `purpose` 必填且值域为 `troubleshooting` / `triage`
3. `root_node_id` 必须存在,节点 `id` 全局唯一。
4. 除结束节点外均必须存在合法后继。
5. 决策节点至少 2 个选项,选项 key 不重复。
6. 从根节点出发所有生产节点均可达,至少存在一个结束节点。
7. 首版禁止循环。
8. 员工可见模板的路径必须具备 `employee_text`,且不得包含内部凭据或管理员命令。
9. 导入旧格式时执行显式迁移,不能静默丢字段;迁移报告随草稿保存。
**`purpose=troubleshooting` 专属规则**
- 节点数上限 100;最大深度 20。
- 结束节点 `result` 允许 `resolved` / `unresolved` / `redirect` / `cancelled`
**`purpose=triage` 专属规则**
- 节点数上限 10;最大深度 4。
- 必须存在结束节点,且结束节点 `result=redirect`(回到标准模板选择)。
- `tags` 必须包含 `triage``intake`
- 不允许 `linked_template_code` 指向其他排查,避免问诊模板变排查。
**`purpose` 字段保护规则**
- 模板创建成功后 `purpose` 字段不可修改。
- 如需另一种用途,必须显式调用 “基于此模板复制为另一种用途” 接口,新模板继承旧模板节点结构但重置 `purpose` 并触发完整校验。
- 导入 JSON 时若未声明 `purpose`,默认 `troubleshooting` 并写入导入报告。
### 3.4 旧数据映射
| 旧字段 | 新字段/处理 |
|---|---|
| `flowchart` 递归树 | 展开为 `nodes[]` + `root_node_id` |
| `root_node` | 作为旧格式根节点输入并转换 |
| `path_steps` | 仅作为只读展示缓存,不再作为事实源;由已选择路径动态计算 |
| `estimated_time` | `estimated_minutes` |
| `is_active` | 模板主记录 `status=active/disabled` |
---
## 四、数据库设计
### 4.1 `troubleshooting_templates` 模板主表
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | UUID PK | 模板 ID |
| `code` | varchar(64) unique | 稳定业务编码 |
| `purpose` | varchar(16) not null | 模板用途:`troubleshooting`(默认)/ `triage`;创建后不可修改,需通过“克隆为另一用途”产生新模板 |
| `name` | varchar(256) | 名称 |
| `category` | varchar(32) | 分类 |
| `description` | text | 描述 |
| `status` | varchar(16) | `active/disabled/archived` |
| `current_published_version_id` | UUID nullable | 当前发布版本 |
| `owner_id` | varchar | 内容负责人 |
| `review_due_at` | timestamptz nullable | 复审日期 |
| `created_by/updated_by` | varchar | 操作者 |
| `created_at/updated_at` | timestamptz | 时间戳 |
### 4.2 `troubleshooting_template_versions` 版本表
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | UUID PK | 版本 ID |
| `template_id` | UUID FK | 模板主记录 |
| `version_no` | integer | 单调递增版本号 |
| `version_label` | varchar(32) | v1.0、v1.1 等展示值 |
| `state` | varchar(16) | `draft/published/superseded` |
| `schema_version` | varchar(16) | JSON Schema 版本 |
| `definition` | JSONB | 完整模板定义 |
| `checksum` | varchar(64) | 内容哈希,检测重复发布 |
| `change_summary` | text | 版本说明 |
| `lock_version` | integer | 乐观锁 |
| `created_by/published_by` | varchar nullable | 操作者 |
| `created_at/published_at` | timestamptz nullable | 时间戳 |
约束:`unique(template_id, version_no)``published` 记录不可更新或删除。
### 4.3 `troubleshooting_executions` 执行实例表
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | UUID PK | 执行实例 |
| `conversation_id` | UUID nullable | 关联会话;员工纯自助阶段可为空 |
| `employee_id` | varchar | 员工 |
| `agent_id` | varchar nullable | 坐席 |
| `template_id/version_id` | UUID FK | 固定模板版本 |
| `source` | varchar(16) | `agent` / `employee` / `ai_recommend` / `triage_fallback``triage_fallback` 为路由无匹配时的兜底问诊实例,不计入排查完成率与解决率指标 |
| `status` | varchar(16) | `running/paused/completed/transferred/cancelled` |
| `current_node_id` | varchar(64) | 当前节点 |
| `path` | JSONB | 已执行节点与分支选择摘要 |
| `result` | varchar(24) nullable | 结果 |
| `started_at/finished_at` | timestamptz | 时间 |
| `last_event_seq` | bigint | 事件顺序号 |
### 4.4 `troubleshooting_execution_events` 事件表
保存 `started/node_completed/decision_selected/paused/resumed/transferred/completed` 等事件;以 `(execution_id, client_event_id)` 唯一约束保证幂等。
### 4.5 `troubleshooting_audit_logs` 审计表
记录模板 ID、版本 ID、动作、操作者、来源 IP、变更摘要、前后校验和、时间和结果。定义中可能包含敏感文本,审计差异需脱敏或仅存校验和与摘要。
---
## 五、API 设计
### 5.1 响应规范
继续使用项目统一结构:
```json
{"code": 0, "message": "success", "data": {}}
```
列表统一返回:
```json
{"items": [], "total": 0, "page": 1, "page_size": 20}
```
管理端客户端必须读取 `data.items`,不得将列表对象当数组调用 `map()`
### 5.2 模板管理 API
| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| GET | `/admin/troubleshooting-templates` | admin/auditor | 分页查询模板,支持 `purpose``category``status``keyword` 过滤 |
| POST | `/admin/troubleshooting-templates` | admin | 创建模板与初始草稿 |
| GET | `/admin/troubleshooting-templates/{id}` | admin/auditor | 模板详情与当前版本 |
| PATCH | `/admin/troubleshooting-templates/{id}` | admin | 更新主信息,使用 `If-Match``lock_version` |
| POST | `/admin/troubleshooting-templates/{id}/drafts` | admin | 从指定版本创建草稿 |
| POST | `/admin/troubleshooting-templates/{id}/clone-as-purpose` | admin | 复制为另一 `purpose` 的新草稿(继承节点结构、重置 `purpose` 并触发完整校验) |
| PUT | `/admin/troubleshooting-template-versions/{version_id}` | admin | 保存草稿定义 |
| POST | `/admin/troubleshooting-template-versions/{version_id}/validate` | admin | 完整校验 |
| POST | `/admin/troubleshooting-template-versions/{version_id}/publish` | admin | 发布新版本 |
| POST | `/admin/troubleshooting-templates/{id}/disable` | admin | 停用模板 |
| GET | `/admin/troubleshooting-templates/{id}/versions` | admin/auditor | 版本历史 |
| POST | `/admin/troubleshooting-template-versions/{version_id}/rollback` | admin | 复制为新草稿 |
| POST | `/admin/troubleshooting-templates/import` | admin | 导入并返回迁移/校验报告 |
| GET | `/admin/troubleshooting-templates/export` | admin | 导出选定版本 |
| GET | `/admin/troubleshooting-audit-logs` | admin/auditor | 查询审计日志 |
### 5.3 执行 API
| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| GET | `/troubleshooting-templates` | employee/agent | 只返回已发布、启用且有权可见的模板摘要 |
| GET | `/troubleshooting-templates/{id}` | employee/agent | 返回当前已发布版本的角色裁剪视图 |
| POST | `/troubleshooting-executions` | employee/agent | 启动执行实例 |
| GET | `/troubleshooting-executions/{id}` | participant/admin | 获取当前状态和路径 |
| POST | `/troubleshooting-executions/{id}/commands` | participant | 提交完成步骤、选择分支等命令 |
| POST | `/troubleshooting-executions/{id}/pause` | agent | 暂停 |
| POST | `/troubleshooting-executions/{id}/resume` | participant | 恢复 |
| POST | `/troubleshooting-executions/{id}/transfer` | employee/agent | 转人工并产生摘要 |
| POST | `/troubleshooting-executions/{id}/complete` | participant | 结束并记录结果 |
命令示例:
```json
{
"client_event_id": "f4d8...",
"expected_seq": 7,
"command": "select_option",
"node_id": "decision-1",
"option_key": "yes"
}
```
服务端校验:参与者身份、实例状态、当前节点、选项合法性、`expected_seq`、幂等键。冲突返回 `409` 并携带最新状态。
---
## 六、发布与执行状态机
### 6.1 模板版本状态
```mermaid
stateDiagram-v2
[*] --> Draft
Draft --> Draft: 保存/校验
Draft --> Published: 校验通过并发布
Published --> Superseded: 新版本发布
Published --> Draft: 复制或回滚为新草稿
Superseded --> Draft: 回滚为新草稿
```
### 6.2 执行实例状态
```mermaid
stateDiagram-v2
[*] --> Running
Running --> Paused: 暂停
Paused --> Running: 恢复
Running --> Transferred: 转人工
Transferred --> Running: 坐席继续
Running --> Completed: 已解决/未解决
Running --> Cancelled: 主动取消
```
状态转换必须由后端服务执行,客户端不得直接写状态。
**`source` 枚举与 triage 实例语义**
- 执行实例 `source` 取值:`agent`(坐席手动启动)、`employee`(员工自助启动)、`ai_recommend`(路由自动启动)、`triage_fallback`(路由无匹配兜底问诊)。
- `triage_fallback` 实例复用完全相同的状态机;其结束(`end` 节点 `result=redirect`**不记录** `resolved` / `unresolved`,由服务端在结束命令中复位会话的路由状态,自动回到“路由推荐 + 手动覆盖”双轨,允许路由层后续再次推荐标准排查。
- 同一 `conversation_id` 同一时刻**仅允许一个 `running` 实例**:创建实例时后端校验该会话不存在未结束实例,否则返回 `409 Conflict` 并携带当前实例信息;手动切换模板须先 `complete` / `cancel` 旧实例再创建新实例(对应 PRD §5.4.5)。
---
## 七、WebSocket 同步方案
### 7.1 消息类型
统一事件消息:
```json
{
"message_type": "troubleshooting_execution_event",
"message_id": "evt-uuid",
"conversation_id": "conv-uuid",
"execution_id": "exec-uuid",
"event_seq": 8,
"event_type": "node_changed",
"data": {
"current_node_id": "check-version",
"progress": {"completed": 5, "visited": 6}
},
"created_at": "2026-07-28T12:00:00+08:00"
}
```
### 7.2 推送规则
1. 事件落库成功后再推送,避免客户端看到未持久化状态。
2. 同时推送坐席会话连接池和员工连接池;项目后端保持 `--workers 1`,符合现有 WebSocket 单例约束。
3. `message_id``event_seq` 用于前端去重与顺序判断。
4. 断线重连后先 `GET execution` 恢复快照,再消费新事件。
5. 客户端收到间断序号时主动拉取快照,不自行猜测中间状态。
### 7.3 转人工摘要
转人工事件至少包含模板名称、版本、启动时间、已访问节点、分支选择、员工备注、当前节点和建议下一步。内部节点说明仅对坐席展示。
---
## 八、权限与安全
### 8.1 后端强制权限
- 管理 API 强制管理员或指定模板管理员角色;不能只依赖前端路由 `requiresAuth`
- 执行 API 校验当前用户是员工本人、会话坐席或管理员。
- 审计员只读,不得发布或推进实例。
- IP 白名单中间件继续作为管理端附加控制,但不能代替 RBAC。
- **按 `purpose` 的显式隔离**`triage` 模板对员工**始终可见**,不受 `visibility.departments` / 角色过滤约束,且不得在可见范围写入敏感过滤条件(避免兜底模板被过滤);对坐席**仅只读**(可查看,不可创建/发布/编辑/停用)。`troubleshooting` 模板仍按权限矩阵与可见范围过滤。
### 8.2 内容安全
1. 发布前执行敏感字段扫描,禁止密码、Token、Secret、生产私钥和个人敏感信息进入模板。
2. 员工视图由后端按角色裁剪,不通过前端隐藏字段实现保密。
3. 模板导入限制文件大小、节点数和嵌套深度,防止资源消耗攻击。
4. JSON 作为数据渲染,禁止执行 HTML、JavaScript 和任意表达式。
5. 高风险操作节点只能链接已审批自动化能力,不能内嵌任意命令。
---
## 九、前端改造
### 9.1 管理端
- `Flowcharts.vue` 更名语义为“分诊排查管理”,保留兼容路由 `/flowcharts`
- 列表适配 `{items,total}`,增加状态、负责人、发布版本、筛选和分页;**按 `purpose` 分 TabTroubleshooting / Triage**,便于运营区分两类模板。
- 编辑器顶部增加 **“模板用途”选项**,新建时强制选择 `purpose`,创建后不可修改;切换用途只能通过“复制为另一种用途”产生新草稿。
- 编辑器由“整个模板 JSON”调整为“结构化编辑 + JSON 高级模式”,两者共用 schema 校验。
- 增加版本历史、发布确认、停用、回滚、并发冲突和审计入口。
- 预览同时显示坐席视图和员工视图,及时发现角色文案缺失或敏感信息暴露。
### 9.2 坐席端
- `TroubleshootBar.vue` 不再维护权威本地步骤状态,改为消费执行实例快照。
- 模板选择后调用启动 API;节点操作发送 command,成功后根据服务端状态更新。
- 支持暂停、恢复、转模板、结束和查看完整路径。
- 页面刷新或切换会话后按 `conversation_id` 恢复进行中的实例。
### 9.3 员工 H5
- 正式注册自助列表、详情和执行路由。
- 员工端只接收角色裁剪后的节点字段。
- “需要人工帮助”调用 transfer API,并跳转或创建服务会话。
- 聊天内嵌排查组件与独立自助页面复用同一 execution store,避免双套状态。
---
## 十、迁移与兼容
### 10.1 数据迁移步骤
1. 新增版本、执行、事件和审计表;扩展模板主表。
2. 将现有 `MOCK_TEMPLATES``data/seed-templates/*.json` 通过离线迁移器转换为 Schema v1 草稿。
3. 对每份迁移结果执行结构校验,生成“成功/警告/失败”报告,人工确认后发布。
4. 管理端先切换新管理 API;旧 GET 列表保留一个版本周期的适配层。
5. 坐席端切换执行实例 API,验证稳定后接入 H5。
6. 删除运行时对 `MOCK_TEMPLATES` 的读写,Mock 仅保留为测试 fixture。
### 10.2 回滚策略
- 数据库迁移具备 Alembic downgrade;涉及版本表的数据迁移必须先备份。
- 新执行 API 使用功能开关 `TROUBLESHOOTING_EXECUTION_ENABLED`,关闭后隐藏执行入口,不回写 Mock。
- 发布失败不改变 `current_published_version_id`;新版本切换使用单事务完成。
- 已创建执行实例永远引用版本快照,回滚当前发布版本不影响历史和进行中实例。
---
## 十一、可观测性
### 11.1 指标
- `troubleshooting_template_start_total{template_id,version,source}`
- `troubleshooting_execution_complete_total{result}`
- `troubleshooting_execution_duration_seconds`
- `troubleshooting_node_exit_total{node_id,reason}`
- `troubleshooting_command_conflict_total`
- `troubleshooting_ws_sync_latency_seconds`
- `troubleshooting_validation_failure_total{rule}`
- `troubleshooting_template_complete_total{result}`:排查完成实例计数(与 `troubleshooting_execution_complete_total` 同源,按 `result` 区分)。
- `troubleshooting_template_resolved_total`:标记为“已解决”的完成实例计数。
**指标隔离规则(对应 PRD §5.4.8、§6.3 #10**
- 指标服务层硬编码 `source=triage_fallback` 的实例**不计入** `troubleshooting_template_complete_total``troubleshooting_template_resolved_total`
- 问诊实例仅计入启动指标:`troubleshooting_template_start_total{...,source=triage_conversion}`,用于观测问诊→标准模板的转化率。
- 此隔离需在 Metrics Service 采集层强制,避免运营指标被兜底问诊流量污染。
### 11.2 日志与告警
| 场景 | 级别 | 告警建议 |
|---|---|---|
| 发布事务失败 | ERROR | 5 分钟 ≥3 次告警 |
| 执行状态推进异常 | ERROR | 错误率 >2% 告警 |
| WebSocket 同步 P95 >2 秒 | WARN | 连续 10 分钟告警 |
| 死路/非法后继 | ERROR | 任意生产实例立即告警 |
| 模板复审到期 | INFO/WARN | 到期前 14 天通知负责人 |
日志禁止输出模板内可能含敏感信息的完整 JSON,仅记录模板/版本/节点 ID、错误码和追踪 ID。
---
## 十二、测试策略
### 12.1 单元测试
- Schema 校验:根节点、重复 ID、不可达、缺失分支、循环、深度和节点上限。
- 状态机:所有合法/非法状态转换。
- 节点推进:步骤、判断、结束和跨模板跳转。
- 幂等:重复 `client_event_id` 不重复推进。
- 角色裁剪:员工响应不包含 `agent_text` 和内部字段。
### 12.2 集成测试
- 草稿创建、校验、发布、停用、回滚完整链路。
- 乐观锁冲突返回 409。
- 发布事务失败时当前版本不改变。
- 执行实例固定绑定版本,新版本发布不影响进行中实例。
- 坐席与员工 WebSocket 双端同步和断线恢复。
### 12.3 E2E 验证
1. 管理员登录 → 创建 VPN 模板 → 校验 → 发布。
2. 坐席登录 → 打开会话 → 启动模板 → 推进判断分支。
3. 员工 H5 登录 → 查看同步进度 → 选择分支或请求人工。
4. 坐席收到转人工摘要 → 继续执行 → 标记解决。
5. 查询数据库、审计日志和指标,确认路径、版本、结果一致。
遵循项目验证铁律:未完成真实端到端验证,不得宣布生产可用。
---
## 十三、实施顺序与完成标准
### 13.1 建议迭代
| 阶段 | 范围 | 完成标准 |
|---|---|---|
| 1 | 统一 Schema、DB、管理 API、发布版本、RBAC、审计 | 管理闭环和 API 测试通过 |
| 2 | 管理端改造、导入迁移、双端预览 | 原型验收和浏览器 E2E 通过 |
| 3 | 执行实例、坐席接入、事件日志 | 会话级暂停恢复和版本隔离通过 |
| 4 | H5 接入、双端同步、转人工 | 端到端三端闭环通过 |
| 5 | 指标、告警、首批模板治理 | 上线与回滚演练通过 |
### 13.2 Definition of Done
- [ ] PRD、原型、技术方案和测试用例完成评审并相互关联。
- [ ] 不再使用进程内 Mock 作为生产数据源。
- [ ] 统一 Schema 覆盖管理端、坐席端、H5、种子和导入导出。
- [ ] 发布版本不可变,执行实例固定绑定版本。
- [ ] 后端 RBAC、IP 附加控制和审计日志有效。
- [ ] 坐席与员工断线恢复、消息去重和顺序一致。
- [ ] 单元、集成、E2E、回归和安全测试通过。
- [ ] 部署、迁移、回滚、监控和告警方案完成验证。
---
## 十四、技术决策与待评审项
### 14.1 建议锁定
1. 产品和技术统一使用“排查”,管理菜单显示“分诊排查管理”。
2. 使用扁平 `nodes[]` 作为唯一存储结构,便于校验、差异比较和节点引用。
3. `path_steps` 不再独立维护,执行时由事件路径计算,避免双数据源不一致。
4. 发布版本不可变,回滚等价于复制历史版本为新草稿并重新发布。
5. WebSocket 仅承担实时通知,最终一致性依赖数据库快照和事件序号。
### 14.2 待评审
- 是否保留兼容的 `/troubleshooting-templates` 管理写接口,或一次性切换到 `/admin`
- 模板版本号由系统自动生成还是允许管理员输入展示标签。
- 跨模板跳转首版是否纳入 P0;如纳入,需要循环依赖校验。
- 执行事件采用直接数据库写入还是引入 outbox;首版建议同事务写事件并同步推送,规模增长后再引入 outbox。
---
## 十五、变更记录
| 日期 | 版本 | 变更内容 | 变更人 | 变更原因 |
|---|---|---|---|---|
| 2026-07-28 | v1.0 | 新建完整技术方案,覆盖统一契约、版本发布、执行状态、双端同步、权限审计、迁移和测试 | Duckula | 补齐 REQ-坐席-007 技术文档缺口 |
| 2026-07-28 | v1.1 | 落实“一体两面”模型:§4.1 模板主表新增 `purpose` 字段、§4.3 执行实例 `source``triage_fallback`;§5.2 列表支持 `purpose` 过滤并新增 `clone-as-purpose` 接口;§6.2 补 triage 实例语义与同会话单实例约束;§8.1 补按 purpose 的权限隔离;§9.1 管理端按 purpose 分 Tab + “模板用途”选项;§11.1 新增 `triage_conversion` 指标隔离规则;头部测试状态同步为已补齐 | Duckula | 对齐 PRD v1.3 的 `purpose` 统一管理与问诊模板闭环 |