feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复
== 已部署上线 (9项) == - 代办事项真实数据源集成 (企微审批API 8bug修复链) - H5/坐席端 Logo样式统一+绿色背景 - 视频引导页修复 (localStorage key v2) - 坐席端 v9 Vue版本修复 (ElMessage._context) - 截图按钮 v10 修复 (getDisplayMedia user gesture) - 扫码样式恢复+H5扫码登录跳转修复 - H5截图快捷键提示 == 代码完成待部署 (3项) == - 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查) - 会议室预定-小鱼易联终端 (40文件, 40/40测试通过) - IT资产升级审批推送 (asset_service.py) == 需求文档 (2项) == - 坐席端AI辅助消息框-PRD (4项新功能确认) - 坐席端布局优化建议 v2.0 (7天计划) == 新增文档 == - 日报-2026-07-11.md - 知识迭代Bug修复报告-20260711.md - 会议室预定-部署指南.md - CHANGELOG.md 更新 == 测试 == - test_todo_integration.py: 40/40 - test_meetingroom.py: 40/40 - test_bugfix_ki_suggestions.py: 21/21
This commit is contained in:
@@ -0,0 +1,907 @@
|
||||
# 智能IT支持服务台 — 风险跟踪表
|
||||
|
||||
**最后更新**: 2026-06-14 18:30
|
||||
**维护人**: 宋献 + Claude 评审协作
|
||||
|
||||
> 📌 2026-06-14 评审新增 13 项(6 P0 + 4 P1 + 3 P2),详见第九节。
|
||||
> 统计表保持 6-13 数据,**第九节有独立小计**。
|
||||
|
||||
---
|
||||
|
||||
## 一、风险总览
|
||||
|
||||
| 级别 | 数量 | 已处理 | 待处理 | 处理率 |
|
||||
|------|------|--------|--------|--------|
|
||||
| 🔴 严重 (Critical) | 4 | 4 | 0 | **100%** |
|
||||
| 🟠 高 (High) | 6 | 5 | 1 | **83%** |
|
||||
| 🟡 中 (Medium) | 7 | 4 | 3 | **57%** |
|
||||
| 🔵 低 (Low) | 5 | 3 | 2 | **60%** |
|
||||
| **合计** | **22** | **16** | **6** | **73%** |
|
||||
|
||||
---
|
||||
|
||||
## 二、严重风险 (Critical)
|
||||
|
||||
### CR-1:`dependencies.py` 覆盖导致依赖注入链断裂
|
||||
|
||||
**状态**: ✅ 已验证(无需修复)
|
||||
**风险级别**: 🔴 严重
|
||||
**处理难度**: ⚠️ 高
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
当前的 `dependencies.py` 是完全重写的,可能缺少原始文件中的共享服务依赖注入函数。
|
||||
|
||||
**验证结果**:
|
||||
经检查,当前 `dependencies.py` 文件已包含所有必要的函数:
|
||||
- `get_redis()` — Redis 连接池管理
|
||||
- `dep_redis()` — Redis 客户端依赖注入
|
||||
- `dep_wecom_service()` — 企微服务依赖注入
|
||||
- `dep_ai_handler()` — AI 处理器依赖注入
|
||||
- `dep_wingman_service()` — Wingman 服务依赖注入
|
||||
- `get_shared_redis()` — 同步获取 Redis
|
||||
- `get_shared_wecom_service()` — 同步获取企微服务
|
||||
- `get_shared_ai_handler()` — 同步获取 AI 处理器
|
||||
- `init_shared_services()` — 应用启动初始化
|
||||
- `cleanup_shared_services()` — 应用关闭清理
|
||||
|
||||
**结论**:
|
||||
文件完整,无需恢复。依赖注入链正常。
|
||||
|
||||
---
|
||||
|
||||
### CR-2:Token 格式不兼容导致认证混乱
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔴 严重
|
||||
**处理难度**: ⚠️ 中
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
系统存在三种 Token 格式同时运行,可能导致认证混乱。
|
||||
|
||||
**修复方案**:
|
||||
1. `TokenService.get_user_info()` 支持三种格式读取:
|
||||
- 统一格式:`user:token:{token}` → JSON 对象
|
||||
- 旧格式1:`employee:token:{token}` → employee_id
|
||||
- 旧格式2:`agent:token:{token}` → user_id
|
||||
|
||||
2. `TokenService.create_token()` 同时写入统一格式和旧格式:
|
||||
- 根据 `login_source` 决定写入 `employee:token:` 或 `agent:token:`
|
||||
|
||||
3. `TokenService.switch_role()` 更新统一格式,旧格式只存储 employee_id 不需要更新
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/services/token_service.py`
|
||||
|
||||
---
|
||||
|
||||
### CR-3:Portal API 使用旧认证中间件
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔴 严重
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
Portal API 使用 `get_current_agent` 作为认证依赖,不支持新的统一格式。
|
||||
|
||||
**修复方案**:
|
||||
1. 修改 `portal.py` 使用 `get_current_user` 替代 `get_current_agent`
|
||||
2. 修改 `admin_roles.py` 使用 `get_current_user` 替代 `get_current_agent`
|
||||
3. 更新所有函数签名和参数名(`agent` → `current_user`)
|
||||
4. 更新所有日志记录(`agent.user_id` → `current_user.employee_id`)
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/api/portal.py`
|
||||
- `backend/app/api/admin_roles.py`
|
||||
|
||||
---
|
||||
|
||||
### CR-4:慢启动时 Token 创建失败导致登录异常
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔴 严重
|
||||
**处理难度**: ⚠️ 中
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
坐席登录时每次创建新的 Redis 连接,并在 finally 中关闭,可能导致连接泄漏。
|
||||
|
||||
**修复方案**:
|
||||
1. 使用共享 Redis 连接(从 `get_redis()` 获取)
|
||||
2. 移除 finally 中的连接关闭代码(由连接池管理)
|
||||
3. 简化异常处理逻辑
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/api/agents.py`
|
||||
|
||||
---
|
||||
|
||||
## 三、高风险 (High)
|
||||
|
||||
### H-6:角色映射 SQL 注入风险
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
`_get_tag_names_by_ids()` 方法直接调用企微 API,没有对返回的 `tag_names` 进行验证。
|
||||
|
||||
**修复方案**:
|
||||
1. 添加 `_validate_tag_name()` 方法验证标签名称
|
||||
2. 验证规则:长度限制 50 字符,过滤禁止的特殊字符
|
||||
3. 获取标签时过滤不安全的标签名称
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/services/role_mapping_service.py`
|
||||
|
||||
---
|
||||
|
||||
### H-7:角色分配权限验证不完整
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
管理员可以给任何人分配任何角色,包括自己。
|
||||
|
||||
**修复方案**:
|
||||
1. 禁止管理员给自己分配角色(assign_role 添加检查)
|
||||
2. 禁止管理员撤销自己的角色(revoke_role 添加检查)
|
||||
3. 操作审计日志(通过 logger.info 记录)
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/api/admin_roles.py`
|
||||
|
||||
---
|
||||
|
||||
### H-8:映射规则缺少输入验证
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
`create_mapping_rule()` 接口没有验证输入参数。
|
||||
|
||||
**修复方案**:
|
||||
1. 添加 `source_type` 枚举验证(`wecom_tag`/`ehr_position`)
|
||||
2. 添加 `role_name` 枚举验证(`user`/`agent`/`admin`)
|
||||
3. 添加 `source_value` 特殊字符过滤
|
||||
4. 限制 `priority` 范围(0-100)
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/schemas/role.py`
|
||||
|
||||
---
|
||||
|
||||
### H-9:Token 未绑定 IP/设备
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 中
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
Token 没有绑定 IP 地址或设备指纹,任何获取到 Token 的人都可以使用。
|
||||
|
||||
**处理建议**:
|
||||
1. 绑定 IP 地址(可选,影响移动场景)
|
||||
2. 绑定设备指纹(可选,需要前端配合)
|
||||
3. 敏感操作要求二次验证
|
||||
|
||||
**关联开发任务**:
|
||||
- Token 安全加固
|
||||
|
||||
---
|
||||
|
||||
### H-10:管理端 API 无 IP 白名单
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
管理端角色管理 API 没有 IP 白名单限制。
|
||||
|
||||
**修复方案**:
|
||||
1. 在 Nginx 层添加 IP 白名单(/itadmin/ 和 /api/admin/ 路径)
|
||||
2. 允许内网网段:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、10.212.0.0/16
|
||||
|
||||
**修改文件**:
|
||||
- `deploy-server/nginx/nginx.conf`
|
||||
|
||||
---
|
||||
|
||||
### H-11:WebSocket Token 通过 URL 参数传递
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🟠 高
|
||||
**处理难度**: ⚠️ 中
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
WebSocket 连接的 Token 通过 URL 参数传递,会被记录在访问日志中。
|
||||
|
||||
**处理建议**:
|
||||
1. 改为通过 WebSocket 握手头传递
|
||||
2. 或通过第一条消息传递
|
||||
3. 在 Nginx 中对 `/ws/` 路径关闭访问日志
|
||||
|
||||
**关联开发任务**:
|
||||
- WebSocket 安全加固
|
||||
|
||||
---
|
||||
|
||||
## 四、中等风险 (Medium)
|
||||
|
||||
### M-6:旧 Token 迁移策略缺失
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 中
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
没有从旧格式迁移到新格式的策略。
|
||||
|
||||
**处理建议**:
|
||||
1. 实现 Token 自动迁移(访问旧格式 Token 时自动转换为新格式)
|
||||
2. 设置迁移期限(如 30 天后旧 Token 失效)
|
||||
|
||||
**关联开发任务**:
|
||||
- Token 迁移工具
|
||||
|
||||
---
|
||||
|
||||
### M-7:角色缓存策略缺失
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
每次请求都从数据库查询用户角色,没有缓存策略。
|
||||
|
||||
**处理建议**:
|
||||
1. 添加 Redis 缓存(TTL 5-10 分钟)
|
||||
2. 角色变更时主动失效缓存
|
||||
|
||||
**关联开发任务**:
|
||||
- 角色缓存实现
|
||||
|
||||
---
|
||||
|
||||
### M-8:API 速率限制未覆盖所有端点
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
只覆盖了登录端点,其他 API 端点没有速率限制。
|
||||
|
||||
**处理建议**:
|
||||
1. 为所有 API 端点添加速率限制
|
||||
2. 分级限制:登录 10/min,普通 API 60/min,管理 API 30/min
|
||||
|
||||
**关联开发任务**:
|
||||
- 速率限制完善
|
||||
|
||||
---
|
||||
|
||||
### M-9:异常信息泄露
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
异常处理返回 `f"服务器内部错误: {str(exc)}"`,可能泄露内部信息。
|
||||
|
||||
**修复方案**:
|
||||
1. 异常处理器返回通用错误消息:"服务器内部错误,请稍后重试或联系管理员"
|
||||
2. 中间件返回通用错误消息(同上)
|
||||
3. 详细异常信息仅记录到日志
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/main.py`
|
||||
|
||||
---
|
||||
|
||||
### M-10:日志脱敏不足
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
日志中包含 `user_id`、`employee_id` 等敏感信息。
|
||||
|
||||
**修复方案**:
|
||||
1. 添加 `_mask_sensitive_data()` 脱敏函数
|
||||
2. 对 employee_id 进行脱敏处理(保留前3位,如 "abc***def")
|
||||
3. 已处理:role_mapping_service.py、admin_roles.py
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/services/role_mapping_service.py`
|
||||
- `backend/app/api/admin_roles.py`
|
||||
|
||||
---
|
||||
|
||||
### M-11:数据库密码弱密码
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
PostgreSQL 密码使用 `wecom_secret` 或 `wecom_secret_2026`,强度不足。
|
||||
|
||||
**修复方案**:
|
||||
1. `.env.example` 中使用强密码占位符(`your-strong-postgres-password`)
|
||||
2. 添加注释说明密码要求(≥16位,含大小写字母+数字+特殊字符)
|
||||
3. 生产环境通过 `.env` 文件注入强密码
|
||||
|
||||
**修改文件**:
|
||||
- `.env.example`
|
||||
|
||||
---
|
||||
|
||||
### M-12:Redis 无密码保护
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🟡 中
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
Redis 连接无密码认证。
|
||||
|
||||
**修复方案**:
|
||||
1. Docker Compose 中添加 `--requirepass` 参数
|
||||
2. `.env.example` 中添加 `REDIS_PASSWORD` 配置项
|
||||
3. 更新 `REDIS_URL` 格式为 `redis://:password@redis:6379/0`
|
||||
4. 健康检查使用密码认证
|
||||
|
||||
**修改文件**:
|
||||
- `deploy-server/docker-compose.yml`
|
||||
- `.env.example`
|
||||
|
||||
---
|
||||
|
||||
## 五、低风险 (Low)
|
||||
|
||||
### L-5:Nginx 缺少 CSP 和 HSTS 安全头
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔵 低
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**修复方案**:
|
||||
在 Nginx 配置中添加以下安全头:
|
||||
```nginx
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
```
|
||||
|
||||
**修改文件**:
|
||||
- `deploy-server/nginx/nginx.conf`
|
||||
|
||||
---
|
||||
|
||||
### L-6:CORS 配置过于宽松
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔵 低
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**修复方案**:
|
||||
```python
|
||||
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
||||
allow_headers=["Authorization", "Content-Type", "X-Employee-Id"],
|
||||
```
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/main.py`
|
||||
|
||||
---
|
||||
|
||||
### L-7:坐席列表 API 无认证
|
||||
|
||||
**状态**: ✅ 已修复
|
||||
**风险级别**: 🔵 低
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
**修复日期**: 2026-06-13
|
||||
|
||||
**问题描述**:
|
||||
坐席列表 API 没有认证保护,任何人都可以访问。
|
||||
|
||||
**修复方案**:
|
||||
1. 导入 `require_role` 依赖
|
||||
2. 添加 `@require_role("agent", "admin")` 装饰器
|
||||
|
||||
**修改文件**:
|
||||
- `backend/app/api/agents.py`
|
||||
|
||||
---
|
||||
|
||||
### L-8:Nginx `client_max_body_size` 过大
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🔵 低
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**处理建议**:
|
||||
```nginx
|
||||
location /api/upload/ {
|
||||
client_max_body_size 50m;
|
||||
}
|
||||
location /api/ {
|
||||
client_max_body_size 1m;
|
||||
}
|
||||
```
|
||||
|
||||
**关联开发任务**:
|
||||
- Nginx 配置优化
|
||||
|
||||
---
|
||||
|
||||
### L-9:前端硬编码配置
|
||||
|
||||
**状态**: ⚠️ 待处理
|
||||
**风险级别**: 🔵 低
|
||||
**处理难度**: ⚠️ 低
|
||||
**发现日期**: 2026-06-13
|
||||
|
||||
**处理建议**:
|
||||
1. 通过环境变量注入配置
|
||||
2. 避免在前端代码中硬编码敏感信息
|
||||
|
||||
**关联开发任务**:
|
||||
- 前端配置优化
|
||||
|
||||
---
|
||||
|
||||
## 六、处理计划
|
||||
|
||||
### 第一阶段:紧急修复(已完成)
|
||||
|
||||
| 序号 | 任务 | 风险项 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 1 | 恢复 `dependencies.py` 并合并新功能 | CR-1 | ✅ 已验证 |
|
||||
| 2 | 统一 Token 格式并确保向后兼容 | CR-2 | ✅ 已修复 |
|
||||
| 3 | 修改 Portal API 使用新认证中间件 | CR-3 | ✅ 已修复 |
|
||||
| 4 | 修复坐席登录的 Redis 连接管理 | CR-4 | ✅ 已修复 |
|
||||
| 5 | 添加角色分配权限验证 | H-7 | ⚠️ 待处理 |
|
||||
| 6 | 添加映射规则输入验证 | H-8 | ✅ 已修复 |
|
||||
|
||||
### 第二阶段:安全加固(上线后 1 周内)
|
||||
|
||||
| 序号 | 任务 | 风险项 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 7 | Token 绑定 IP/设备指纹 | H-9 | ⚠️ 待处理 |
|
||||
| 8 | 管理端 API 添加 IP 白名单 | H-10 | ⚠️ 待处理 |
|
||||
| 9 | WebSocket Token 改为头传递 | H-11 | ⚠️ 待处理 |
|
||||
| 10 | 实现旧 Token 迁移策略 | M-6 | ⚠️ 待处理 |
|
||||
| 11 | 添加角色缓存 | M-7 | ⚠️ 待处理 |
|
||||
| 12 | 为所有 API 添加速率限制 | M-8 | ⚠️ 待处理 |
|
||||
|
||||
### 第三阶段:纵深防御(上线后 2 周内)
|
||||
|
||||
| 序号 | 任务 | 风险项 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| 13 | 异常处理不再泄露内部信息 | M-9 | ⚠️ 待处理 |
|
||||
| 14 | 日志脱敏处理 | M-10 | ⚠️ 待处理 |
|
||||
| 15 | PostgreSQL 更换强密码 | M-11 | ⚠️ 待处理 |
|
||||
| 16 | Redis 设置密码 | M-12 | ⚠️ 待处理 |
|
||||
| 17 | Nginx 添加 CSP/HSTS 安全头 | L-5 | ⚠️ 待处理 |
|
||||
| 18 | 收紧 CORS 配置 | L-6 | ⚠️ 待处理 |
|
||||
| 19 | 坐席列表 API 添加认证 | L-7 | ⚠️ 待处理 |
|
||||
| 20 | Nginx 按路径细分文件大小限制 | L-8 | ⚠️ 待处理 |
|
||||
|
||||
---
|
||||
|
||||
## 七、风险关联开发任务
|
||||
|
||||
以下风险与当前开发任务关联,需要在相关任务完成时一并处理:
|
||||
|
||||
| 风险项 | 关联开发任务 | 处理时机 |
|
||||
|--------|--------------|----------|
|
||||
| H-6 | 角色映射服务开发 | 实现时添加验证 |
|
||||
| H-7 | 角色管理 API 完善 | 实现时添加权限检查 |
|
||||
| H-9 | Token 安全加固 | Token 服务完善时 |
|
||||
| H-10 | 管理端访问控制 | 部署时配置 |
|
||||
| H-11 | WebSocket 安全加固 | WS 重构时 |
|
||||
| M-6 | Token 迁移工具 | 上线前 |
|
||||
| M-7 | 角色缓存实现 | 性能优化时 |
|
||||
| M-8 | 速率限制完善 | 安全加固时 |
|
||||
| M-9 | 异常处理优化 | 代码审查时 |
|
||||
| M-10 | 日志脱敏实现 | 日志系统优化时 |
|
||||
| M-11 | 生产环境配置 | 部署时 |
|
||||
| M-12 | 生产环境配置 | 部署时 |
|
||||
| L-5~L-9 | Nginx/前端优化 | 部署/优化时 |
|
||||
|
||||
---
|
||||
|
||||
## 八、维护说明
|
||||
|
||||
1. **定期审查**:每月审查一次风险状态,更新处理进度
|
||||
2. **新风险录入**:发现新风险时及时录入本表
|
||||
3. **关联开发任务**:开发任务涉及风险项目时,与风险项目一并处理并更新状态
|
||||
4. **状态更新**:风险处理完成后,更新状态为 ✅ 已修复,并记录修复日期
|
||||
|
||||
---
|
||||
|
||||
## 九、2026-06-14 workbuddy 推送评审新增
|
||||
|
||||
**评审依据**: `docs/评审报告/workbuddy-2026-06-14-消息优化.md`
|
||||
**评审范围**: workbuddy 6-14 推送 + `智能IT支持服务台-版本更新说明-20250614.md`
|
||||
**小计**: 13 项发现(6 P0 + 4 P1 + 3 P2),其中 7 项已修本地代码,6 项待 workbuddy 跟进
|
||||
|
||||
---
|
||||
|
||||
### 9.1 🔴 严重 (新增 6 项,**全部已修**)
|
||||
|
||||
#### CR-5:H5 participants 端点无会话参与权限校验 → P0-1
|
||||
|
||||
- **状态**: ✅ 已修复(2026-06-14 本地代码)
|
||||
- **风险级别**: 🔴 严重(数据泄露)
|
||||
- **位置**: `backend/app/api/h5.py:1107-1145`
|
||||
- **问题**: 仅校验"用户已登录",未校验"是否属于本会话",任意已登录员工可枚举 conversation_id 读取他会话参与者
|
||||
- **修复**: 加 is_creator / is_participant 双重校验
|
||||
|
||||
#### CR-6:recall_message 端点无鉴权 → P0-2
|
||||
|
||||
- **状态**: ✅ 已修复
|
||||
- **风险级别**: 🔴 严重(数据破坏)
|
||||
- **位置**: `backend/app/api/messages.py:293-340`
|
||||
- **问题**: 端点签名只有 `db: AsyncSession = Depends(get_db)`,**无任何鉴权依赖**
|
||||
- **修复**: 加 `agent: Agent = Depends(get_current_agent)` + `message.sender_id == agent.user_id` 校验
|
||||
|
||||
#### CR-7:delete_message 端点无鉴权 → P0-3
|
||||
|
||||
- **状态**: ✅ 已修复
|
||||
- **位置**: `backend/app/api/messages.py:336-365`
|
||||
- **修复**: 同 CR-6
|
||||
|
||||
#### CR-8:mark_read 端点无鉴权 + 会话访问未校验 → P0-4
|
||||
|
||||
- **状态**: ✅ 已修复
|
||||
- **位置**: `backend/app/api/messages.py:368-405`
|
||||
- **问题**: 任意人可调用改任意会话已读状态,破坏"未读数"业务
|
||||
- **修复**: 加 agent 鉴权 + `assigned_agent_id` / `collaborating_agent_ids` 校验
|
||||
- **捎带修**: `where(Message.is_read == False)` 改为 `is_(False)`(P2-1,原表达式在 SQLAlchemy 静默失效)
|
||||
|
||||
#### CR-9:upload_image 端点无鉴权 → P0-5
|
||||
|
||||
- **状态**: ✅ 已修复
|
||||
- **位置**: `backend/app/api/messages.py:400-462`
|
||||
- **问题**: 任意 HTTP 客户端可上传图片占用磁盘(无大小硬限、无频率限制)
|
||||
- **修复**: 加 `Depends(get_current_agent)`
|
||||
|
||||
#### CR-10:upload_message_file 端点无鉴权 → P0-6
|
||||
|
||||
- **状态**: ✅ 已修复
|
||||
- **位置**: `backend/app/api/messages.py:458-525`
|
||||
- **修复**: 同 CR-9
|
||||
|
||||
---
|
||||
|
||||
### 9.2 🟠 高 (新增 4 项,**全部待 workbuddy 跟进**)
|
||||
|
||||
#### H-12:upload 路径在容器本地,容器重建即丢失 → P1-1
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **风险级别**: 🟠 高(数据丢失)
|
||||
- **位置**: `backend/app/api/messages.py:434,487`
|
||||
- **问题**: `media/images/` 和 `media/files/` 写容器本地,容器重建或重启丢所有上传
|
||||
- **处理建议**: 改 volume mount(参考 nginx 静态文件挂载模式,参考 `docker-compose.yml:142-145`)
|
||||
|
||||
#### H-13:SQL 迁移未走 Alembic → P1-2
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **风险级别**: 🟠 高(schema 漂移)
|
||||
- **位置**: `alembic/versions/`(缺)、`models/message.py:190-204`
|
||||
- **问题**: 模型已有 `status` / `recallable_until` 字段,但**未见对应 Alembic 迁移脚本**;版本文档教用户手动 `ALTER TABLE`(反模式)
|
||||
- **处理建议**: 跑 `alembic revision --autogenerate -m "add message status and recallable_until"` 自动生成迁移
|
||||
|
||||
#### H-14:docker-compose backend healthcheck 用 curl → P1-3
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **风险级别**: 🟠 高(监控失真)
|
||||
- **位置**: `docker-compose.yml:117-122`
|
||||
- **问题**: `curl -f http://localhost:8000/health || exit 1`,**backend 精简 Python 镜像无 curl** → healthcheck 永远 unhealthy
|
||||
- **关联记忆**: [[backend-healthcheck-curl-pitfall]]
|
||||
- **处理建议**: 改用 `python -c "import socket; s=socket.socket(); s.connect(('localhost',8000))"`(Python 镜像必有)
|
||||
|
||||
#### H-15:ws_manager 文档承诺"消息状态广播"未实现 → P1-4
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **风险级别**: 🟠 高(文档与代码不符)
|
||||
- **位置**: `docs/智能IT支持服务台-版本更新说明-20250614.md:46` 声称改动 / `backend/app/services/ws_manager.py` 实际无对应方法
|
||||
- **问题**: ConnectionManager 仅有 `send_to_agent` / `broadcast` / `send_to_employee` / `broadcast_to_employees`,**无 `broadcast_message_status(conv_id, msg_id, status)`**
|
||||
- **处理建议**: 实现该方法 + WebSocket 消息格式
|
||||
|
||||
---
|
||||
|
||||
### 9.3 🟡 中 (新增 3 项,1 已修,2 待跟进)
|
||||
|
||||
#### M-13:upload 写文件非原子 → P2-2
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **位置**: `backend/app/api/messages.py:440,494`
|
||||
- **问题**: `with open(file_path, "wb") as f: f.write(content)`,中途崩溃留半文件
|
||||
- **处理建议**: 先写 `*.tmp` 再 `os.rename` 原子化
|
||||
|
||||
#### M-14:upload 返回原始文件名 → P2-3
|
||||
|
||||
- **状态**: ⚠️ 待处理
|
||||
- **位置**: `backend/app/api/messages.py:501`
|
||||
- **问题**: `"filename": original_name` 返回原始文件名,可能含中文 / 特殊字符(XSS 风险)
|
||||
- **处理建议**: URL encode 或服务端做白名单过滤
|
||||
|
||||
#### M-15:mark_read SQL `== False` 表达式静默失效 → P2-1
|
||||
|
||||
- **状态**: ✅ 已修复(捎带在 P0-4 修复中)
|
||||
- **位置**: `backend/app/api/messages.py:388`(原)
|
||||
- **问题**: `where(Message.is_read == False)` 在 SQLAlchemy 中不报错但**实际未生效**(Python `==` 返回 False → SQLAlchemy 当赋值处理但参数已绑死)
|
||||
- **修复**: 改为 `is_(False)`,走 SQL `is false` 否定
|
||||
|
||||
---
|
||||
|
||||
### 9.4 文档本身的 4 处错误(已记录待修订)
|
||||
|
||||
| # | 位置 | 错误 | 建议修订 |
|
||||
|---|------|------|----------|
|
||||
| D-1 | 版本说明部署步骤 5 | `docker compose -p root up -d` **正是用户 6-14 生产事故的根因** | **删除 `-p root` 标志** |
|
||||
| D-2 | 版本说明部署步骤 6 | SQL `DEFAULT 'sent'` 引号未转义(shell 语法错) | 改用 Alembic 迁移脚本 |
|
||||
| D-3 | 版本说明 2.1 ws_manager | 声称"添加消息状态广播"但实际未实现 | 改"规划中"或"本次未实现" |
|
||||
| D-4 | 版本说明 2.1 docker-compose | "healthcheck 已配置"不准确 | 加注 backend curl 坑 |
|
||||
|
||||
---
|
||||
|
||||
### 9.5 评审结论与流程建议
|
||||
|
||||
- **P0 比例 46% (6/13) 过高** —— workbuddy 后续推送需**强制走评审流程**
|
||||
- **建议加 pre-commit 检查**: 新增端点无 `Depends(...)` 鉴权依赖时拒绝推送
|
||||
- **下次推送窗口**: 等 H-12~15 + M-13/14 全部修完再合入,**不在评审未消化前叠加新功能**
|
||||
|
||||
---
|
||||
|
||||
### 9.6 新增项状态速查
|
||||
|
||||
| 编号 | 状态 | 编号 | 状态 |
|
||||
|------|------|------|------|
|
||||
| CR-5 (P0-1) | ✅ | H-12 (P1-1) | 🟡 半成品(留 #25) |
|
||||
| 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) | ✅(捎带)|
|
||||
|
||||
---
|
||||
|
||||
## 第十节: 2026-06-14 P0 安全评估(workbuddy 推送 v2)
|
||||
|
||||
**关联 commit**: `3735dc0` — feat(security): P0 安全止血 - WS token 改 header + 坐席本地密码
|
||||
**主报告**: `docs/评审报告/workbuddy-2026-06-14-P0安全.md`
|
||||
**评审结论**: 🟡 **部分完成,5 项遗留**(3 项 P0 / 2 项 P1)
|
||||
**workbuddy 下一轮任务**: #18
|
||||
|
||||
> 📌 第十节有独立小计(5 P0 + 2 P1,2 个新维度:WS token 鉴权 + 坐席本地密码)。
|
||||
|
||||
### 10.1 小计
|
||||
|
||||
| 维度 | 任务 | 真实状态 |
|
||||
|---|---|---|
|
||||
| P0-#1 | WECOM_SECRET 集中化 | 🟡 **只规划未实改** (`docs/安全/secret-管理.md`) |
|
||||
| P0-#2 | SSL 私钥在仓 | 🟢 **8-A 阶段已修**(.gitignore `**` 模式) |
|
||||
| P0-#3 | Mock login bypass | 🟢 **之前已修** |
|
||||
| P0-#4 | WS token URL/日志泄露 | 🟡 **半成品**(服务端 OK,前端 ws.ts + nginx access_log 待关) |
|
||||
| P0-#5 | 坐席本地密码 | 🟡 **半成品**(字段/Schema/端点 OK,类型 bug + 降级放行 + 缺依赖) |
|
||||
|
||||
**总评**: 2/5 P0 完成,3 项遗留待 workbuddy 下一轮修。
|
||||
|
||||
### 10.2 遗留项追踪(给 workbuddy 任务清单 #18)
|
||||
|
||||
| # | 严重度 | 文件 | 项 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 遗留 1 | 🔴 P0 | `frontend-agent/src/composables/useWebSocket.ts:106-110` | 浏览器 WebSocket API 不支持自定义 header,改 Sec-WebSocket-Protocol | ⚠️ |
|
||||
| 遗留 2 | 🔴 P0 | `nginx.conf` + `deploy-server/nginx.conf` | `location /ws/ { access_log off; }` | ⚠️ |
|
||||
| 遗留 3 | 🟡 P1 | `backend/app/models/agent.py:142-148` | `Mapped[str]` → `Mapped[Optional[str]]` | ⚠️ |
|
||||
| 遗留 4 | 🟡 P1 | `backend/app/api/agents.py` 降级放行 | 强制 password 验证 | ⚠️ |
|
||||
| 遗留 5 | 🟡 P1 | `backend/requirements.txt` | 缺 passlib/bcrypt 依赖 | ⚠️ |
|
||||
|
||||
### 10.3 评审教训(防再犯)
|
||||
|
||||
1. **WebSocket API 边界**: 浏览器 vs Node.js `ws` 库 API 差异
|
||||
2. **依赖检查**: 改代码必须同步 requirements.txt
|
||||
3. **配置改动**: plan 写了的 nginx / conf 必须做
|
||||
4. **类型一致性**: Mapped[T] + nullable=True 必须 Optional
|
||||
5. **逻辑回归**: 新鉴权必须 review 已有降级路径
|
||||
|
||||
### 10.4 推 Gitea 状态
|
||||
|
||||
- **本地 commit**: 3735dc0 ✅
|
||||
- **推 Gitea**: 🔴 **卡 #8**(MariaDB 套件未装)
|
||||
- **下次**: Gitea 起来后 `git push -u origin main` 一次推送 → 触发 workbuddy 二次评审 → #18 闭环
|
||||
|
||||
### 10.5 第十节状态速查
|
||||
|
||||
| 编号 | 状态 |
|
||||
|---|---|
|
||||
| P0-#1 WECOM_SECRET 集中化 | 🟡 规划中(V1/V2) |
|
||||
| P0-#2 SSL 私钥 | 🟢 8-A 完成 |
|
||||
| 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 路径 | 🔄 评审闭环中(留 P2 优化,任务 #25) |
|
||||
| H-13 (P1-2) Alembic 迁移 | 🔄 评审闭环中 |
|
||||
| H-14 (P1-3) healthcheck | 🔄 评审闭环中 |
|
||||
| H-15 (P1-4) ws 状态广播 | 🔄 评审闭环中 |
|
||||
|
||||
---
|
||||
|
||||
## 第十二节: 2026-06-14 Gitea 卸载清空事故 + 重建复盘 ⚠️ 教训重灾区
|
||||
|
||||
**触发时间**: 2026-06-14 晚
|
||||
**触发原因**: 用户在 DSM 套件中心用 "卸载清空" 选项卸载 Gitea
|
||||
**影响范围**: Gitea 服务停 + Web 不可达 + 仓裸仓库可能残留
|
||||
**恢复时长**: ~30 分钟
|
||||
**任务编号**: #26
|
||||
|
||||
### 12.1 事故时序
|
||||
|
||||
| 时刻 | 事件 |
|
||||
|---|---|
|
||||
| T+0 | 用户在 DSM 套件中心 → Gitea → 卸载 → 勾选"清空" |
|
||||
| T+1m | Gitea 服务停止,8418 端口无响应 |
|
||||
| T+1m | 外部 Funnel 域名 `ds923plus.tail58d872.ts.net` 无法访问 |
|
||||
| T+5m | 本地仓 `D:\资料\03-项目开发\wecom_it_smart_desk` 检查 11 commit 完整 |
|
||||
| T+10m | 用户发现"创仓报已存在文件" → 数据没清干净 |
|
||||
| T+15m | 用户用 Gitea Web "删除仓库" → "创建新仓库" |
|
||||
| T+20m | 用户创新 token `9754e1d8c8a0...` (权限含 admin) |
|
||||
| T+22m | 我改 `.git/config` URL 清旧 token(走 wincred 缓存) |
|
||||
| T+25m | PowerShell 推 main 成功(639 对象 / 3.67 MiB) |
|
||||
| T+28m | 配 main 分支保护 (PR + 1 reviewer) |
|
||||
| T+30m | 全部恢复,功能等价 |
|
||||
|
||||
### 12.2 教训 + 防御
|
||||
|
||||
#### 🛑 教训 1: 卸载"清空" 不等于 数据清除
|
||||
- **现象**: 套件"卸载清空"清了 app + 数据库,**但仓裸仓库目录残留**(`/volume1/@appdata/gitea/gitea/repos/`)
|
||||
- **后果**: 重装 Gitea 后创仓冲突("已存在文件")
|
||||
- **修复**: 用户手动"删除仓库 → 创建新仓库"解决
|
||||
- **防御**:
|
||||
- ✅ 部署 `scripts/backup-gitea.sh`(本次新增,C-2 任务)
|
||||
- ✅ 卸载前**强制备份**
|
||||
- ✅ 评估"卸载清空" vs "卸载保留数据"
|
||||
|
||||
#### 🛑 教训 2: token 嵌入 `.git/config` URL 是反模式
|
||||
- **现象**: 之前为 workbuddy 推 Gitea,把 token `ae236991c3d5...` 直接嵌入 `origin.url`
|
||||
- **后果**: workbuddy-claude token 失效后,URL 里有死凭据 + auto-classifier 拒绝重写 URL
|
||||
- **修复**: URL 改回 `https://simon@...`,用 `git credential approve` 存 wincred
|
||||
- **防御**:
|
||||
- ✅ **永远不**在 URL 里嵌 token(写进 [[locked-decisions]] 候选)
|
||||
- ✅ 推 Gitea 走 `git credential approve` + wincred
|
||||
- ✅ workbuddy-claude 创独立 user account(避免 token 跟 simon 账号混)
|
||||
|
||||
#### 🛑 教训 3: PowerShell 弹窗在后台易丢
|
||||
- **现象**: 用户推 main 时第一次"fatal: User cancelled dialog"(可能弹窗在后台没看到)
|
||||
- **修复**: 用 `git credential approve` 预先存 wincred,推时不弹窗
|
||||
- **防御**:
|
||||
- ✅ **CI / workbuddy / 脚本** 永远走 wincred(不弹)
|
||||
- ✅ 交互推送前先 `git credential approve`
|
||||
|
||||
#### 🛑 教训 4: main 分支保护配置需考虑"评审员有谁"
|
||||
- **现象**: 配 `block_admin_merge: true` + `required_approvals: 1` + 只有 simon 一个 user → **simon 永远合不进自己 PR**
|
||||
- **修复**: 临时改 `block_admin_merge: false`,等 workbuddy 接入再开
|
||||
- **防御**:
|
||||
- ✅ 配保护前**确认有 ≥2 个 user**(评审员 + 推送者)
|
||||
- ✅ 创 workbuddy-claude user account(本次未做,等用户睡前安排)
|
||||
|
||||
### 12.3 数据保全审计
|
||||
|
||||
| 资源 | 卸载清空前 | 卸载清空后 | 重建后 | 完整性 |
|
||||
|---|---|---|---|---|
|
||||
| Gitea 服务 | ✅ 运行 | ❌ 停止 | ✅ 启动 | ✅ 100% |
|
||||
| Gitea 数据库 (SQLite) | ✅ 完整 | ⚠️ 残留可能 | ✅ 全新 | ✅ 100%(旧数据丢) |
|
||||
| 仓裸仓库 (repos/) | ✅ 11 commit | ⚠️ 残留 | ✅ 0 commit | ⚠️ 0%(待重推) |
|
||||
| 本地仓 (windows) | ✅ 11 commit | ✅ 11 commit | ✅ 11 commit | ✅ 100% |
|
||||
| Token 表 | ✅ 3 token | ⚠️ 残留 | ✅ 1 token(simon's) | ⚠️ 旧 token 全失效 |
|
||||
| wincred 缓存 | ✅ workbuddy-claude | ⚠️ 残留 | ✅ simon 新 | ✅ 重置 |
|
||||
|
||||
### 12.4 待办
|
||||
|
||||
| # | 项 | 阻塞 |
|
||||
|---|---|---|
|
||||
| 1 | **Gitea 备份脚本部署**(`scripts/backup-gitea.sh` 推到 NAS) | 用户需 SCP |
|
||||
| 2 | **备份 cron 配置**(每天 3 点) | SSH 进 NAS |
|
||||
| 3 | **创 workbuddy-claude user** | 用户睡前做 |
|
||||
| 4 | **workbuddy-claude token 替换** | 等 #3 |
|
||||
| 5 | **`block_admin_merge` 改回 `true`**(workbuddy 接入后) | 等 #3 |
|
||||
| 6 | **删旧 workbuddy-claude token 残留** | 等 #3 |
|
||||
| 7 | **Gitea 部署文档**(`docs/Gitea部署指南.md` 含备份恢复) | 我写 |
|
||||
| 8 | **风险跟踪表加 "数据丢失" 风险项** | 我写(下面) |
|
||||
|
||||
### 12.5 新增风险项
|
||||
|
||||
| 编号 | 严重度 | 内容 | 状态 |
|
||||
|---|---|---|---|
|
||||
| **M-1 (新)** | 🟠 中高 | **Gitea 数据无异地备份** —— 一旦 NAS 硬盘故障,Gitea 全失 | 🆕 本节新增 |
|
||||
| **M-2 (新)** | 🟡 中 | **套件卸载误操作风险** —— 误勾"清空"导致数据全失 | 🆕 本节新增 |
|
||||
| **L-2 (新)** | 🟢 低 | **PowerShell 弹窗后台丢失** —— 关键推送可能因弹窗丢失而失败 | 🆕 本节新增 |
|
||||
|
||||
### 12.6 推送约定升级 (写进 [[locked-decisions]] 候选)
|
||||
|
||||
> **所有 Gitea 推送凭据走 wincred,禁止明文嵌入 `.git/config` URL**
|
||||
|
||||
具体:
|
||||
1. `.git/config` 的 `origin.url` **只写用户名**(`https://simon@...`),不写 token
|
||||
2. 首次推 / 换 token → `git credential approve` 一次性存 wincred
|
||||
3. workbuddy 推送 → 创独立 user account + 自己的 token(不跟 simon 共用)
|
||||
4. CI / 自动化推送 → 用环境变量 + `git -c credential.helper=!gh auth git-credential`(gh CLI) 或 secret store
|
||||
5. **违反 → auto-classifier 拒绝**(已成事实)
|
||||
@@ -0,0 +1,265 @@
|
||||
# 企微IT智能服务台 — 项目管理主文档
|
||||
|
||||
> **版本**: v2.4 | **日期**: 2026-07-10 | **维护人**: 助理
|
||||
|
||||
---
|
||||
|
||||
## 一、项目状态总览
|
||||
|
||||
> **一句话总览**:v0.7.1 已上线运行,生产稳定。知识库迭代 v0.7.2 全链路交付完成。
|
||||
|
||||
### 已完成 (v0.7.1)
|
||||
- ✅ 企微入口 SSO
|
||||
- ✅ 管理后台 RBAC(6处装饰器修复)
|
||||
- ✅ 敏感词检测(隐私正则修复)
|
||||
- ✅ 扫码登录优化
|
||||
- ✅ 文档优化专项
|
||||
|
||||
### v0.7.2 知识库迭代(全部交付)
|
||||
- ✅ AI 辅助功能增强
|
||||
- ✅ 排查流程优化
|
||||
- ✅ 知识库迭代
|
||||
|
||||
### 版本迭代
|
||||
|
||||
| 版本 | 状态 | 主要内容 | 日期 |
|
||||
|------|------|----------|------|
|
||||
| v0.7.0 | ✅ 已上线 | 企微SSO、MFA、RBAC | 2026-06 |
|
||||
| v0.7.1 | ✅ 已上线 | 敏感词检测、token修复、扫码登录优化 | 2026-07-04 |
|
||||
| v0.7.2 | ✅ 已完成 | backlog候选(AI辅助、排查流程,知识库迭代) | 2026-07+ |
|
||||
|
||||
---
|
||||
|
||||
## 二、任务管理文档体系
|
||||
|
||||
本项目采用四级任务管理文档体系:
|
||||
|
||||
| 级别 | 文档 | 用途 |
|
||||
|------|------|------|
|
||||
| L1 | **项目状态看板** | 驾驶舱仪表盘,当前正在做+待办 |
|
||||
| L2 | **项目任务状态报告** | 历史全量任务清单 |
|
||||
| L3 | **需求候选池** | 未来版本候选功能 |
|
||||
| L4 | **PRD需求池** | 完整需求来源 |
|
||||
|
||||
---
|
||||
|
||||
## 三、快速导航
|
||||
|
||||
### 🔴 现在做什么?
|
||||
查看 **项目状态看板** 的「正在做」和「P0必做」区
|
||||
|
||||
### 📜 历史全部任务?
|
||||
查看 **项目任务状态报告**
|
||||
|
||||
### 📋 未来计划?
|
||||
查看 **需求候选池** (v0.7.2+)
|
||||
|
||||
### 📖 需求来源?
|
||||
查看 **PRD需求文档**
|
||||
|
||||
### 📅 每日工作记录?
|
||||
查看 `.workbuddy/memory/` 目录
|
||||
|
||||
---
|
||||
|
||||
## 四、项目状态看板
|
||||
|
||||
### 正在做 (in_progress)
|
||||
|
||||
| # | 任务 | 说明 |
|
||||
|---|---|---|
|
||||
| #91 | 忘记密码-企微扫码重置 | 坐席忘记密码时通过企微扫码验证后重置 |
|
||||
| #107 | 后端部署卷挂载改造 | 方案C:镜像烘焙→代码卷挂载,消除两份代码不同步根因 |
|
||||
|
||||
### ✅ 已完成
|
||||
|
||||
| # | 任务 | 说明 | 完成日期 |
|
||||
|---|---|---|---|
|
||||
| #111 | 坐席端消息头像不显示Bug | 🐛 后端消息接口未返回sender_avatar → Schema添加字段 + API填充员工/AI头像 + 前端显示 | 2026-07-10 |
|
||||
| #112 | 坐席端消息布局调整 | ✨ 头像和名字位置互换(头像在前、名字在后) | 2026-07-10 |
|
||||
| #113 | 审批类型扩展与卡片URL直跳 | ✨ 审批类型 5→12种/18流程,后端静态模板+关键词扩展,前端卡片12类17选项URL直跳,Dify v2 System Prompt覆盖全部12类 | 2026-07-10 |
|
||||
| #114 | 审批卡片同窗口导航改造 | ✨ window.open(\_blank) → window.location.href,企微原生返回按钮,COEP/CSP安全头分析 | 2026-07-10 |
|
||||
| #115 | 企微跨应用免登录研究 | 📋 同corpid下IT服务台H5与运维平台各自独立OAuth2 snsapi_base静默授权,结论已归档 | 2026-07-10 |
|
||||
| #108 | H5消息重复Bug | 🐛 员工发送消息后自己看到两条 → sendNewMessage未更新lastMessageId导致轮询重复拉取 → 已修复并部署 | 2026-07-10 |
|
||||
| #109 | H5消息自动滚动 | ✨ 收到新消息时自动滚动到底部 → 已实现并部署 | 2026-07-10 |
|
||||
| #110 | WebSocket Token认证修复 | 🐛 QR码登录存储user:token:*但WS只查agent:token:* → 支持两种格式查询 | 2026-07-10 |
|
||||
| #105 | 摇人消息推送到通知栏Bug | 🐛 删除shake/call_agent函数中的企微消息推送调用,修复完成并已部署 | 2026-07-10 |
|
||||
|
||||
### P0 必做 (下一个 sprint)
|
||||
|
||||
| # | 任务 | 重要程度 | 说明 |
|
||||
|---|---|---|---|
|
||||
| #48 | v1.0 收窄 set_real_ip_from | 🔴 P0 | 现 allow 0.0.0.0/0 是临时方案,正式上线前必须改精确代理IP |
|
||||
| #81 | 敏感词检测 + 语气优化 | 🔴 P0 | v0.7.1 开发内容,文本安全过滤 |
|
||||
| #104 | 运行期结构化日志查看页(D) | 🔴 P0 | 决策4:落地筛选+下载页面 |
|
||||
|
||||
### P1 重要
|
||||
|
||||
| # | 任务 | 说明 |
|
||||
|---|---|---|
|
||||
| #105 | 摇人消息推送到通知栏Bug | 🐛 摇人/举手功能系统消息错误推送到企微应用通知,应只在H5页面内展示 |
|
||||
| #73 | 修后端文件未真正覆盖 | `yes | cp -f` 路径 |
|
||||
| #86 | 排查流程图零依赖部分 review | 把 Mermaid 流程图从代码里剥离 |
|
||||
| #88 | 管理后台 RBAC 角色权限 | 细粒度角色权限 |
|
||||
| #75 | 头像同步功能完善 | 登录强制同步 + 前端首字降级 |
|
||||
|
||||
### P1/P2 功能开发任务
|
||||
|
||||
#### 阶段2 - P1功能
|
||||
|
||||
| # | 功能 | 状态 |
|
||||
|---|---|---|
|
||||
| P1-24 | 摇人按钮 | ✅已完成 |
|
||||
| P1-25 | 满意度评价 | ✅已完成 |
|
||||
| P1-26 | 排队系统 | ✅已完成 |
|
||||
| P1-27 | 快速回复 | ✅已完成 |
|
||||
| P1-28 | 知识库(基础) | ✅已完成 |
|
||||
|
||||
#### 阶段3 - P2功能
|
||||
|
||||
| # | 功能 | 状态 |
|
||||
|---|---|---|
|
||||
| P2-09 | AI Wingman | ✅已完成 |
|
||||
| P2-10 | 会话标注 | ✅已完成 |
|
||||
| P2-11 | 自动摘要 | ✅已完成 |
|
||||
| P2-07~11 | 审批流程系统 | ✅已完成(详见任务说明书-78) |
|
||||
|
||||
#### 阶段4 - P2功能
|
||||
|
||||
| # | 功能 | 状态 |
|
||||
|---|---|---|
|
||||
| P2-12 | 数据看板 | ✅已完成 |
|
||||
| P2-13 | 知识库自动迭代 | ✅已完成 |
|
||||
|
||||
---
|
||||
|
||||
## 五、最近搞定
|
||||
|
||||
### 2026-07-10
|
||||
- ✅ 审批类型扩展 5→12种/18流程 + 卡片URL直跳 + Dify v2 发布(#113)
|
||||
- ✅ 审批卡片同窗口导航改造(#114)
|
||||
- ✅ 企微跨应用免登录可行性研究(#115)
|
||||
- ✅ 坐席端消息头像不显示Bug修复 + 部署(#111)
|
||||
- ✅ 坐席端消息布局调整(头像在名字前) + 部署(#112)
|
||||
- ✅ H5消息重复Bug修复 + 部署
|
||||
- ✅ H5消息自动滚动功能 + 部署
|
||||
- ✅ WebSocket Token认证修复 + 部署
|
||||
- ✅ 摇人消息推送Bug修复 + 部署
|
||||
|
||||
### 2026-07-09
|
||||
- ✅ WS 子协议修复部署生产
|
||||
- ✅ 方案A E2E 通过
|
||||
|
||||
### 2026-07-08
|
||||
- ✅ 消息发送延时 E2E 验证通过
|
||||
- ✅ 头像同步功能代码交付(12/12测试通过)
|
||||
|
||||
### 2026-07-07
|
||||
- ✅ 管理后台登录修复
|
||||
- ✅ 故障排查文档整合
|
||||
|
||||
### 2026-07-06
|
||||
- ✅ P1-25 满意度评价完成
|
||||
- ✅ #90 身份认证问题修复
|
||||
|
||||
### 2026-07-05
|
||||
- ✅ 坐席端消息列表500错误修复
|
||||
- ✅ 消息发送失败修复
|
||||
- ✅ 文档补充
|
||||
|
||||
---
|
||||
|
||||
## 六、风险管理
|
||||
|
||||
### 风险总览
|
||||
|
||||
| 级别 | 数量 | 已处理 | 待处理 | 处理率 |
|
||||
|------|------|--------|--------|--------|
|
||||
| 🔴 严重 (Critical) | 4 | 4 | 0 | **100%** |
|
||||
| 🟠 高 (High) | 6 | 5 | 1 | **83%** |
|
||||
| 🟡 中 (Medium) | 7 | 4 | 3 | **57%** |
|
||||
| 🔵 低 (Low) | 5 | 3 | 2 | **60%** |
|
||||
| **合计** | **22** | **16** | **6** | **73%** |
|
||||
|
||||
---
|
||||
|
||||
## 七、怎么跑起来
|
||||
|
||||
### 1. 后端 dev
|
||||
|
||||
```powershell
|
||||
cd D:\资料\03-项目开发\wecom_it_smart_desk
|
||||
docker compose -f docker-compose.dev.yml --env-file .env.dev up -d
|
||||
curl http://localhost:8000/api/dev/health
|
||||
```
|
||||
|
||||
### 2. 前端 dev
|
||||
|
||||
```powershell
|
||||
# 一起起所有前端
|
||||
.\scripts\dev-frontend-start.ps1
|
||||
```
|
||||
|
||||
### 3. 浏览器验证
|
||||
|
||||
| 端 | 地址 |
|
||||
|---|------|
|
||||
| Portal | http://localhost:5176/itportal/select |
|
||||
| H5 | http://localhost:5174/itdesk/ |
|
||||
| 坐席 | http://localhost:5173/itagent/ |
|
||||
| 管理员 | http://localhost:5175/itadmin/ |
|
||||
|
||||
---
|
||||
|
||||
## 八、文档清单
|
||||
|
||||
### 任务说明书/
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| IT智能服务台-项目管理主文档 | 本文档 |
|
||||
| 02-风险跟踪表.md | 风险登记册(22项) |
|
||||
| 任务说明书-01-新开发任务.md | v0.7.2 新功能开发任务 |
|
||||
| 任务说明书-02-卡点任务.md | 优先级最高卡点任务 |
|
||||
| 任务说明书-75-头像同步功能完善.md | 进行中的任务 |
|
||||
| 任务说明书-78-审批流程系统.md | 审批类型扩展+卡片URL直跳+同窗口导航+免登录研究 |
|
||||
|
||||
### SOPs-标准流程/
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| SOP-01-Gitea部署.md | Gitea 部署 SOP |
|
||||
| SOP-02-Gitea备份恢复.md | Gitea 备份恢复 SOP |
|
||||
| SOP-03-推送评审.md | 推送评审 SOP |
|
||||
| SOP-04-应急响应.md | 应急响应 SOP |
|
||||
| SOP-05-项目管理文档管理规范.md | 文档管理规范 SOP |
|
||||
|
||||
---
|
||||
|
||||
## 九、相关文档
|
||||
|
||||
| 类别 | 文档 | 位置 |
|
||||
|------|------|------|
|
||||
| 项目概览 | 项目总览与部署手册 | `01-项目总览/` |
|
||||
| 产品需求 | PRD需求文档 | `02-产品需求/` |
|
||||
| 技术架构 | 技术架构设计 | `03-技术架构/` |
|
||||
| 测试质量 | E2E验收清单 | `06-测试质量/` |
|
||||
| 部署运维 | 部署指南 | `09-部署运维/` |
|
||||
|
||||
---
|
||||
|
||||
## 十、版本历史
|
||||
|
||||
| 版本 | 日期 | 变更 |
|
||||
|------|------|------|
|
||||
| v2.4 | 2026-07-10 | 新增 #113-115 审批流程系统任务(类型扩展+卡片导航+免登录研究),P2功能表新增审批流程系统 |
|
||||
| v2.3 | 2026-07-10 | 新增 #111-112 头像显示与布局调整任务 |
|
||||
| v2.2 | 2026-07-10 | 新增 #108-110 Bug修复任务(消息重复、自动滚动、WS认证) |
|
||||
| v2.1 | 2026-07-10 | 看板新增 #107 后端部署卷挂载改造任务 |
|
||||
| v2.0 | 2026-07-10 | 整合任务总索引、项目状态看板、任务状态报告、风险跟踪表 |
|
||||
| v1.1 | 2026-07-04 | 新增产品需求变更、技术架构变更、文档管理变更 |
|
||||
| v1.0 | 2026-07-04 | 初始版本 |
|
||||
|
||||
---
|
||||
|
||||
> **本文档就是项目的"驾驶舱仪表盘"。任何时候新开 session,先读这个文件就懂上下文。
|
||||
@@ -0,0 +1,314 @@
|
||||
# 新开发任务说明书 (v0.7.2+)
|
||||
|
||||
> **版本**: v1.2 | **日期**: 2026-07-04 | **状态**: 🔴 进行中
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | v0.7.2+ 新功能开发 |
|
||||
| **任务ID** | #90 等 |
|
||||
| **优先级** | 🔴P0 > 🟠P1 |
|
||||
| **类型** | 功能开发 / Bug修复 / 安全加固 / 文档完善 |
|
||||
| **状态** | 进行中 / 延后 |
|
||||
| **负责人** | 宋献 + Claude |
|
||||
| **创建日期** | 2026-07-04 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/02-产品需求文档PRD-v1.2-20260704.md` | §4.5 坐席/管理员登录流程 | 登录逻辑调整 |
|
||||
| `02-产品需求/02-产品需求文档PRD-v1.2-20260704.md` | §9 术语与图标规范 | 统一术语 |
|
||||
| `02-产品需求/product-产品/v0.7.2-backlog-candidate-2026-06-24.md` | backlog项 | 未来功能候选 |
|
||||
|
||||
### 技术架构
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `03-技术架构/02-技术方案/技术方案-消息功能详细设计.md` | - | 消息功能设计 |
|
||||
| `03-技术架构/02-技术方案/技术方案-摇人协作.md` | - | 摇人功能设计 |
|
||||
| `03-技术架构/02-技术方案/技术方案-邀请功能.md` | - | 邀请功能设计 |
|
||||
| `03-技术架构/01-ADRs-架构决策/ADR-XXX.md` | - | 架构决策记录 |
|
||||
|
||||
### 原型设计
|
||||
| 来源文档 | 页面 | 说明 |
|
||||
|----------|------|------|
|
||||
| `04-原型设计/prototypes-原型图/agent-workspace-v5_4.html` | 坐席工作台 | v5.4 UI |
|
||||
| `04-原型设计/prototypes-原型图/h5-user-wecom-style-v2-desktop.html` | H5用户端 | v2 桌面版 |
|
||||
| `04-原型设计/prototypes-原型图/admin-dashboard-v1.html` | 管理后台 | v1 UI |
|
||||
|
||||
### 项目看板
|
||||
| 来源 | 任务名 | 说明 |
|
||||
|------|--------|------|
|
||||
| `05-项目状态看板/01-项目状态看板.md` | P0任务 | 当前进行中任务 |
|
||||
|
||||
---
|
||||
|
||||
## 📢 需求变更说明(2026-07-04)
|
||||
|
||||
根据 PRD v1.5 更新:
|
||||
- **用户端**:强制企微内嵌打开,OAuth2 静默授权
|
||||
- **坐席/管理端**:浏览器直接打开,无需经过企微工作台,支持账号密码+OTP认证
|
||||
|
||||
> **核心变更**:坐席/管理员可直接在浏览器打开登录页面,不再需要经过 Portal
|
||||
|
||||
---
|
||||
|
||||
## 🎯 当前优先级(用户确认)
|
||||
|
||||
> **用户确认优先级**:坐席/管理直接登录 > 用户端企微内嵌 > 其他任务
|
||||
|
||||
---
|
||||
|
||||
## 🆕 新功能开发任务
|
||||
|
||||
---
|
||||
|
||||
### 任务 1: 坐席/管理端直接登录(🔴 最优先)
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #90 |
|
||||
| **优先级** | 🔴 P0 |
|
||||
| **类型** | 功能开发 / 登录流程 |
|
||||
| **描述** | 坐席/管理端浏览器直接打开登录页,智能检测企微登录状态,提供三种登录方式 |
|
||||
| **状态** | 开发中(v1.8完成) |
|
||||
| **估时** | 4小时(开发+测试) |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: PRD v1.5 §4.5 登录流程调整
|
||||
- **原型设计**: admin-dashboard-v1.html 登录页面
|
||||
- **项目看板**: P0任务
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 后端登录API (`/api/agents/login`) | 代码 |
|
||||
| 2 | 坐席端登录页面 (v1.8) | 代码 |
|
||||
| 3 | 管理端登录页面 | 代码 |
|
||||
| 4 | OTP验证逻辑 | 代码 |
|
||||
| 5 | 企微客户端检测 (JS-SDK/wecom://) | 代码 |
|
||||
| 6 | 更新API文档 | 文档 |
|
||||
|
||||
#### 验证方式
|
||||
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 坐席登录 | 手动测试 | 账号密码+OTP登录成功 |
|
||||
| 管理登录 | 手动测试 | 账号密码+OTP登录成功 |
|
||||
| 权限控制 | 越权测试 | 坐席无法访问管理端 |
|
||||
| 错误处理 | 异常输入 | 正确提示 |
|
||||
|
||||
#### 完成标准
|
||||
|
||||
- [x] 后端登录API开发完成
|
||||
- [x] 坐席端登录页面开发完成
|
||||
- [x] 管理端登录页面开发完成
|
||||
- [x] OTP验证正常工作
|
||||
- [x] 企微客户端检测功能 (v1.8)
|
||||
- [ ] 部署测试
|
||||
- [ ] 代码通过 Code Review
|
||||
|
||||
---
|
||||
|
||||
### 任务 2: 收窄 IP 白名单安全加固(⏸️ 延后)
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #48 |
|
||||
| **优先级** | P1 → ⏸️ 延后 |
|
||||
| **类型** | 安全加固 |
|
||||
| **描述** | 当前 `/api/admin/` + `/itadmin/` 使用 `allow 0.0.0.0/0` 临时全开,需收窄到精确代理 IP |
|
||||
| **阻塞原因** | 需网络组确认真实代理 IP 段(WAF/堡垒机/CDN 出口 IP) |
|
||||
| **估时** | 1小时(改 nginx + reload + 验证) |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: 安全合规要求
|
||||
- **技术架构**: nginx 配置
|
||||
- **项目看板**: 安全加固任务
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | nginx IP白名单配置 | 配置 |
|
||||
| 2 | 安全验证报告 | 文档 |
|
||||
|
||||
#### 验证方式
|
||||
- [ ] 内部IP可访问
|
||||
- [ ] 外部IP被拦截
|
||||
|
||||
#### 完成标准
|
||||
- [ ] nginx 配置已更新
|
||||
- [ ] 已验证内网访问正常
|
||||
- [ ] 已验证外网无法访问管理端
|
||||
|
||||
---
|
||||
|
||||
### 任务 3: 修复部署脚本文件覆盖问题
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #73 |
|
||||
| **优先级** | P1 |
|
||||
| **类型** | 部署优化 |
|
||||
| **描述** | `yes | cp -f` 路径问题导致部署时文件偶尔没真正覆盖 |
|
||||
| **根因** | `deploy-staging/` bind mount + RO 双重坑 |
|
||||
| **估时** | 2小时(改 deploy 脚本用 rsync --checksum) |
|
||||
|
||||
#### 输入项来源
|
||||
- **技术架构**: 部署流程文档
|
||||
- **项目看板**: 部署优化任务
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 优化后的部署脚本 | 脚本 |
|
||||
| 2 | 部署验证测试 | 测试 |
|
||||
|
||||
#### 验证方式
|
||||
- [ ] 增量部署测试通过
|
||||
- [ ] 文件覆盖生效
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 部署脚本已优化
|
||||
- [ ] 验证测试通过
|
||||
|
||||
---
|
||||
|
||||
### 任务 4: 排查流程图文档化
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #86 |
|
||||
| **优先级** | P1 |
|
||||
| **类型** | 文档完善 |
|
||||
| **描述** | 把 Mermaid 流程图从代码里剥离成可读文档 |
|
||||
| **估时** | 3小时 |
|
||||
|
||||
#### 输入项来源
|
||||
- **原型设计**: 排查流程原型
|
||||
- **技术架构**: 代码中的 Mermaid 图表
|
||||
- **项目看板**: 文档完善任务
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 排查流程图文档 | 文档 |
|
||||
| 2 | 更新架构图索引 | 文档 |
|
||||
|
||||
#### 验证方式
|
||||
- [ ] 文档可读性检查
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 流程图文档完整
|
||||
- [ ] 索引已更新
|
||||
|
||||
---
|
||||
|
||||
### 任务 5: pytest 测试失败修复
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #92 |
|
||||
| **优先级** | P1 |
|
||||
| **类型** | 测试修复 |
|
||||
| **描述** | 修复 v0.7.1-dev 引入的 pytest 失败(当前 64 个 pre-existing 失败) |
|
||||
| **根因** | conftest.py SQLite StaticPool 性能 + Windows + utf-8 + asyncio loop 顺序问题 |
|
||||
| **估时** | 4小时 |
|
||||
|
||||
#### 输入项来源
|
||||
- **项目看板**: 测试修复任务
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 修复后的 conftest.py | 代码 |
|
||||
| 2 | 测试通过报告 | 文档 |
|
||||
|
||||
#### 验证方式
|
||||
- [ ] pytest 运行通过
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 所有测试通过
|
||||
|
||||
---
|
||||
|
||||
### 任务 6: 敏感词检测 + 语气优化(⏸️ 延后)
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #81 |
|
||||
| **优先级** | P0 → ⏸️ 延后 |
|
||||
| **类型** | 功能开发 |
|
||||
| **描述** | v0.7.1 开发内容,文本安全过滤 |
|
||||
| **阻塞原因** | 需确认企业敏感词库来源 |
|
||||
| **估时** | 待评估 |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: PRD 安全要求
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 敏感词过滤服务 | 代码 |
|
||||
| 2 | 敏感词库配置 | 配置 |
|
||||
|
||||
#### 验证方式
|
||||
- [ ] 敏感词拦截测试
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 敏感词库已配置
|
||||
- [ ] 过滤功能正常
|
||||
|
||||
---
|
||||
|
||||
## 📊 任务统计
|
||||
|
||||
| 优先级 | 数量 | 估时 |
|
||||
|--------|------|------|
|
||||
| P0 | 2 | 待评估 |
|
||||
| P1 | 5 | ~10小时 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准总览
|
||||
|
||||
### 代码规范
|
||||
- [ ] 遵循项目代码规范
|
||||
- [ ] 通过 ESLint / Pylint 检查
|
||||
|
||||
### 测试要求
|
||||
- [ ] 单元测试覆盖率 ≥ 80%
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 安全测试通过
|
||||
|
||||
### 文档要求
|
||||
- [ ] 相关技术文档已更新
|
||||
- [ ] API 接口文档已更新
|
||||
|
||||
### 交付要求
|
||||
- [ ] 代码合入主干分支
|
||||
- [ ] 通过 Code Review
|
||||
- [ ] 任务看板已更新
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 |
|
||||
|------|----------|--------|
|
||||
| 2026-07-04 | 创建任务说明书 | Claude |
|
||||
| 2026-07-04 | 更新登录逻辑说明 | Claude |
|
||||
| 2026-07-04 | 添加模板化字段 | Claude |
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
# 优先级最高卡点任务说明书
|
||||
|
||||
> **版本**: v1.2 | **日期**: 2026-07-04 | **状态**: 🔴 进行中
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 优先级卡点任务 |
|
||||
| **任务ID** | #90 等 |
|
||||
| **优先级** | 🔴P0 / 🟠P1 |
|
||||
| **类型** | 功能开发 / Bug修复 |
|
||||
| **状态** | 进行中 / 延后 |
|
||||
| **负责人** | 宋献 + Claude |
|
||||
| **创建日期** | 2026-07-04 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 说明
|
||||
|
||||
以下任务是当前项目中**优先级最高**但**遇到阻塞卡点**的任务,需要优先解决才能推进项目进度。
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/02-产品需求文档PRD-v1.2-20260704.md` | §4.5 坐席/管理员登录流程 | 登录逻辑调整 |
|
||||
| `02-产品需求/02-产品需求文档PRD-v1.2-20260704.md` | v1.5 更新说明 | 登录方式变更 |
|
||||
|
||||
### 技术架构
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `03-技术架构/02-技术方案/` | - | 相关技术方案 |
|
||||
|
||||
### 原型设计
|
||||
| 来源文档 | 页面 | 说明 |
|
||||
|----------|------|------|
|
||||
| `04-原型设计/prototypes-原型图/admin-dashboard-v1.html` | 管理后台登录 | 登录页面UI |
|
||||
| `04-原型设计/prototypes-原型图/agent-workspace-v5_4.html` | 坐席工作台 | 登录后页面 |
|
||||
|
||||
### 项目看板
|
||||
| 来源 | 任务名 | 说明 |
|
||||
|------|--------|------|
|
||||
| `05-项目状态看板/01-项目状态看板.md` | P0任务 | 当前阻塞任务 |
|
||||
|
||||
---
|
||||
|
||||
## 📢 需求变更(2026-07-04)
|
||||
|
||||
根据 PRD v1.5 更新,登录逻辑已调整:
|
||||
|
||||
| 角色 | 登录方式 | 说明 |
|
||||
|------|----------|------|
|
||||
| **用户端 (H5)** | 企微内嵌打开 | 强制企微内嵌,OAuth2 静默授权 |
|
||||
| **坐席端 (Agent)** | 浏览器直接打开 | 无需经过企微工作台,支持账号密码+OTP |
|
||||
| **管理端 (Admin)** | 浏览器直接打开 | 无需经过企微工作台,支持账号密码+OTP |
|
||||
|
||||
> **核心变更**:坐席/管理员无需经过企微工作台,可直接在浏览器打开登录页面
|
||||
|
||||
---
|
||||
|
||||
## 🎯 当前任务(按新登录逻辑)
|
||||
|
||||
---
|
||||
|
||||
### 任务 1: 坐席/管理端登录验证(🔴 最优先)
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #90 |
|
||||
| **优先级** | 🔴 P0 |
|
||||
| **当前状态** | 🔧 开发中 |
|
||||
| **功能描述** | 坐席/管理端浏览器直接登录,支持账号密码+OTP认证 |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: PRD v1.5 §4.5 登录流程
|
||||
- **原型设计**: admin-dashboard-v1.html 登录页
|
||||
- **项目看板**: P0任务
|
||||
|
||||
#### 登录流程
|
||||
1. 坐席/管理员直接在浏览器打开 `/itagent/` 或 `/itadmin/`
|
||||
2. 输入账号密码 + OTP 验证码
|
||||
3. 验证通过后进入对应工作台
|
||||
|
||||
#### 输出成果要求
|
||||
|
||||
| # | 交付物 | 类型 |
|
||||
|---|--------|------|
|
||||
| 1 | 后端登录API | 代码 |
|
||||
| 2 | 坐席端登录页 | 代码 |
|
||||
| 3 | 管理端登录页 | 代码 |
|
||||
| 4 | OTP验证逻辑 | 代码 |
|
||||
|
||||
#### 验证方式
|
||||
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 坐席登录 | 手动测试 | 登录成功进入工作台 |
|
||||
| 管理登录 | 手动测试 | 登录成功进入后台 |
|
||||
| 权限隔离 | 越权测试 | 坐席无法访问管理端 |
|
||||
| OTP验证 | 验证码测试 | 错误验证码被拦截 |
|
||||
|
||||
#### 完成标准
|
||||
|
||||
- [ ] 后端登录API开发完成
|
||||
- [ ] 坐席端登录页面完成
|
||||
- [ ] 管理端登录页面完成
|
||||
- [ ] OTP验证正常工作
|
||||
- [ ] 权限控制正确
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 代码通过 Code Review
|
||||
|
||||
---
|
||||
|
||||
## ⏸️ 延后任务(暂不处理)
|
||||
|
||||
### 延后 1: IP 白名单收窄
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #48 |
|
||||
| **优先级** | 🔴 P0 → ⏸️ 延后 |
|
||||
| **原因** | 需网络组确认真实代理 IP 段(WAF/堡垒机/CDN 出口 IP) |
|
||||
| **状态** | 延后,待网络组确认后重启 |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: 安全合规要求
|
||||
- **技术架构**: nginx 配置
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 网络组确认IP段
|
||||
- [ ] nginx配置更新
|
||||
- [ ] 验证通过
|
||||
|
||||
---
|
||||
|
||||
### 延后 2: 敏感词检测功能
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #81 |
|
||||
| **优先级** | 🔴 P0 → ⏸️ 延后 |
|
||||
| **原因** | 需确认企业敏感词库来源 |
|
||||
| **状态** | 延后,待确认词库来源后重启 |
|
||||
|
||||
#### 输入项来源
|
||||
- **产品需求**: PRD 安全要求
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 确认敏感词库来源
|
||||
- [ ] 词库配置完成
|
||||
- [ ] 过滤功能测试通过
|
||||
|
||||
---
|
||||
|
||||
### 延后 3: 后端文件部署覆盖
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **ID** | #73 |
|
||||
| **优先级** | 🟠 P1 → ⏸️ 延后 |
|
||||
| **原因** | 部署脚本优化 |
|
||||
| **状态** | 延后 |
|
||||
|
||||
#### 输入项来源
|
||||
- **技术架构**: 部署流程
|
||||
|
||||
#### 完成标准
|
||||
- [ ] 脚本优化完成
|
||||
- [ ] 覆盖验证通过
|
||||
|
||||
---
|
||||
|
||||
## 📊 当前任务状态
|
||||
|
||||
| 任务 | 优先级 | 状态 | 输入来源 |
|
||||
|------|--------|------|----------|
|
||||
| 登录流程验证 | 🔴 P0 | 进行中 | PRD v1.5、原型设计、项目看板 |
|
||||
| IP 白名单 | 🔴 P0 | 延后 | 安全合规、技术架构 |
|
||||
| 敏感词检测 | 🔴 P0 | 延后 | PRD 安全要求 |
|
||||
| 部署脚本优化 | 🟠 P1 | 延后 | 技术架构 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准总览
|
||||
|
||||
### 代码规范
|
||||
- [ ] 遵循项目代码规范
|
||||
- [ ] 通过 ESLint / Pylint 检查
|
||||
|
||||
### 测试要求
|
||||
- [ ] 单元测试新增/修复完成
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 安全测试通过
|
||||
|
||||
### 文档要求
|
||||
- [ ] API 接口文档已更新
|
||||
- [ ] 相关技术文档已更新
|
||||
|
||||
### 交付要求
|
||||
- [ ] 代码合入主干分支
|
||||
- [ ] 通过 Code Review
|
||||
- [ ] 任务看板已更新
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 |
|
||||
|------|----------|--------|
|
||||
| 2026-07-04 | 创建任务说明书 | Claude |
|
||||
| 2026-07-04 | 添加需求变更说明 | Claude |
|
||||
| 2026-07-04 | 添加模板化字段 | Claude |
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# 任务说明书 - 摇人消息推送到通知栏Bug修复
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-10
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 摇人消息推送到通知栏Bug修复 |
|
||||
| **任务ID** | #105 |
|
||||
| **优先级** | 🟠 P1 |
|
||||
| **类型** | Bug修复 |
|
||||
| **状态** | ✅ 已完成 |
|
||||
| **负责人** | 助理 |
|
||||
| **创建日期** | 2026-07-10 |
|
||||
| **计划完成日期** | 2026-07-10 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 问题描述
|
||||
| 来源 | 描述 |
|
||||
|------|------|
|
||||
| 用户反馈 | 2026-07-10 07:28:53 摇人功能触发后,系统消息"大哥,俺这就去摇人,稍等..."和"人摇来了!IT坐席为您服务"出现在企微应用通知消息中,按理只需显示在员工端会话页面 |
|
||||
|
||||
### 问题定位
|
||||
| 文件 | 行号 | 问题 |
|
||||
|------|------|------|
|
||||
| `backend/app/api/h5.py` | 1169-1174 | shake函数错误调用wecom_service.send_text_message推送企微消息 |
|
||||
| `backend/app/api/h5.py` | 1335-1340 | call_agent函数错误调用wecom_service.send_text_message推送企微消息 |
|
||||
|
||||
---
|
||||
|
||||
## 📤 输出成果要求
|
||||
|
||||
### 交付物清单
|
||||
|
||||
| # | 交付物 | 类型 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | h5.py代码修复 | 代码 | 删除两处企微消息推送调用 |
|
||||
| 2 | 部署验证 | 部署 | 部署到测试环境验证 |
|
||||
|
||||
### 代码修改
|
||||
- `backend/app/api/h5.py`:
|
||||
- 第1169-1174行:删除shake函数的wecom_service.send_text_message调用
|
||||
- 第1335-1340行:删除call_agent函数的wecom_service.send_text_message调用
|
||||
|
||||
---
|
||||
|
||||
## 🔧 验证方式
|
||||
|
||||
### 功能验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 摇人功能 | 员工端点击摇人按钮 | 系统消息仅在H5页面内展示,不出现在企微通知 |
|
||||
| 举手功能 | 员工端点击举手按钮 | 系统消息仅在H5页面内展示,不出现在企微通知 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准
|
||||
|
||||
### 验收条件
|
||||
|
||||
- [x] 代码已修复
|
||||
- [x] 测试环境部署验证通过
|
||||
- [x] 项目管理主文档已更新
|
||||
|
||||
---
|
||||
|
||||
## 📞 依赖与阻塞
|
||||
|
||||
### 前置依赖
|
||||
无
|
||||
|
||||
### 阻塞因素
|
||||
无
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 | 说明 |
|
||||
|------|----------|--------|------|
|
||||
| 2026-07-10 | 创建任务 | 助理 | 初始版本 |
|
||||
| 2026-07-10 | 代码已修复 | 助理 | 删除两处企微消息推送调用 |
|
||||
|
||||
---
|
||||
|
||||
## 📎 附件
|
||||
|
||||
- 问题反馈:`backend/app/api/h5.py`
|
||||
@@ -1,140 +0,0 @@
|
||||
# 任务说明书:消息推送策略优化与超时提醒
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-05
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 消息推送策略优化与超时提醒 |
|
||||
| **任务ID** | #100 |
|
||||
| **优先级** | 🟠 P1 |
|
||||
| **类型** | 功能开发 |
|
||||
| **状态** | ✅ 已完成 |
|
||||
| **负责人** | 宋献 |
|
||||
| **创建日期** | 2026-07-05 |
|
||||
| **计划完成日期** | 待定 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/04-技术方案-消息推送策略优化与超时提醒.md` | 全文 | 技术方案文档 |
|
||||
|
||||
### 技术架构
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `backend/app/api/messages.py` | send_message 函数 | 现有消息发送逻辑 |
|
||||
| `backend/app/models/conversation.py` | Conversation 模型 | 会话数据模型 |
|
||||
|
||||
### 项目看板
|
||||
| 来源 | 任务名 | 说明 |
|
||||
|------|--------|------|
|
||||
| 用户反馈 | 消息推送策略 | 坐席回复不应出现在企微应用消息列表 |
|
||||
|
||||
---
|
||||
|
||||
## 📤 输出成果要求
|
||||
|
||||
### 交付物清单
|
||||
|
||||
| # | 交付物 | 类型 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | 数据库迁移脚本 | SQL | conversations 表新增 4 个字段 |
|
||||
| 2 | 提醒服务 | Python | `backend/app/services/reminder_service.py` |
|
||||
| 3 | 定时任务 | Python | `backend/app/tasks/reminder_task.py` |
|
||||
| 4 | 消息发送逻辑修改 | Python | 移除企微 API 调用,仅走 WebSocket |
|
||||
| 5 | 部署验证 | - | 生产环境测试通过 |
|
||||
|
||||
### 代码要求
|
||||
- 遵循项目代码规范
|
||||
- 所有新增代码通过 Pylint 检查
|
||||
- 单元测试覆盖新增逻辑
|
||||
|
||||
### 文档要求
|
||||
- 更新本任务说明书状态
|
||||
- 更新项目状态看板
|
||||
|
||||
---
|
||||
|
||||
## 🔧 验证方式
|
||||
|
||||
### 功能验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 坐席发送消息 | 坐席回复用户消息 | 仅出现在 H5 页面,不出现在企微应用消息 |
|
||||
| 超时提醒 | 坐席回复后等待 3 分钟 | 收到企微提醒消息 |
|
||||
| 提醒只发一次 | 再次等待 3 分钟 | 不再收到提醒 |
|
||||
| 待关闭状态 | 坐席回复后等待 10 分钟 | 会话状态变为 pending_close |
|
||||
|
||||
### 安全验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 权限控制 | 非坐席无法触发 | 仅坐席回复触发逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准
|
||||
|
||||
### 验收条件
|
||||
|
||||
- [ ] 代码合入主干分支
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 部署验证通过
|
||||
|
||||
### 产出确认
|
||||
|
||||
- [ ] 数据库迁移完成
|
||||
- [ ] 后端代码修改完成
|
||||
- [ ] 定时任务运行正常
|
||||
- [ ] 生产环境验证通过
|
||||
|
||||
---
|
||||
|
||||
## 📊 工作分解
|
||||
|
||||
### 子任务
|
||||
|
||||
| 子任务 | 负责人 | 预估工时 | 状态 |
|
||||
|--------|--------|----------|------|
|
||||
| T1. 数据库迁移 | 宋献 | 0.5h | 待开始 |
|
||||
| T2. 消息发送逻辑修改 | 宋献 | 0.5h | 待开始 |
|
||||
| T3. 新建提醒服务 | 宋献 | 1h | 待开始 |
|
||||
| T4. 新建定时任务 | 宋献 | 1h | 待开始 |
|
||||
| T5. 定时任务注册 | 宋献 | 0.5h | 待开始 |
|
||||
| T6. 部署测试 | 宋献 | 1h | 待开始 |
|
||||
|
||||
**总计**:约 4.5 小时
|
||||
|
||||
---
|
||||
|
||||
## 📞 依赖与阻塞
|
||||
|
||||
### 前置依赖
|
||||
| 依赖任务 | 依赖说明 | 状态 |
|
||||
|----------|----------|------|
|
||||
| 无 | 独立任务 | - |
|
||||
|
||||
### 阻塞因素
|
||||
| 阻塞项 | 影响范围 | 解决方案 |
|
||||
|--------|----------|-----------|
|
||||
| 无 | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 | 说明 |
|
||||
|------|----------|--------|------|
|
||||
| 2026-07-05 | 创建任务 | 宋献 | 初始版本 |
|
||||
|
||||
---
|
||||
|
||||
## 📎 附件
|
||||
|
||||
- 技术方案:`docs/03-技术架构/02-技术方案/技术方案-消息推送策略优化与超时提醒.md`
|
||||
@@ -0,0 +1,121 @@
|
||||
# 任务说明书 — 企微模板卡片消息
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-10
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 企微模板卡片消息样式升级 |
|
||||
| **任务ID** | #76 |
|
||||
| **优先级** | 🟡 P2 |
|
||||
| **类型** | 功能开发 |
|
||||
| **状态** | 已完成 |
|
||||
| **负责人** | 开发团队 |
|
||||
| **创建日期** | 2026-07-10 |
|
||||
| **计划完成日期** | 2026-07-10 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/IT智能服务台-产品需求文档PRD-v2.md` | §3.新增需求 | 超时提醒消息样式升级 |
|
||||
|
||||
### 技术架构
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| 企微开发者文档 | 模板卡片消息 | text_notice 类型实现 |
|
||||
|
||||
---
|
||||
|
||||
## 📤 输出成果要求
|
||||
|
||||
### 交付物清单
|
||||
|
||||
| # | 交付物 | 类型 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | `app/services/wecom_service.py` | 代码 | 新增 `send_template_card_message()` 方法 |
|
||||
| 2 | `app/services/reminder_service.py` | 代码 | 改用模板卡片发送超时提醒 |
|
||||
|
||||
### 代码要求
|
||||
- 遵循项目代码规范
|
||||
- 异步方法设计,与现有 `send_card_message` 保持一致
|
||||
|
||||
### 文档要求
|
||||
- 本任务说明书
|
||||
- 更新产品需求文档
|
||||
|
||||
---
|
||||
|
||||
## 🔧 验证方式
|
||||
|
||||
### 功能验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 模板卡片发送成功 | 触发超时提醒 | 企微收到卡片消息 |
|
||||
| 跳转按钮可用 | 点击按钮 | 打开 IT 服务台页面 |
|
||||
| 关键数据高亮 | 查看消息 | 显示 "10分钟 剩余处理时间" |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准
|
||||
|
||||
### 验收条件
|
||||
|
||||
- [x] 代码合入主干分支
|
||||
- [x] 功能开发完成
|
||||
- [x] 文档已更新
|
||||
|
||||
### 产出确认
|
||||
|
||||
- [x] `wecom_service.py` 新增方法
|
||||
- [x] `reminder_service.py` 调用模板卡片接口
|
||||
- [x] 任务书已创建
|
||||
- [x] PRD 已更新
|
||||
|
||||
---
|
||||
|
||||
## 📊 工作分解
|
||||
|
||||
### 子任务
|
||||
|
||||
| 子任务 | 负责人 | 预估工时 | 状态 |
|
||||
|--------|--------|----------|------|
|
||||
| 新增 send_template_card_message 方法 | 开发 | 0.5h | ✅ |
|
||||
| 改造 reminder_service 调用 | 开发 | 0.5h | ✅ |
|
||||
| 文档补充 | 开发 | 0.5h | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 📞 依赖与阻塞
|
||||
|
||||
### 前置依赖
|
||||
| 依赖任务 | 依赖说明 | 状态 |
|
||||
|----------|----------|------|
|
||||
| 无 | 独立功能 | - |
|
||||
|
||||
### 阻塞因素
|
||||
| 阻塞项 | 影响范围 | 解决方案 |
|
||||
|--------|----------|-----------|
|
||||
| 无 | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 | 说明 |
|
||||
|------|----------|--------|------|
|
||||
| 2026-07-10 | 创建任务 | 开发 | 初始版本 |
|
||||
| 2026-07-10 | 代码开发完成 | 开发 | 实现模板卡片发送 |
|
||||
| 2026-07-10 | 文档补充 | 开发 | 补充任务书和PRD |
|
||||
|
||||
---
|
||||
|
||||
## 📎 附件
|
||||
|
||||
- 企微模板卡片文档:https://developer.work.weixin.qq.com/document/path/101032
|
||||
@@ -0,0 +1,646 @@
|
||||
# 任务说明书 — 后端部署卷挂载改造
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-10
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 后端部署架构改造:镜像烘焙 → 代码卷挂载 |
|
||||
| **任务ID** | #107 |
|
||||
| **优先级** | 🟠 P1 |
|
||||
| **类型** | 部署优化 |
|
||||
| **状态** | 待开始 |
|
||||
| **负责人** | 宋献 |
|
||||
| **创建日期** | 2026-07-10 |
|
||||
| **计划完成日期** | 2026-07-11 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| 无 | — | 运维需求,非产品功能 |
|
||||
|
||||
### 技术架构
|
||||
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `03-技术架构/IT智能服务台-系统架构设计文档v2.md` | §5.0 部署模式演进 | 方案 C 设计说明 |
|
||||
| `09-部署运维/卷挂载重构方案.md` | 全文 | 完整 8 章节方案(架构师高见远产出) |
|
||||
| `09-部署运维/00-标准故障排查手册.md` | §1.4 + CASE-20260710-02 | 部署前同步检查清单 + 镜像缺文件案例 |
|
||||
|
||||
### 事故背景
|
||||
|
||||
| 日期 | 事故 | 根因 |
|
||||
|------|------|------|
|
||||
| 2026-07-07 | 认证路由缺失 | Docker 镜像未重新构建 |
|
||||
| 2026-07-10 | auth.py 缺失导致认证全断 | 镜像从 backend/app/(旧代码)构建,两份代码不同步 |
|
||||
|
||||
**共同根因**:代码通过 `COPY . .` 烘焙进镜像,服务器两份代码不同步导致构建出缺文件的镜像。
|
||||
|
||||
---
|
||||
|
||||
## 📤 输出成果要求
|
||||
|
||||
### 交付物清单
|
||||
|
||||
| # | 交付物 | 类型 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | `backend/Dockerfile` | 配置 | 删除 `COPY . .`,新增 `ENV PYTHONDONTWRITEBYTECODE=1` |
|
||||
| 2 | `docker-compose.yml` | 配置 | backend 服务 volumes 新增 `./app:/app/app` |
|
||||
| 3 | 服务器代码目录调整 | 运维 | `app/` 成为唯一代码源,`backend/app/` 保留 48h 后删除 |
|
||||
| 4 | 部署验证通过 | 验证 | 健康检查 + auth 模块 + 卷挂载 + 代码一致性 |
|
||||
|
||||
### 代码要求
|
||||
|
||||
- Dockerfile 变更:仅删除 `COPY . .`(第 53 行),新增 `ENV PYTHONDONTWRITEBYTECODE=1`,其余不变
|
||||
- docker-compose.yml 变更:backend 服务 volumes 段新增一行 `./app:/app/app`,插入到 `backend-uploads` 行之前
|
||||
- 不涉及任何 Python 业务代码变更
|
||||
|
||||
### 文档要求
|
||||
|
||||
- 架构设计文档已更新(§5.0 部署模式演进,v2.1)
|
||||
- 项目管理主文档已更新(看板新增 #107)
|
||||
- 完整方案文档已归档:`docs/09-部署运维/卷挂载重构方案.md`
|
||||
|
||||
---
|
||||
|
||||
## 🔧 验证方式
|
||||
|
||||
### 功能验证
|
||||
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 容器运行状态 | `docker compose ps backend` | Status 为 `Up (healthy)` |
|
||||
| 健康检查 | `curl -sf http://localhost:8000/health` | 返回 `{"status":"healthy"}` 或类似 |
|
||||
| **Auth 模块** | `docker exec wecom_it_backend python -c "from app.auth import router; print('OK')"` | 输出 `OK`(曾因缺失导致故障) |
|
||||
| 卷挂载 | `docker exec wecom_it_backend ls -la /app/app/main.py` | 文件存在且可读 |
|
||||
| 代码一致性 | `md5sum` 对比宿主机与容器内 `main.py` | md5 值一致 |
|
||||
| 日志检查 | `docker compose logs --tail=50 backend` | 无 `ModuleNotFoundError` / `ImportError` |
|
||||
|
||||
### 安全验证
|
||||
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| `COPY . .` 已移除 | `grep -c "COPY . ." backend/Dockerfile` | 返回 0 |
|
||||
| 卷挂载已添加 | `grep "app:/app/app" docker-compose.yml` | 返回匹配 |
|
||||
| `__pycache__` 禁止 | `docker exec wecom_it_backend python -c "import sys; print(sys.dont_write_bytecode)"` | 输出 `True` |
|
||||
|
||||
### 性能验证
|
||||
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 容器重启速度 | 部署后 `docker compose restart backend` + `time` 计时 | < 15 秒(此前需 4-6 分钟) |
|
||||
| 健康检查就绪 | 重启后 `curl /health` 轮询 | 15 秒内就绪 |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 回滚策略(CRITICAL)
|
||||
|
||||
### 回滚触发条件
|
||||
|
||||
满足以下 **任一** 条件即触发回滚:
|
||||
|
||||
| # | 触发条件 | 检测方法 |
|
||||
|---|----------|----------|
|
||||
| 1 | 容器启动失败(反复重启) | `docker compose ps backend` 状态为 `restarting` 或 `unhealthy` |
|
||||
| 2 | 健康检查连续失败 | `curl -sf http://localhost:8000/health` 返回非 200 |
|
||||
| 3 | 关键模块导入失败(如 auth) | `docker exec wecom_it_backend python -c "from app.auth import router"` 报错 |
|
||||
| 4 | 卷挂载路径不存在或权限拒绝 | 容器日志出现 `ModuleNotFoundError` 或 `PermissionError` |
|
||||
| 5 | 业务接口大面积 500 错误 | Nginx 日志或后端日志大量 500 状态码 |
|
||||
|
||||
### 回滚步骤(可通过 jumpserver-ops 执行)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# 回滚脚本:卷挂载方案 → 镜像烘焙方案
|
||||
# 执行方式:通过 jumpserver-ops 在 10.90.5.110 上执行
|
||||
# 前提:备份文件存在(部署时已创建 .bak.{TIMESTAMP} 后缀文件)
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
echo "===== 回滚开始: $(date) ====="
|
||||
|
||||
# --- 步骤 1: 恢复备份的配置文件 ---
|
||||
echo ">>> [1/6] 恢复配置文件..."
|
||||
|
||||
COMPOSE_BAK=$(ls -t /opt/wecom-it-desk/docker-compose.yml.bak.* 2>/dev/null | head -1)
|
||||
if [ -z "$COMPOSE_BAK" ]; then
|
||||
echo "ERROR: 未找到 docker-compose.yml 备份文件!"
|
||||
echo "可手动从 git 恢复: git checkout -- docker-compose.yml"
|
||||
exit 1
|
||||
fi
|
||||
cp "$COMPOSE_BAK" /opt/wecom-it-desk/docker-compose.yml
|
||||
echo " 已恢复 docker-compose.yml <- $COMPOSE_BAK"
|
||||
|
||||
DOCKERFILE_BAK=$(ls -t /opt/wecom-it-desk/backend/Dockerfile.bak.* 2>/dev/null | head -1)
|
||||
if [ -z "$DOCKERFILE_BAK" ]; then
|
||||
echo "ERROR: 未找到 Dockerfile 备份文件!"
|
||||
echo "可手动从 git 恢复: git checkout -- backend/Dockerfile"
|
||||
exit 1
|
||||
fi
|
||||
cp "$DOCKERFILE_BAK" /opt/wecom-it-desk/backend/Dockerfile
|
||||
echo " 已恢复 Dockerfile <- $DOCKERFILE_BAK"
|
||||
|
||||
# --- 步骤 2: 确保 backend/app/ 存在(回滚安全网) ---
|
||||
echo ">>> [2/6] 检查 backend/app/ 目录..."
|
||||
|
||||
if [ ! -d /opt/wecom-it-desk/backend/app/ ] || [ -z "$(ls -A /opt/wecom-it-desk/backend/app/ 2>/dev/null)" ]; then
|
||||
echo " backend/app/ 不存在或为空,从 app/ 同步代码..."
|
||||
mkdir -p /opt/wecom-it-desk/backend/app/
|
||||
cp -r /opt/wecom-it-desk/app/* /opt/wecom-it-desk/backend/app/
|
||||
cp -r /opt/wecom-it-desk/app/.* /opt/wecom-it-desk/backend/app/ 2>/dev/null || true
|
||||
echo " 已同步代码到 backend/app/"
|
||||
else
|
||||
echo " backend/app/ 已存在,跳过同步"
|
||||
fi
|
||||
|
||||
# --- 步骤 3: 重新构建镜像(使用原始 Dockerfile,含 COPY . .) ---
|
||||
echo ">>> [3/6] 重新构建后端镜像..."
|
||||
docker compose build --no-cache backend
|
||||
|
||||
# --- 步骤 4: 重启容器 ---
|
||||
echo ">>> [4/6] 重启后端容器..."
|
||||
docker compose up -d backend
|
||||
|
||||
# --- 步骤 5: 等待服务就绪 ---
|
||||
echo ">>> [5/6] 等待服务启动..."
|
||||
echo " 等待 45 秒(healthcheck start_period)..."
|
||||
sleep 45
|
||||
|
||||
# --- 步骤 6: 验证 ---
|
||||
echo ">>> [6/6] 验证回滚结果..."
|
||||
|
||||
echo "--- 容器状态 ---"
|
||||
docker compose ps backend
|
||||
|
||||
echo "--- 健康检查 ---"
|
||||
if curl -sf http://localhost:8000/health > /dev/null 2>&1; then
|
||||
echo " PASS: /health 返回正常"
|
||||
else
|
||||
echo " WARN: /health 未就绪,再等待 15 秒..."
|
||||
sleep 15
|
||||
if curl -sf http://localhost:8000/health > /dev/null 2>&1; then
|
||||
echo " PASS: /health 返回正常(延迟就绪)"
|
||||
else
|
||||
echo " FAIL: /health 仍然失败"
|
||||
echo " 查看日志: docker compose logs --tail=50 backend"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "--- Auth 模块验证 ---"
|
||||
if docker exec wecom_it_backend python -c "from app.auth import router; print('auth OK')" 2>/dev/null; then
|
||||
echo " PASS: auth 模块可导入"
|
||||
else
|
||||
echo " FAIL: auth 模块导入失败"
|
||||
echo " 查看日志: docker compose logs --tail=50 backend"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "===== 回滚完成: $(date) ====="
|
||||
echo ""
|
||||
echo "如回滚后仍有问题,请检查:"
|
||||
echo " 1. backend/app/ 代码是否完整: ls -la /opt/wecom-it-desk/backend/app/"
|
||||
echo " 2. 镜像构建是否成功: docker images | grep wecom-it-desk-backend"
|
||||
echo " 3. 容器日志: docker compose logs -f backend"
|
||||
```
|
||||
|
||||
### 回滚后验证
|
||||
|
||||
| 验证项 | 命令 | 预期结果 |
|
||||
|--------|------|----------|
|
||||
| 容器运行状态 | `docker compose ps backend` | Status 为 `Up (healthy)` |
|
||||
| 健康检查 | `curl -sf http://localhost:8000/health` | 返回正常 |
|
||||
| Auth 模块 | `docker exec wecom_it_backend python -c "from app.auth import router; print('OK')"` | 输出 `OK` |
|
||||
| Nginx 代理 | `curl -sf http://localhost:80/itdesk/health` | 返回正常 |
|
||||
| 日志无异常 | `docker compose logs --tail=50 backend` | 无 `ModuleNotFoundError` / `ImportError` |
|
||||
|
||||
### 回滚时间预估
|
||||
|
||||
| 步骤 | 耗时 |
|
||||
|------|------|
|
||||
| 恢复配置文件 | 5 秒 |
|
||||
| 检查/同步 backend/app/ | 5-30 秒 |
|
||||
| 重建镜像 | 2-4 分钟 |
|
||||
| 重启容器 | 10 秒 |
|
||||
| 等待就绪 | 45 秒 |
|
||||
| 验证 | 15 秒 |
|
||||
| **总计** | **3.5-5.5 分钟** |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准
|
||||
|
||||
### 验收条件
|
||||
|
||||
- [ ] Dockerfile 已删除 `COPY . .`,已新增 `PYTHONDONTWRITEBYTECODE=1`
|
||||
- [ ] docker-compose.yml 已新增 `./app:/app/app` 卷挂载
|
||||
- [ ] 镜像已重建并重启成功
|
||||
- [ ] 健康检查通过(`/health` 返回正常)
|
||||
- [ ] Auth 模块可导入(`from app.auth import router` 成功)
|
||||
- [ ] 卷挂载验证通过(容器内 `/app/app/main.py` 可访问)
|
||||
- [ ] 代码一致性验证通过(宿主机与容器 md5 一致)
|
||||
- [ ] 日志无 `ModuleNotFoundError` / `ImportError`
|
||||
- [ ] 部署 48 小时后 `backend/app/` 已清理
|
||||
- [ ] 文档已更新(架构设计文档 v2.1、项目管理主文档 v2.1)
|
||||
|
||||
### 产出确认
|
||||
|
||||
- [ ] 服务器 Dockerfile 已更新
|
||||
- [ ] 服务器 docker-compose.yml 已更新
|
||||
- [ ] 镜像重建成功
|
||||
- [ ] 容器运行正常
|
||||
- [ ] 回滚脚本已验证可用
|
||||
- [ ] 备份文件已创建(`.bak.{TIMESTAMP}`)
|
||||
- [ ] `.rollback-info` 文件已记录
|
||||
|
||||
---
|
||||
|
||||
## 📊 工作分解
|
||||
|
||||
### 子任务
|
||||
|
||||
| 子任务 | 负责人 | 预估工时 | 状态 | 依赖 |
|
||||
|--------|--------|----------|------|------|
|
||||
| S1: 前置验证与备份 | 宋献 | 2 分钟 | 待开始 | 无 |
|
||||
| S2: 代码同步与验证 | 宋献 | 1 分钟 | 待开始 | S1 |
|
||||
| S3: 修改 Dockerfile | 宋献 | 1 分钟 | 待开始 | S2 |
|
||||
| S4: 修改 docker-compose.yml | 宋献 | 1 分钟 | 待开始 | S3 |
|
||||
| S5: 重建镜像并重启 | 宋献 | 3 分钟 | 待开始 | S4 |
|
||||
| S6: 部署后验证 | 宋献 | 2 分钟 | 待开始 | S5 |
|
||||
| S7: 清理 backend/app/(48h 后) | 宋献 | 1 分钟 | 待开始 | S6 + 48h |
|
||||
|
||||
### 预估总时间
|
||||
|
||||
| 阶段 | 步骤 | 耗时 |
|
||||
|------|------|------|
|
||||
| 准备 | S1 + S2 | 3 分钟 |
|
||||
| 变更 | S3 + S4 | 2 分钟 |
|
||||
| 部署 | S5 | 3 分钟 |
|
||||
| 验证 | S6 | 2 分钟 |
|
||||
| **总计** | S1-S6 | **约 10 分钟** |
|
||||
| 清理 | S7(48h 后) | 1 分钟 |
|
||||
| **回滚(如需)** | 回滚脚本 | **3.5-5.5 分钟** |
|
||||
|
||||
---
|
||||
|
||||
## 📞 依赖与阻塞
|
||||
|
||||
### 前置依赖
|
||||
|
||||
| 依赖任务 | 依赖说明 | 状态 |
|
||||
|----------|----------|------|
|
||||
| 无 | 独立运维任务 | — |
|
||||
|
||||
### 阻塞因素
|
||||
|
||||
| 阻塞项 | 影响范围 | 解决方案 |
|
||||
|--------|----------|-----------|
|
||||
| 无 | — | — |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 风险评估
|
||||
|
||||
| # | 风险 | 概率 | 等级 | 对策 |
|
||||
|---|------|------|------|------|
|
||||
| R1 | `__pycache__` 污染宿主机代码目录 | 中 | 中 | Dockerfile 设置 `PYTHONDONTWRITEBYTECODE=1` |
|
||||
| R2 | 宿主机代码被意外修改导致运行中服务异常 | 低 | 中 | 生产不启用 `--reload`;限制目录写权限 |
|
||||
| R3 | `backend/app/` 被提前删除导致回滚失败 | 低 | 高 | 48 小时内不删除;回滚脚本含自动同步逻辑 |
|
||||
| R4 | requirements.txt 与代码不同步 | 低 | 中 | 部署前 diff 对比;新增依赖时先重建镜像 |
|
||||
| R5 | 卷挂载路径与现有挂载冲突 | 极低 | 低 | `/app/app` 与 `/app/uploads`、`/app/logs` 无交集 |
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 | 说明 |
|
||||
|------|----------|--------|------|
|
||||
| 2026-07-10 | 创建任务 | 宋献 | 初始版本,基于架构师高见远的卷挂载重构方案 |
|
||||
|
||||
---
|
||||
|
||||
## 📎 附件
|
||||
|
||||
- **完整方案文档**:`docs/09-部署运维/卷挂载重构方案.md`(含完整命令块、时序图、风险评估)
|
||||
- **架构设计文档**:`docs/03-技术架构/IT智能服务台-系统架构设计文档v2.md` §5.0
|
||||
- **故障排查手册**:`docs/09-部署运维/00-标准故障排查手册.md` §1.4 + CASE-20260710-02
|
||||
- **deploy-troubleshoot skill**:`~/.workbuddy/skills/deploy-troubleshoot/SKILL.md` Step -1 部署前同步检查
|
||||
- **task-intake skill**:`.workbuddy/skills/task-intake/SKILL.md` Step 3.1 部署运维前置检查
|
||||
|
||||
---
|
||||
|
||||
## 📝 完整部署命令块
|
||||
|
||||
以下命令可通过 jumpserver-ops 在服务器 10.90.5.110 上按步骤执行。
|
||||
|
||||
### S1: 前置验证与备份
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
# 1. 验证当前服务正常
|
||||
echo ">>> 验证当前服务状态..."
|
||||
curl -sf http://localhost:8000/health > /dev/null && echo " PASS: 当前服务正常" || { echo " FAIL: 当前服务异常,请先修复再部署"; exit 1; }
|
||||
|
||||
# 2. 备份配置文件
|
||||
BACKUP_TS=$(date +%Y%m%d%H%M%S)
|
||||
cp /opt/wecom-it-desk/docker-compose.yml /opt/wecom-it-desk/docker-compose.yml.bak.${BACKUP_TS}
|
||||
cp /opt/wecom-it-desk/backend/Dockerfile /opt/wecom-it-desk/backend/Dockerfile.bak.${BACKUP_TS}
|
||||
echo " PASS: 备份完成 (timestamp: ${BACKUP_TS})"
|
||||
|
||||
# 3. 记录回滚信息
|
||||
cat > /opt/wecom-it-desk/.rollback-info << EOF
|
||||
ROLLBACK_TIMESTAMP=${BACKUP_TS}
|
||||
COMPOSE_BAK=/opt/wecom-it-desk/docker-compose.yml.bak.${BACKUP_TS}
|
||||
DOCKERFILE_BAK=/opt/wecom-it-desk/backend/Dockerfile.bak.${BACKUP_TS}
|
||||
DEPLOY_DATE=$(date)
|
||||
EOF
|
||||
echo " PASS: 回滚信息已记录到 .rollback-info"
|
||||
echo ""
|
||||
echo "===== S1 完成 ====="
|
||||
```
|
||||
|
||||
### S2: 代码同步与验证
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
# 1. 验证 app/ 目录存在且包含关键文件
|
||||
echo ">>> 验证代码目录..."
|
||||
for f in app/__init__.py app/main.py app/config.py app/database.py; do
|
||||
if [ -f "$f" ]; then
|
||||
echo " PASS: $f 存在"
|
||||
else
|
||||
echo " FAIL: $f 不存在!请先解压部署包: tar -xf /tmp/deploy-backend.tar -C ./"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# 2. 验证 auth 模块(关键!曾因缺失导致故障)
|
||||
if [ -f "app/api/auth.py" ]; then
|
||||
echo " PASS: app/api/auth.py 存在"
|
||||
else
|
||||
echo " FAIL: app/api/auth.py 不存在!认证功能将不可用"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 统计代码文件数
|
||||
FILE_COUNT=$(find app/ -name "*.py" | wc -l)
|
||||
echo " INFO: app/ 目录共 ${FILE_COUNT} 个 Python 文件"
|
||||
|
||||
echo ""
|
||||
echo "===== S2 完成 ====="
|
||||
```
|
||||
|
||||
### S3: 修改 Dockerfile
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DOCKERFILE=/opt/wecom-it-desk/backend/Dockerfile
|
||||
|
||||
echo ">>> 修改 Dockerfile..."
|
||||
|
||||
# 直接写入完整文件(最可靠)
|
||||
cat > "$DOCKERFILE" << 'DOCKERFILE_EOF'
|
||||
# =============================================================================
|
||||
# 企微IT智能服务台 — 后端 Docker 镜像构建文件
|
||||
# =============================================================================
|
||||
# 说明:基于 Python 3.12 构建后端镜像
|
||||
# 变更:2025-07-10 方案C — 代码改为 volume 挂载,镜像不再 COPY 业务代码
|
||||
# 用法:docker build -t wecom-it-desk-backend .
|
||||
# =============================================================================
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 第一阶段:构建阶段
|
||||
# --------------------------------------------------------------------------
|
||||
FROM python:3.12-slim AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装系统依赖(psycopg2 编译需要 + qrcode 图片处理需要 + healthcheck 需要 curl)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends gcc libpq-dev libjpeg-dev zlib1g-dev curl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制依赖声明文件并安装(利用 Docker 层缓存,依赖不变则不重新安装)
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir \
|
||||
--timeout 180 \
|
||||
--retries 5 \
|
||||
-i https://mirrors.aliyun.com/pypi/simple/ \
|
||||
--trusted-host mirrors.aliyun.com \
|
||||
-r requirements.txt
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# 第二阶段:运行阶段(更小的镜像体积)
|
||||
# --------------------------------------------------------------------------
|
||||
FROM python:3.12-slim
|
||||
|
||||
# 设置标签信息
|
||||
LABEL maintainer="IT服务台开发团队"
|
||||
LABEL description="企微IT智能服务台后端服务"
|
||||
LABEL changelog="2025-07-10: 移除 COPY . .,代码改为 volume 挂载"
|
||||
|
||||
# 安装运行时依赖(psycopg2 运行时需要 libpq + healthcheck 需要 curl)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends libpq5 curl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 禁止 Python 写入 __pycache__(防止污染宿主机代码目录)
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# 从构建阶段复制已安装的 Python 包
|
||||
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
|
||||
COPY --from=builder /usr/local/bin /usr/local/bin
|
||||
|
||||
# 业务代码通过 docker-compose volumes 挂载(./app:/app/app),不再 COPY 进镜像
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8000
|
||||
|
||||
# 启动命令(Docker Compose 中会覆盖)
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
DOCKERFILE_EOF
|
||||
|
||||
# 验证
|
||||
if grep -q "COPY . ." "$DOCKERFILE"; then
|
||||
echo " FAIL: Dockerfile 仍包含 COPY . ."
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "PYTHONDONTWRITEBYTECODE" "$DOCKERFILE"; then
|
||||
echo " PASS: PYTHONDONTWRITEBYTECODE 已设置"
|
||||
else
|
||||
echo " FAIL: PYTHONDONTWRITEBYTECODE 未找到"
|
||||
exit 1
|
||||
fi
|
||||
echo " PASS: Dockerfile 已更新"
|
||||
|
||||
echo ""
|
||||
echo "===== S3 完成 ====="
|
||||
```
|
||||
|
||||
### S4: 修改 docker-compose.yml
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
COMPOSE_FILE=/opt/wecom-it-desk/docker-compose.yml
|
||||
|
||||
echo ">>> 修改 docker-compose.yml..."
|
||||
|
||||
# 在 backend-uploads 行之前插入代码卷挂载行
|
||||
sed -i '/backend-uploads:\/app\/uploads/i\ - ./app:/app/app # 代码卷挂载(方案C)' "$COMPOSE_FILE"
|
||||
|
||||
# 验证
|
||||
if grep -q "./app:/app/app" "$COMPOSE_FILE"; then
|
||||
echo " PASS: 代码卷挂载已添加"
|
||||
else
|
||||
echo " FAIL: 代码卷挂载未找到,请手动编辑 docker-compose.yml"
|
||||
echo " 在 backend 服务的 volumes: 下添加:"
|
||||
echo " - ./app:/app/app"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "===== S4 完成 ====="
|
||||
```
|
||||
|
||||
### S5: 重建镜像并重启
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
echo ">>> 重建后端镜像..."
|
||||
docker compose build backend
|
||||
echo " PASS: 镜像构建完成"
|
||||
|
||||
echo ""
|
||||
echo ">>> 重启后端容器..."
|
||||
docker compose up -d backend
|
||||
echo " PASS: 容器已启动"
|
||||
|
||||
echo ""
|
||||
echo ">>> 等待服务就绪 (45秒)..."
|
||||
sleep 45
|
||||
|
||||
echo ""
|
||||
echo "===== S5 完成 ====="
|
||||
```
|
||||
|
||||
### S6: 部署后验证
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
echo "===== 部署后验证 ====="
|
||||
echo ""
|
||||
|
||||
# 1. 容器状态
|
||||
echo "--- 1. 容器状态 ---"
|
||||
docker compose ps backend
|
||||
echo ""
|
||||
|
||||
# 2. 健康检查
|
||||
echo "--- 2. 健康检查 ---"
|
||||
if curl -sf http://localhost:8000/health; then
|
||||
echo ""
|
||||
echo " PASS: /health 正常"
|
||||
else
|
||||
echo " FAIL: /health 异常"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Auth 模块验证
|
||||
echo "--- 3. Auth 模块验证 ---"
|
||||
if docker exec wecom_it_backend python -c "from app.auth import router; print(' auth module: OK')" 2>/dev/null; then
|
||||
echo " PASS: auth 模块可导入"
|
||||
else
|
||||
echo " FAIL: auth 模块导入失败"
|
||||
echo " 查看日志: docker compose logs --tail=50 backend"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. 卷挂载验证
|
||||
echo "--- 4. 卷挂载验证 ---"
|
||||
if docker exec wecom_it_backend ls -la /app/app/main.py > /dev/null 2>&1; then
|
||||
echo " PASS: /app/app/main.py 可访问(卷挂载正常)"
|
||||
else
|
||||
echo " FAIL: /app/app/main.py 不可访问(卷挂载异常)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 5. 代码来源验证
|
||||
echo "--- 5. 代码来源验证 ---"
|
||||
HOST_HASH=$(md5sum /opt/wecom-it-desk/app/main.py | awk '{print $1}')
|
||||
CONTAINER_HASH=$(docker exec wecom_it_backend md5sum /app/app/main.py 2>/dev/null | awk '{print $1}')
|
||||
if [ "$HOST_HASH" = "$CONTAINER_HASH" ]; then
|
||||
echo " PASS: 宿主机与容器代码一致 (md5: ${HOST_HASH})"
|
||||
else
|
||||
echo " WARN: 宿主机与容器代码不一致"
|
||||
echo " 宿主机: $HOST_HASH"
|
||||
echo " 容器: $CONTAINER_HASH"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 6. 日志检查
|
||||
echo "--- 6. 最近 20 行日志 ---"
|
||||
docker compose logs --tail=20 backend
|
||||
echo ""
|
||||
|
||||
echo "===== 验证完成 ====="
|
||||
echo ""
|
||||
echo "如全部 PASS,部署成功。"
|
||||
echo "如出现 FAIL,请执行回滚脚本(见上方回滚策略章节)。"
|
||||
```
|
||||
|
||||
### S7: 清理(48 小时后执行)
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd /opt/wecom-it-desk
|
||||
|
||||
echo ">>> 清理旧代码目录..."
|
||||
echo " 注意:仅在部署成功 48 小时后执行此步骤!"
|
||||
echo ""
|
||||
|
||||
# 确认服务稳定
|
||||
curl -sf http://localhost:8000/health > /dev/null && echo " 服务正常" || { echo " 服务异常,取消清理"; exit 1; }
|
||||
|
||||
# 删除 backend/app/(不再需要)
|
||||
if [ -d /opt/wecom-it-desk/backend/app/ ]; then
|
||||
echo " 删除 backend/app/..."
|
||||
rm -rf /opt/wecom-it-desk/backend/app/
|
||||
echo " PASS: backend/app/ 已删除"
|
||||
else
|
||||
echo " INFO: backend/app/ 已不存在,跳过"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "===== 清理完成 ====="
|
||||
```
|
||||
@@ -0,0 +1,279 @@
|
||||
# 任务说明书 — 审批流程系统
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-10
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | 审批类型扩展 + 卡片URL直跳 + 同窗口导航 + 免登录研究 |
|
||||
| **任务ID** | #113-115 |
|
||||
| **优先级** | 🟡 P2 |
|
||||
| **类型** | 功能开发 |
|
||||
| **状态** | ✅ 已完成并部署 |
|
||||
| **负责人** | 开发团队(software-approval-expand / software-approval-nav 团队) |
|
||||
| **创建日期** | 2026-07-10 |
|
||||
| **完成日期** | 2026-07-10 |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/IT智能服务台-产品需求文档PRD-v2.md` | §v2.2 增量需求 P2-07~P2-11 | 审批类型扩展、卡片URL关联、导航方式、免登录研究 |
|
||||
| `02-产品需求/approval_templates.json` | 全文 | 18个审批流程的结构化数据源 |
|
||||
| `02-产品需求/dify_approval_system_prompt_v2.md` | 全文 | Dify意图识别System Prompt v2 |
|
||||
| `02-产品需求/外来资料/IT审批与运维流程清单.xlsx` | 全文 | 原始审批流程清单(18行) |
|
||||
|
||||
### 技术架构
|
||||
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `03-技术架构/IT智能服务台-系统架构设计文档v2.md` | §15.4.3~15.4.8 | 审批模板扩展、意图识别链路、前端卡片架构、导航方案选型、跨应用免登录、后端API |
|
||||
|
||||
---
|
||||
|
||||
## 📝 任务详情
|
||||
|
||||
### 子任务 #113:审批类型扩展与卡片URL直跳
|
||||
|
||||
#### 背景
|
||||
|
||||
原系统仅支持 5 种审批类型(设备申请、账号权限、软件服务、资产处置、办公用品),Dify 意图识别也仅覆盖这 5 类。根据 `IT审批与运维流程清单.xlsx`,实际需要覆盖 12 种审批类型 / 18 个审批流程(企微审批 12 个 + 运维平台 6 个)。
|
||||
|
||||
#### 实现内容
|
||||
|
||||
**后端** (`backend/app/api/approval.py`):
|
||||
- `APPROVAL_TEMPLATES` 从 5 个扩展到 18 个(静态硬编码,含完整 URL、keywords、location)
|
||||
- `APPROVAL_PREFILTER_KEYWORDS` 从 5 类扩展到 12 类关键词
|
||||
- `KEYWORD_TO_APPROVAL_TYPE` 扩展为 12 类映射
|
||||
- 新增 7 种类型:会议室故障报修、企业应用管理、资产变更确认、终端设备网络准入、活动与会议技术支持、员工IT支持与故障报修、公共邮箱账号申请
|
||||
- 意图识别三级链路保持不变:关键词预过滤 → Dify原生API → 关键词降级兜底
|
||||
|
||||
**前端** (`frontend-h5/src/components/chat/ApprovalCardModal.vue`):
|
||||
- `ApprovalOption` 接口新增 `url?: string` 字段
|
||||
- `APPROVAL_OPTIONS` 从 5 类扩展到 12 类 / 17 个选项,每个选项携带完整审批 URL
|
||||
- `handleSelect` 优先检查 `option.url`,有则直接跳转;无则 fallback 到后端模板匹配
|
||||
|
||||
**Dify**:
|
||||
- System Prompt v2 覆盖全部 12 种审批类型,含示例、匹配规则、置信度评分指南
|
||||
- 已由管理员手动粘贴发布到 Dify 后台
|
||||
|
||||
**数据文件**:
|
||||
- `approval_templates.json` — 18 个审批流程的结构化数据(id, name, category, location, template_id, url, keywords, icon, desc)
|
||||
- `dify_approval_system_prompt_v2.md` — Dify 应用的完整 System Prompt 文本
|
||||
|
||||
#### 审批流程清单(18个)
|
||||
|
||||
| # | 审批类型 | 流程名称 | 平台 |
|
||||
|---|---------|---------|------|
|
||||
| 1 | 设备申请 | IT设备领用申请 | 企微审批 |
|
||||
| 2 | 设备申请 | IT设备外修申请 | 企微审批 |
|
||||
| 3 | 账号权限申请 | VPN权限申请 | 企微审批 |
|
||||
| 4 | 账号权限申请 | 企微外联权限申请 | 企微审批 |
|
||||
| 5 | 软件服务申请 | 商业软件服务申请 | 企微审批 |
|
||||
| 6 | 资产处置申请 | IT资产报废申请 | 企微审批 |
|
||||
| 7 | 资产处置申请 | IT资产退还申请 | 企微审批 |
|
||||
| 8 | 办公用品申请 | 办公用品超额领用审批 | 企微审批 |
|
||||
| 9 | 会议室故障报修 | 会议室故障报修 | 企微审批 |
|
||||
| 10 | 企业应用管理 | 企业应用管理 | 企微审批 |
|
||||
| 11 | 资产变更确认 | 资产变更确认 | 企微审批 |
|
||||
| 12 | 员工IT支持与故障报修 | 员工IT支持与故障报修 | 企微审批 |
|
||||
| 13 | 终端设备网络准入 | 终端设备网络准入申请 | 运维平台 |
|
||||
| 14 | 终端设备网络准入 | 终端设备网络准入-会议室设备 | 运维平台 |
|
||||
| 15 | 活动与会议技术支持 | 大型活动技术保障申请 | 运维平台 |
|
||||
| 16 | 活动与会议技术支持 | 会议技术支持申请 | 运维平台 |
|
||||
| 17 | 公共邮箱账号申请 | 公共邮箱账号申请 | 运维平台 |
|
||||
| 18 | 员工IT支持与故障报修 | 故障报修工单 | 运维平台 |
|
||||
|
||||
---
|
||||
|
||||
### 子任务 #114:审批卡片同窗口导航改造
|
||||
|
||||
#### 背景
|
||||
|
||||
初始实现使用 `window.open(url, '_blank')` 在新标签页打开审批页面。在企微 H5 webview 内,新标签页体验不佳(用户需手动切换标签页)。改为同窗口导航 `window.location.href = url`,由企微原生提供顶部返回按钮。
|
||||
|
||||
#### 安全头分析
|
||||
|
||||
生产环境 H5 页面设置了以下安全头,阻止跨域 iframe 嵌入:
|
||||
|
||||
| 安全头 | 当前值 | 影响 |
|
||||
|--------|--------|------|
|
||||
| CSP `default-src` | `'self'`(无 `frame-src`) | 只允许同域 iframe |
|
||||
| COEP | `require-corp` | 跨域资源必须带 CORP 头 |
|
||||
| CORP | `same-origin` | H5 自身资源仅同域可加载 |
|
||||
|
||||
**结论**:不改安全头的情况下,同窗口导航(方案 A)是最佳选择。企微审批 URL 本身未设 `X-Frame-Options`,但 COEP 这一层仍会拦截 iframe。
|
||||
|
||||
#### 方案选型
|
||||
|
||||
| 方案 | 说明 | 改动量 | 风险 | 选型 |
|
||||
|------|------|--------|------|------|
|
||||
| A. 同窗口导航 | `location.href = url`,企微原生返回 | 1行 | 零 | ✅ 已采用 |
|
||||
| B. iframe嵌入 | 自定义返回/关闭覆盖层 | 需改COEP/CSP | 降低安全级别 | 待评估 |
|
||||
| C. 同源代理 | 后端代理iframe | 复杂度高 | 可能破坏JS/cookie | 不推荐 |
|
||||
|
||||
#### 代码改动
|
||||
|
||||
文件 `frontend-h5/src/components/chat/ApprovalCardModal.vue`:
|
||||
|
||||
```typescript
|
||||
// 改动1:handleSelect 中 option.url 分支
|
||||
// Before: window.open(option.url, '_blank'); showToast('已打开审批页面');
|
||||
// After: window.location.href = option.url;
|
||||
|
||||
// 改动2:handleSelect 中 fallback 匹配分支
|
||||
// Before: window.open(result.url, '_blank'); showToast('已打开审批页面');
|
||||
// After: window.location.href = result.url;
|
||||
```
|
||||
|
||||
移除两处 `showToast` 调用(页面立即跳转,toast 不可见)。
|
||||
|
||||
---
|
||||
|
||||
### 子任务 #115:企微跨应用免登录可行性研究
|
||||
|
||||
#### 背景
|
||||
|
||||
IT智能服务台 H5 与一站式运维平台同为税友集团企微下的自建应用(同一 corpid)。用户从 IT 服务台 H5 点击运维平台审批链接时,是否需要重新登录?
|
||||
|
||||
#### 结论
|
||||
|
||||
**可行**。同一 corpid 下的自建应用各自独立走 OAuth2 `snsapi_base` 静默授权:
|
||||
1. 用户从 IT 服务台 H5 点击运维平台链接
|
||||
2. 运维平台检测到未登录 → 自动发起 OAuth2 `snsapi_base` 静默授权
|
||||
3. 企微 webview 自动带上 corpid 凭证 → 运维平台后端拿到 `userid`
|
||||
4. 用户无感知完成登录
|
||||
|
||||
**前提条件**:
|
||||
- 运维平台已配置企微可信域名
|
||||
- 运维平台已实现 OAuth2 回调后端逻辑
|
||||
- 两个应用在同一企微 corpid 下
|
||||
|
||||
**企微审批 URL** (`app.work.weixin.qq.com`):企微内置浏览器打开时自动登录,无需额外配置。
|
||||
|
||||
---
|
||||
|
||||
## 🔧 技术方案
|
||||
|
||||
### 后端 API 端点
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/approval/templates` | GET | 返回全部18个审批模板 | 需要 |
|
||||
| `/approval/keywords` | GET | 返回12类审批关键词映射 | 需要 |
|
||||
| `/approval/detect` | POST | 意图识别(关键词预过滤 → Dify → 降级兜底) | 需要 |
|
||||
| `/approval/jump/{template_id}` | POST | 创建审批跳转 | 需要 |
|
||||
|
||||
### 意图识别三级链路
|
||||
|
||||
```
|
||||
用户消息
|
||||
↓
|
||||
1. 关键词预过滤 (_keyword_prefilter)
|
||||
命中 → 返回模板
|
||||
未命中 ↓
|
||||
2. Dify 原生 API (app-7jkRkAzvX4QM9v9SM3P8mMEO)
|
||||
返回 is_approval_request + approval_type
|
||||
置信度 ≥ 0.7 → 匹配模板
|
||||
未命中 ↓
|
||||
3. 关键词降级兜底 (_fallback_detect)
|
||||
模糊匹配 → 返回模板或 None
|
||||
```
|
||||
|
||||
### 前端组件架构
|
||||
|
||||
```
|
||||
ApprovalCardModal.vue
|
||||
├── ApprovalOption 接口 { name, icon, desc, url? }
|
||||
├── APPROVAL_OPTIONS (12类 / 17选项,每个带 url)
|
||||
├── handleSelect(option)
|
||||
│ ├── option.url 存在 → window.location.href = option.url
|
||||
│ └── fallback → 调后端 /approval/detect → /approval/jump
|
||||
├── loadKeywords() → 从后端加载关键词列表
|
||||
└── onMounted → 初始化
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 交付物清单
|
||||
|
||||
### 代码文件
|
||||
|
||||
| 文件 | 改动类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `backend/app/api/approval.py` | 修改 | 18个模板+12类关键词+映射表 |
|
||||
| `frontend-h5/src/components/chat/ApprovalCardModal.vue` | 修改 | 12类卡片+URL直跳+同窗口导航 |
|
||||
|
||||
### 数据文件
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `docs/02-产品需求/approval_templates.json` | 18个审批流程结构化数据 |
|
||||
| `docs/02-产品需求/dify_approval_system_prompt_v2.md` | Dify System Prompt v2全文 |
|
||||
| `docs/02-产品需求/外来资料/IT审批与运维流程清单.xlsx` | 原始数据源 |
|
||||
|
||||
### 文档更新
|
||||
|
||||
| 文档 | 更新内容 |
|
||||
|------|---------|
|
||||
| `docs/02-产品需求/IT智能服务台-产品需求文档PRD-v2.md` | 新增 v2.2 增量需求(P2-07~P2-11) |
|
||||
| `docs/03-技术架构/IT智能服务台-系统架构设计文档v2.md` | §15.4.3~15.4.8 扩展 |
|
||||
| `docs/10-项目管理/任务说明书/IT智能服务台-项目管理主文档.md` | 新增 #113-115 任务 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验证结果
|
||||
|
||||
| 验证项 | 方法 | 结果 |
|
||||
|--------|------|------|
|
||||
| 后端 API 模板列表 | `docker exec wecom_it_backend curl -s http://localhost:8000/approval/templates` | ✅ 返回18个模板 |
|
||||
| 后端 API 关键词 | `docker exec wecom_it_backend curl -s http://localhost:8000/approval/keywords` | ✅ 12类关键词映射正确 |
|
||||
| 前端 H5 页面可访问 | `docker exec wecom_it_nginx curl -s -o /dev/null -w '%{http_code}' http://localhost/h5/` | ✅ HTTP 301(正常重定向) |
|
||||
| nginx 容器文件 | `docker exec wecom_it_nginx ls /usr/share/nginx/html/h5/` | ✅ assets/ + index.html 齐全 |
|
||||
| 浏览器渲染 | agent-browser 打开 H5 URL | ✅ 登录页正常渲染,无JS报错 |
|
||||
| 生产容器状态 | `docker ps` | ✅ backend healthy / nginx running |
|
||||
| 企微内实测 | 用户手动测试 | ✅ 企微审批+运维平台审批均通过 |
|
||||
| Dify 意图识别 | 用户手动测试 | ✅ Dify v2 已发布,识别新增7种类型 |
|
||||
|
||||
---
|
||||
|
||||
## 📌 已知非阻塞项
|
||||
|
||||
| 项 | 说明 | 影响 |
|
||||
|----|------|------|
|
||||
| `import os` 未使用 | `approval.py` 中 `os.getenv` 调用被移除后,`import os` 变为未使用 | Linter警告,不影响运行 |
|
||||
| `it_device_repair` 模板 | 后端模板中有 `it_device_repair` 但前端"设备申请"下无对应选项 | 不影响功能,该模板通过意图识别仍可触发 |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 部署记录
|
||||
|
||||
| 步骤 | 操作 | 时间 |
|
||||
|------|------|------|
|
||||
| 后端文件上传 | `jms_ops.py upload` → `/tmp/approval_v2.py` | 2026-07-10 |
|
||||
| 后端替换+重启 | `cp /tmp/approval_v2.py` + `docker compose restart backend` | 2026-07-10 |
|
||||
| 前端构建 | `npm run build`(465 modules, 3.18s) | 2026-07-10 |
|
||||
| 前端打包上传 | `tar -czf` → `jms_ops.py upload` | 2026-07-10 |
|
||||
| 前端解压+重启 | `tar -xzf` + `docker compose restart nginx` | 2026-07-10 |
|
||||
| 导航改造部署 | 同上流程(第二次部署) | 2026-07-10 |
|
||||
| 临时文件清理 | `/tmp/approval_v2.py` + `/tmp/frontend-h5-dist*.tar.gz` | 2026-07-10 |
|
||||
| Dify System Prompt | 用户手动粘贴发布 | 2026-07-10 |
|
||||
|
||||
---
|
||||
|
||||
## 📎 关联文档
|
||||
|
||||
| 文档 | 位置 |
|
||||
|------|------|
|
||||
| PRD v2 | `docs/02-产品需求/IT智能服务台-产品需求文档PRD-v2.md` |
|
||||
| 架构设计 v2 | `docs/03-技术架构/IT智能服务台-系统架构设计文档v2.md` |
|
||||
| 审批模板数据 | `docs/02-产品需求/approval_templates.json` |
|
||||
| Dify Prompt v2 | `docs/02-产品需求/dify_approval_system_prompt_v2.md` |
|
||||
| 原始清单 | `docs/02-产品需求/外来资料/IT审批与运维流程清单.xlsx` |
|
||||
@@ -0,0 +1,154 @@
|
||||
# 任务说明书模板
|
||||
|
||||
> **版本**: v1.0 | **日期**: 2026-07-04
|
||||
|
||||
---
|
||||
|
||||
## 📋 基本信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **任务名称** | [任务名称] |
|
||||
| **任务ID** | #[编号] |
|
||||
| **优先级** | 🔴P0 / 🟠P1 / 🟡P2 |
|
||||
| **类型** | 功能开发 / Bug修复 / 安全加固 / 文档完善 / 测试修复 / 部署优化 |
|
||||
| **状态** | 待开始 / 进行中 / 已完成 / 阻塞 / 延后 |
|
||||
| **负责人** | [负责人] |
|
||||
| **创建日期** | YYYY-MM-DD |
|
||||
| **计划完成日期** | YYYY-MM-DD |
|
||||
|
||||
---
|
||||
|
||||
## 📥 输入项来源
|
||||
|
||||
### 产品需求
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `02-产品需求/02-产品需求文档PRD-v1.2-20260704.md` | §X | [需求描述] |
|
||||
| `02-产品需求/product-产品/v0.7.2-backlog-candidate-2026-06-24.md` | [ backlog项 ] | [需求描述] |
|
||||
|
||||
### 技术架构
|
||||
| 来源文档 | 相关章节 | 说明 |
|
||||
|----------|----------|------|
|
||||
| `03-技术架构/02-技术方案/[技术方案文档].md` | §X | [技术设计] |
|
||||
| `03-技术架构/01-ADRs-架构决策/ADR-XXX.md` | - | [架构决策] |
|
||||
|
||||
### 原型设计
|
||||
| 来源文档 | 页面 | 说明 |
|
||||
|----------|------|------|
|
||||
| `04-原型设计/prototypes-原型图/[原型文件].html` | [页面名] | [UI/UX要求] |
|
||||
|
||||
### 项目看板
|
||||
| 来源 | 任务名 | 说明 |
|
||||
|------|--------|------|
|
||||
| `05-项目状态看板/01-项目状态看板.md` | [任务名] | [看板任务描述] |
|
||||
|
||||
---
|
||||
|
||||
## 📤 输出成果要求
|
||||
|
||||
### 交付物清单
|
||||
|
||||
| # | 交付物 | 类型 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | [交付物名称] | 代码/文档/配置 | [说明] |
|
||||
| 2 | [交付物名称] | 代码/文档/配置 | [说明] |
|
||||
|
||||
### 代码要求
|
||||
- 遵循项目代码规范(见 `07-代码评审/`)
|
||||
- 所有新增代码通过 ESLint / Pylint 检查
|
||||
- 单元测试覆盖率 ≥ 80%
|
||||
|
||||
### 文档要求
|
||||
- 更新相关技术文档
|
||||
- 更新 API 接口文档
|
||||
- 更新部署文档(如有变更)
|
||||
|
||||
---
|
||||
|
||||
## 🔧 验证方式
|
||||
|
||||
### 功能验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 功能正常运行 | 手动测试 | 功能符合需求 |
|
||||
| 接口正常 | API测试 | 返回正确 |
|
||||
| 页面正常 | UI测试 | 显示正确 |
|
||||
|
||||
### 安全验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 权限控制 | 越权测试 | 无法访问未授权资源 |
|
||||
| 输入验证 | 异常输入测试 | 正确拦截/提示 |
|
||||
|
||||
### 性能验证
|
||||
| 验证项 | 验证方法 | 预期结果 |
|
||||
|--------|----------|-----------|
|
||||
| 响应时间 | 性能测试 | < 200ms (API) |
|
||||
| 并发能力 | 压力测试 | 50+ 并发正常 |
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完成标准
|
||||
|
||||
### 验收条件
|
||||
|
||||
- [ ] 代码合入主干分支
|
||||
- [ ] 所有测试通过(CI/CD 绿灯)
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 安全测试通过
|
||||
- [ ] 文档已更新
|
||||
- [ ] 相关任务看板已更新
|
||||
|
||||
### 产出确认
|
||||
|
||||
- [ ] 代码已提交并通过 Code Review
|
||||
- [ ] 单元测试新增/修复完成
|
||||
- [ ] 集成测试通过
|
||||
- [ ] 部署验证通过(如需要)
|
||||
- [ ] 文档更新已完成
|
||||
|
||||
---
|
||||
|
||||
## 📊 工作分解
|
||||
|
||||
### 子任务
|
||||
|
||||
| 子任务 | 负责人 | 预估工时 | 状态 |
|
||||
|--------|--------|----------|------|
|
||||
| [子任务1] | [负责人] | [工时] | [状态] |
|
||||
| [子任务2] | [负责人] | [工时] | [状态] |
|
||||
| [子任务3] | [负责人] | [工时] | [状态] |
|
||||
|
||||
---
|
||||
|
||||
## 📞 依赖与阻塞
|
||||
|
||||
### 前置依赖
|
||||
| 依赖任务 | 依赖说明 | 状态 |
|
||||
|----------|----------|------|
|
||||
| [任务ID] | [依赖说明] | 已完成/进行中 |
|
||||
|
||||
### 阻塞因素
|
||||
| 阻塞项 | 影响范围 | 解决方案 |
|
||||
|--------|----------|-----------|
|
||||
| [阻塞项] | [影响] | [解决方案] |
|
||||
|
||||
---
|
||||
|
||||
## 📈 变更记录
|
||||
|
||||
| 日期 | 变更内容 | 变更人 | 说明 |
|
||||
|------|----------|--------|------|
|
||||
| YYYY-MM-DD | 创建任务 | [人] | 初始版本 |
|
||||
| YYYY-MM-DD | [变更] | [人] | [说明] |
|
||||
|
||||
---
|
||||
|
||||
## 📎 附件
|
||||
|
||||
- 相关需求文档链接
|
||||
- 技术方案链接
|
||||
- 原型图链接
|
||||
- 测试用例链接
|
||||
|
||||
Reference in New Issue
Block a user