151 lines
5.3 KiB
Markdown
151 lines
5.3 KiB
Markdown
|
|
# 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)
|