From 4c65307e0c50e143e7fb02d059c794a28b7c68d9 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 14 Jun 2026 21:43:35 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=8E=A8=20P1-1~4=20=E7=BB=99=20workbu?= =?UTF-8?q?ddy=20=E4=BF=AE=E6=B6=88=E6=81=AF=E4=BC=98=E5=8C=96=E9=81=97?= =?UTF-8?q?=E7=95=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .workbuddy/memory/2026-06-14-任务-修P1消息.md | 150 ++++++++++++++++++ docs/风险跟踪表.md | 42 ++++- 2 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 .workbuddy/memory/2026-06-14-任务-修P1消息.md diff --git a/.workbuddy/memory/2026-06-14-任务-修P1消息.md b/.workbuddy/memory/2026-06-14-任务-修P1消息.md new file mode 100644 index 0000000..125f2d6 --- /dev/null +++ b/.workbuddy/memory/2026-06-14-任务-修P1消息.md @@ -0,0 +1,150 @@ +# workbuddy 任务 — 修消息优化推送遗留 P1-1~4 + +**触发日期**: 2026-06-14 +**来源**: 之前评审报告 `docs/评审报告/workbuddy-2026-06-14-消息优化.md` 9.3 节遗留 4 P1 +**Gitea 仓(公网 Funnel)**: `https://ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk` +**Gitea 仓(内网 LAN)**: `http://100.85.152.112:8418/simon/wecom_it_smart_desk` +**当前 main HEAD**: `3c1d563` +**workbuddy token**: 见 `.workbuddy/config.json` 的 `gitea.token` 字段 + +--- + +## ▶▶▶ 任务清单(按推荐度,4 项)起 + +### P1-1. upload 路径在容器本地(改 volume mount) + +**问题**: 消息图片/文件上传路径(在容器内)会在容器重建时丢失。当前 docker-compose.yml 应该是 backend 容器内路径,**没挂载到 host** 或 NAS。 + +**修复**: +1. 编辑 `docker-compose.yml` 的 backend 服务: + ```yaml + backend: + volumes: + # 新增 + - backend-uploads:/app/uploads + volumes: + backend-uploads: + driver: local + driver_opts: + type: none + o: bind + device: /volume1/docker/wecom-it-desk/uploads + ``` +2. `backend/app/api/messages.py` `upload_image` / `upload_message_file` 端点保存路径用 `UPLOAD_DIR` 配置项(从 `app.config` 读),不用硬编码 +3. 加 `UPLOAD_DIR=/app/uploads` 到 `.env.example` +4. `nginx.conf` `/uploads/` 路径反代到 backend,或加 `location /uploads/ { root /volume1/...; }` 静态服务 +5. `scripts/deploy.sh` 创建 `/volume1/docker/wecom-it-desk/uploads/` 目录(部署时) + +**验收**: +- 容器重建后上传文件**不丢** +- `df -h` 看 host 上 `/volume1/.../uploads` 体积能涨 + +### P1-2. 消息状态字段走 Alembic 迁移 + +**问题**: `backend/app/models/message.py` 之前加了 `status` 字段(已发/已送达/已读/撤回/删除等),但 **alembic 迁移未生成**。 + +**修复**: +```bash +cd backend +alembic revision --autogenerate -m "add message status and recallable_until" +# 检查生成的迁移脚本 +# 字段: +# - status: String(20), default="sent", nullable=False +# - recallable_until: DateTime, nullable=True +alembic upgrade head +``` + +**手动 SQL 不行**(评审报告已点出,部署步骤 6 引号未转义是历史错误) + +**验收**: +- `alembic upgrade head` 不报错 +- 生产数据库 `messages` 表有 `status` + `recallable_until` 字段 + +### P1-3. backend healthcheck 改用 Python 一行 + +**问题**: `docker-compose.yml` backend 用了 `curl http://localhost:8000/` 当 healthcheck,但**精简 backend 镜像没装 curl**(参考 [[backend-healthcheck-curl-pitfall]]),导致 `unhealthy` 但业务正常。 + +**修复**: 编辑 `docker-compose.yml`: +```yaml +backend: + healthcheck: + test: ["CMD", "python", "-c", "import socket; s=socket.socket(); s.connect(('localhost', 8000))"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s +``` + +或更稳(用 HTTP 检测): +```yaml +test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/v1/system/health').read()"] +# 需要 backend 有 /api/v1/system/health 端点(可能需要新增) +``` + +**验收**: +- `docker ps` 显示 backend `healthy`(不再 `unhealthy`) +- 业务正常 + +### P1-4. ws_manager 实现消息状态广播 + +**问题**: 文档承诺了"消息状态广播"(撤回/已读/删除等事件推送),但 `ws_manager.py` 实际**没实现**。 + +**修复**: 在 `backend/app/services/ws_manager.py` 加方法: +```python +async def broadcast_message_status( + self, + conv_id: str, + msg_id: str, + status: str, + extra: dict = None, +) -> int: + """向会话所有参与方广播消息状态变更。 + + Args: + conv_id: 会话ID + msg_id: 消息ID + status: 新状态(sent / delivered / read / recalled / deleted) + extra: 额外数据(可选,如 recall_by / recall_at) + + Returns: + 推送到客户端数量 + """ + # 1. 查会话所有参与方(agent_id + employee_id) + # 2. 找每个参与方的 WebSocket 连接 + # 3. 发 JSON 消息 {"type": "message_status", "msg_id": ..., "status": ..., "extra": ...} + # 4. 返回推送数 + ... +``` + +调用方:`messages.py` `recall_message` / `delete_message` / `mark_read` 在改 DB 状态后,**调 `await ws_manager.broadcast_message_status(...)`**。 + +**验收**: +- 端到端测试:坐席 A 撤回消息 → 坐席 B + H5 员工实时收到 `message_status` 推送 +- 前端(`useWebSocket.ts`)处理 `message_status` 类型消息(更新 UI) + +## ▼▼▼ 任务清单止 + +--- + +## 🔄 工作流(等 workbuddy 修完 4 项后) + +1. workbuddy 修完 → 提交 commit 到 Gitea +2. 通知 Claude 评审 +3. Claude 评审(对照 4 项 + 跑相关测试) +4. 合并到 main +5. 关 #23 + +## 🔴 评审历史(防 workbuddy 再犯) + +参考评审报告 `docs/评审报告/workbuddy-2026-06-14-消息优化.md` 9.5 节: + +- **P0 比例 46% (6/13) 过高** —— 后续推送需**强制走评审流程** +- pre-commit 检查建议(Claude 可生成脚本):新增端点无 `Depends(...)` 鉴权 → 拒绝推送 +- 4 P1 一旦 P0 修完就推,**不要在评审未消化前叠加新功能** + +## 关联 + +- 评审主报告: `docs/评审报告/workbuddy-2026-06-14-消息优化.md` +- 风险跟踪表: 第九节(P1-1~4 状态追踪) + 即将加第十一节 +- Claude 记忆: `review-messages-2026-06-14.md` +- Gitea 仓: `https://ds923plus.tail58d872.ts.net/simon/wecom_it_smart_desk` (公网 Funnel) diff --git a/docs/风险跟踪表.md b/docs/风险跟踪表.md index bc90249..42aedbd 100644 --- a/docs/风险跟踪表.md +++ b/docs/风险跟踪表.md @@ -704,10 +704,10 @@ location /api/ { | 编号 | 状态 | 编号 | 状态 | |------|------|------|------| -| CR-5 (P0-1) | ✅ | H-12 (P1-1) | ⚠️ | -| CR-6 (P0-2) | ✅ | H-13 (P1-2) | ⚠️ | -| CR-7 (P0-3) | ✅ | H-14 (P1-3) | ⚠️ | -| CR-8 (P0-4) | ✅ | H-15 (P1-4) | ⚠️ | +| CR-5 (P0-1) | ✅ | H-12 (P1-1) | 🔄 | +| CR-6 (P0-2) | ✅ | H-13 (P1-2) | 🔄 | +| CR-7 (P0-3) | ✅ | H-14 (P1-3) | 🔄 | +| CR-8 (P0-4) | ✅ | H-15 (P1-4) | 🔄 | | CR-9 (P0-5) | ✅ | M-13 (P2-2) | ⚠️ | | CR-10 (P0-6) | ✅ | M-14 (P2-3) | ⚠️ | | | | M-15 (P2-1) | ✅(捎带)| @@ -768,3 +768,37 @@ location /api/ { | P0-#3 Mock login | 🟢 完成 | | P0-#4 WS token | 🟡 遗留 1+2 | | P0-#5 坐席密码 | 🟡 遗留 3+4+5 | + +--- + +## 第十一节: 2026-06-14 P1 消息优化推送(2 轮) + +**来源**: 6-14 workbuddy 消息优化推送遗留 4 P1 +**主报告**: `docs/评审报告/workbuddy-2026-06-14-消息优化.md` 9.3 节 +**workbuddy 任务清单**: `.workbuddy/memory/2026-06-14-任务-修P1消息.md` +**任务编号**: #23 + +### 11.1 4 P1 项 + +| 编号 | 严重度 | 内容 | 状态 | +|---|---|---|---| +| H-12 (P1-1) | 🟡 | upload 路径在容器本地,容器重建即丢失 → 改 volume mount | 🔄 | +| H-13 (P1-2) | 🟡 | SQL 迁移未走 Alembic → 生成 `add message status` 迁移 | 🔄 | +| H-14 (P1-3) | 🟡 | docker-compose backend healthcheck 用 curl → 改 Python 一行 | 🔄 | +| H-15 (P1-4) | 🟡 | ws_manager 没实现"消息状态广播" → 实现 `broadcast_message_status()` | 🔄 | + +### 11.2 评审教训(防 workbuddy 再犯) + +1. **依赖 docker volume 部署前要先建 host 目录** —— `scripts/deploy.sh` 需加创建逻辑 +2. **alembic autogenerate 需人工 review** —— 自动生成的不一定对(可能漏 index / 加了不想要的) +3. **backend 精简镜像没 curl 是已知坑** —— 用 Python 一行替代 +4. **文档承诺的 WS 广播必须实做** —— 否则前端靠轮询兜底,实时性不够 + +### 11.3 第十一节状态速查 + +| 编号 | 状态 | +|---|---| +| H-12 (P1-1) upload 路径 | 🔄 评审闭环中 | +| H-13 (P1-2) Alembic 迁移 | 🔄 评审闭环中 | +| H-14 (P1-3) healthcheck | 🔄 评审闭环中 | +| H-15 (P1-4) ws 状态广播 | 🔄 评审闭环中 |