Files
wecom_it_smart_desk/docs/02-技术文档/AI回复三态开关-工程师续载清单.md
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

102 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 回复三态开关(REQ-坐席-010)— 工程师续载清单
> 创建于 2026-08-04 18:5x
> 用途:寇豆码在 429 重启后无需重读架构文档,直接据此清单补完剩余 3 件。
## 权威需求/设计(先读)
- PRD`docs/01-产品文档/04-坐席工作台/PRD-REQ-坐席-010-AI回复三态开关.md`
- 技术方案(含 5 任务、行号、Mermaid):`docs/02-技术文档/技术方案-REQ-坐席-010-AI回复三态开关.md`
- Mermaid 图:`docs/02-技术文档/architecture/REQ-坐席-010-{class-diagram,sequence-diagram}.mermaid`
## 已落盘(**不要重写**
### T01 数据层
-`src/backend/app/constants/ai_reply_mode.py`62 行)
-`src/backend/app/models/conversation.py` line 231 新增 `ai_reply_mode: Mapped[str]`
-`src/backend/app/schemas/conversation.py` line 359 ConversationResponse 加 `ai_reply_mode`
### T02 门控内核
-`src/backend/app/services/ai_reply_gate.py`163 行,6 函数:resolve_mode / conversation_mode / _normalize_status / can_ai_auto_reply_path_a / can_ai_auto_reply_path_b / agent_mirror_enabled / agent_dedicated_message
-`src/backend/tests/test_ai_reply_gate.py`(51 项参数化断言全过 2026-08-04 18:59
### T03 路径 A
-`src/backend/app/services/message_router.py` line 187 接入 `can_ai_auto_reply_path_a`
- ✓ L399 `_push_agent_dedicated_message` + L567 调用(b 态专属推送)
- ✓ imports constants/ai_reply_gate
### T02.5 设置 API
-`src/backend/app/api/conversations.py` line 400 PUT `/api/conversations/{conversation_id}/ai-reply-mode`
- ✓ 含广播 `ai_reply_mode_changed` WS 事件
-`src/backend/app/services/session_service.py` 已加 `set_ai_reply_mode`
### T04 路径 B**含接单后停 AI 缺口修复**)
-`src/backend/app/api/h5.py` line 946 接 `can_ai_auto_reply_path_b`(门控在 create_task 之前 ✅)
-`src/backend/app/api/ws.py` line 478 同上
-`src/backend/app/tasks/h5_ai_task.py` 4 处坐席广播点(L540/817/970/1684)已接 `agent_mirror_enabled`
- ✓ 2 处 `_push_agent_dedicated_message` 调用(L567/855
## 仍需补完(3 件)
### 1. Alembic 058 迁移(最简单,可立刻做)
- 文件:`src/backend/alembic/versions/058_add_ai_reply_mode.py`(仿 057 幂等写法:`sa.inspect(bind)` 守卫)
- `down_revision = '057_troubleshooting_templates'`
- 字段:`ai_reply_mode = sa.Column("ai_reply_mode", sa.String(20), nullable=False, server_default="employee_only")`
- 存量自动套用 server_default,无需数据回填
### 2. 前端 T055 子项)
#### 2a. `src/frontend-agent/src/components/chat/ai-assist/AiReplyModeSwitch.vue`
- 🤖 图标按钮(复用 `.tb-btn` 样式)+ `el-popover``el-radio-group` 三态单选
- 三个值:`employee_only` / `employee_and_agent` / `off`,显示中文文案
- 选中即调 `setAiReplyMode` API
- 当前态高亮(a 正常色 / b 高亮 / off 置灰)
#### 2b. `src/frontend-agent/src/components/chat/ReplyBox.vue`
-`.toolbar-left` 之后、`.tb-sep` 之后、`<AiAssistToolbar />` 之前插入 `<AiReplyModeSwitch />`
- 与 4 个主动 AI 按钮(💡🎚️🖌️🔄)以 `.tb-sep` 分隔,视觉独立
#### 2c. `src/frontend-agent/src/api/`(或现有 api 模块)
- `setAiReplyMode(conversationId, mode)` → PUT `/api/conversations/{conversation_id}/ai-reply-mode`
#### 2d. conversation store(找已有 conversation store,按 conversationId 存当前 mode
- action 存 + getter 取;切会话读各自值
#### 2e. WS 监听 `ai_reply_mode_changed`**不复用** `conversation_updated`,新增独立 handler
- payload: `{conversation_id, ai_reply_mode}`
- 多端同步:收到事件 → 更新 store
### 3. 修正技术方案文档(按 B 口径)
**用户最终澄清**2026-08-04 15:47):
> a 态(employee_only= AI 只对员工消息/选择作进一步回复;坐席端**仍按现状能看到 AI 回复员工的消息**。
> 即:a 维持现状镜像;b 在 a 基础上**额外**推专属;off 全关。
修正 `docs/02-技术文档/技术方案-REQ-坐席-010-AI回复三态开关.md`
- "推坐席"小节:明确 `agent_mirror_enabled = (mode != "off")`a/b 都镜像)
- "专属坐席消息"小节:`agent_dedicated_message = (mode == "employee_and_agent")`(仅 b 推)
- 说明当前实现(h5_ai_task.py + message_router.py 的 _push_agent_dedicated_message)已与本修正口径一致
## 完成后自测
1. 跑后端:`pytest tests/test_ai_reply_gate.py` → 期望 51/51
2. 跑前端:`pnpm vue-tsc --noEmit`(仅 AiReplyModeSwitch.vue 范围无新增错)
3. **全局一致性审查 IS_PASS: YES/NO** 重点核对:
- 字段 `ai_reply_mode`(不要写成 aiReplyMode / reply_scope
- WS 事件 `ai_reply_mode_changed`(不要复用 conversation_updated
- 端点路径 `/api/conversations/{conversation_id}/ai-reply-mode`
- 4 个广播点全部已接 `agent_mirror_enabled`grep 确认)
- 不动的 4 个 `broadcast_to_employees` 未被误改
## 提交
```
git add ... && git commit -m "feat(ai-reply-mode): REQ-坐席-010 三态开关完工
- T01 数据层 + alembic 058
- T02 门控内核 + 单测
- T03 路径 A + 坐席专属推送
- T04 路径 B + h5_ai_task 4 广播点收紧 + 接单后停 AI 缺口修复
- T05 前端 AiReplyModeSwitch + 集成 + WS 监听
- 修正技术方案文档'推坐席'小节按 B 口径"
```
把 commit hash + 改动文件清单 + IS_PASS 结果回传主理人。