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-*/
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# 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. 前端 T05(5 子项)
|
||||
|
||||
#### 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 结果回传主理人。
|
||||
Reference in New Issue
Block a user