docs: T40 UI 审计报告 + wiki 更新 + Docker 配置

- T40 UI 审计计划和结果文档(docs/qa/)
- wiki 更新:miniprogram 设计系统合规审计记录 + index 关键数字更新
- 审计 V2 完整报告(docs/audits/v2/)
- 讨论记录文档(docs/discussions/)
- 设计规格和实施计划(docs/superpowers/)
- 角色测试计划和结果(docs/qa/role-test-*)
- Docker 生产部署配置
This commit is contained in:
iven
2026-05-13 23:29:42 +08:00
parent 212c08b7ae
commit df1d85bfde
78 changed files with 10345 additions and 39 deletions

View File

@@ -0,0 +1,180 @@
# HMS V2 系统性功能审计 — 最终报告
> 审计日期: 2026-05-04 | V1 基线: 83% (2026-04-30) | Git HEAD: 95fa09c | 提交: 623
## 一、总体评分
| 指标 | V1 | V2 | 变化 |
|------|-----|-----|------|
| **系统完成度** | 83% | **85%** | +2% |
| 后端代码行数 | ~77k | 98,501 | +28% |
| 后端路由 | 328 | 302 | 整合优化 |
| Web API | 235 | 252 | +7% |
| MP API | 76 | 96 | +26% |
| 事件类型 | 25 | 51 | +104% |
| Web 测试文件 | 10 | 62 | +520% |
> 评分说明:完成度从 83% 提升至 85%。虽然 V1 的 15 个问题中 14 个已修复但新增代码引入了新问题SQL 注入、孤立模块),两者抵消。
## 二、V2 审计发现总览
### CRITICAL2 个)
| # | 问题 | 位置 | 影响 |
|---|------|------|------|
| C1 | **SQL 注入**: `patient_id`/`user_id` 通过 `format!` 拼接 SQL | `action_inbox_service.rs:272-306` | 数据泄露/篡改风险 |
| C2 | **FHIR 越权**: `allowed_patient_ids` 未在查询层强制执行 | `fhir/handler.rs` | 第三方应用可访问非授权患者数据 |
### HIGH6 个)
| # | 问题 | 位置 | 影响 |
|---|------|------|------|
| H1 | 5 个模块 34 条路由完全孤立(护理计划/班次/BLE网关/家庭代理/药物记录) | 前端无 UI | Phase 1 产出未交付 |
| H2 | AI 前后对比功能未实现reanalysis.rs 仅日志) | `erp-ai/src/service/reanalysis.rs` | 关怀闭环断链 |
| H3 | BLE 双写 vital_signs 无事务保护,失败静默忽略 | `device_reading_service.rs` | 数据不一致 |
| H4 | 透析创建与 KDIGO 风险评分未自动串联 | 事件无 subscriber | 人工触发,效率低 |
| H5 | OAuth handler 5 个端点缺少 `require_permission` | `oauth/handler.rs` | 权限绕过风险 |
| H6 | MP 测试 0 个40+ 页面全靠手工) | `apps/miniprogram/` | 回归风险极高 |
### MEDIUM8 个)
| # | 问题 | 位置 |
|---|------|------|
| M1 | AI 分析缓存功能存在但未启用 | `erp-ai/service/analysis.rs` |
| M2 | SSE 无背压保护unbounded channel | 告警推送 |
| M3 | JWT Secret 硬编码 fallback `"dev-secret-key"` | `oauth/middleware.rs:67` |
| M4 | 新增 service 4/6 无 tracing 日志 | care_plan/shift/ble_gateway/vital_signs_daily |
| M5 | 告警双路径可能重复触发 | alert.rs + alert_engine.rs |
| M6 | MP 日期格式化 6+ 处独立实现,无统一封装 | MP utils |
| M7 | MP 错误提示无 403/500 分支,统一"请求失败" | MP request.ts |
| M8 | MP 存在约 15 处 20px 字号低于适老阈值 22px | MP 多处 |
### LOW5 个)
| # | 问题 | 位置 |
|---|------|------|
| L1 | 速率限制已建模未执行 | `oauth/service.rs` |
| L2 | 测试文件含明文数据库密码 | `test_db.rs` |
| L3 | E2E 测试 fixture 硬编码 localhost 无 fallback | `web/e2e/auth.fixture.ts` |
| L4 | action_inbox DTO 内嵌 service未抽取独立文件 | `action_inbox_service.rs` |
| L5 | FHIR Bundle 缺 link 字段,不符合 R4 规范 | `fhir/converter.rs` |
## 三、功能域评分20 域 × 10 维度)
| 功能域 | D1目标 | D2代码 | D3连通 | D4数据流 | D5安全 | D6错误 | D7日志 | D8性能 | D9测试 | D10 UX | 加权分 |
|--------|-------|-------|-------|---------|-------|-------|-------|-------|-------|--------|--------|
| F1 患者 | 90 | 100 | 70 | 85 | 95 | 90 | 85 | 90 | 70 | 75 | **85** |
| F2 医生 | 80 | 100 | 100 | 90 | 95 | 90 | 85 | 90 | 70 | 85 | **89** |
| F3 健康数据 | 95 | 100 | 75 | 80 | 95 | 85 | 80 | 85 | 75 | 70 | **83** |
| F4 预约 | 95 | 100 | 100 | 95 | 95 | 90 | 85 | 90 | 80 | 90 | **93** |
| F5 随访 | 95 | 100 | 80 | 85 | 90 | 90 | 80 | 85 | 75 | 75 | **85** |
| F6 咨询 | 90 | 100 | 95 | 90 | 95 | 90 | 85 | 90 | 70 | 85 | **89** |
| F7 内容 | 70 | 100 | 90 | 85 | 90 | 90 | 80 | 85 | 65 | 80 | **84** |
| F8 积分 | 75 | 100 | 85 | 80 | 90 | 85 | 75 | 80 | 70 | 75 | **82** |
| F9 告警 | 95 | 100 | 85 | 80 | 85 | 85 | 80 | 75 | 70 | 75 | **83** |
| F10 AI | 90 | 100 | 75 | 70 | 90 | 80 | 70 | 60 | 65 | 60 | **76** |
| F11 透析 | 95 | 100 | 90 | 80 | 90 | 85 | 75 | 85 | 70 | 80 | **85** |
| F12 仪表盘 | 85 | 100 | 75 | 80 | 90 | 85 | 75 | 80 | 65 | 75 | **81** |
| F13 行动收件箱 | 95 | 100 | 85 | 70 | **50** | 80 | 75 | 80 | 65 | 75 | **78** |
| F14 护理计划 | 80 | 100 | **0** | **0** | 90 | 80 | **0** | 85 | **0** | **0** | **44** |
| F15 班次 | 75 | 100 | **0** | **0** | 90 | 80 | **0** | 85 | **0** | **0** | **41** |
| F16 BLE 网关 | 75 | 100 | **0** | 60 | 85 | 80 | **0** | 70 | **0** | **0** | **40** |
| F17 家庭代理 | 75 | 100 | **0** | 60 | 90 | 80 | **0** | 85 | **0** | **0** | **41** |
| F18 FHIR | 70 | 100 | **0** | 65 | **60** | 75 | **0** | 60 | **0** | **0** | **35** |
| F19 OAuth | 60 | 100 | 50 | 70 | **55** | 75 | **0** | 80 | **0** | **0** | **42** |
| F20 日聚合 | 85 | 100 | 50 | 75 | 90 | 80 | **0** | 85 | **0** | **0** | **52** |
> D2 代码存在性: 所有域均为 100%(后端代码完整)
> D3 连通性: 5 个域为 0%(后端已实现但完全无前端接入)
> D9 测试: 8 个域为 0%(新增模块无测试)
## 四、V1 问题修复确认
| ID | V1 问题 | V2 状态 |
|----|--------|---------|
| C1 | 晚间血压丢失 | ✅ 已修复 |
| C2 | 告警权限拼写 | ✅ 已修复 |
| H1 | 透析 MP 无入口 | ✅ 已修复7 个 MP 页面) |
| H2 | 知情同意 MP 无入口 | ✅ 已修复 |
| H3 | 日志 30% | ✅ 已修复116 处 tracing |
| M1 | 权限声明 47% | ✅ 已修复53 个 Descriptor |
| M3 | 体温/血氧 MP | ✅ 已修复 |
| M4 | SSE 指数退避 | ✅ 已修复 |
| M5 | erp-ai 集成测试 | ✅ 已修复 |
| M6 | Web 测试极低 | ✅ 大幅改善10→62 文件) |
| M7 | MP 测试 | ❌ 未修复(仍为 0 |
| M8 | 健康记录/诊断 MP | ✅ 已修复 |
| L1 | 孤立事件 | ✅ 已修复 |
| L5 | unwrap() 风险 | ✅ 已修复 |
| L12 | 40 编译警告 | ⚠️ 需关注18 处 allow 标注) |
**修复率: 13/15 (87%)**。仅 M7(MP 测试)和 L12(allow 标注)未完全解决。
## 五、修复优先级排序
### P0 — 必须在 Phase 2 前修复(阻塞交付)
| 优先级 | 问题 | 工作量 | 原因 |
|--------|------|--------|------|
| 1 | **C1: SQL 注入修复** | 2h | 安全漏洞,数据泄露风险 |
| 2 | **C2: FHIR allowed_patient_ids 强制执行** | 4h | 越权访问风险 |
| 3 | **H5: OAuth handler 添加 require_permission** | 1h | 权限绕过风险 |
| 4 | **M3: 移除 JWT Secret 硬编码 fallback** | 1h | 生产安全 |
### P1 — Phase 2 期间修复
| 优先级 | 问题 | 工作量 | 原因 |
|--------|------|--------|------|
| 5 | H2: AI 前后对比功能实现 | 8h | 关怀闭环核心 |
| 6 | H4: 透析→KDIGO 自动串联 | 4h | 自动化风险预警 |
| 7 | H3: BLE 双写事务保护 | 4h | 数据一致性 |
| 8 | M4: 新增 service tracing 补全 | 4h | 可观测性 |
| 9 | M1: AI 缓存启用 | 2h | 性能/成本优化 |
### P2 — 中期补全
| 优先级 | 问题 | 工作量 | 原因 |
|--------|------|--------|------|
| 10 | H1: 孤立模块前端 UI 接入(按业务优先级) | 40h+ | Phase 2 范围 |
| 11 | H6: MP 测试框架搭建 | 16h | 回归保障 |
| 12 | M6/M7: MP 日期/错误统一封装 | 8h | UX 一致性 |
| 13 | M8: 适老化字号修复 | 4h | 老年友好 |
| 14 | M5: 告警去重机制 | 4h | 告警风暴保护 |
## 六、关键建议
### 6.1 架构建议
1. **统一前端 API 层**: MP 端日期/错误处理需统一封装,避免 6+ 处独立实现
2. **事件消费者补全**: 8 个事件无消费者care_plan 相关事件全部悬空
3. **DTO 规范化**: action_inbox DTO 内嵌 service应抽取独立文件
### 6.2 测试建议
1. **MP 测试框架**: 最高优先级搭建 Taro 测试环境Vitest + React Testing Library
2. **新增模块测试**: care_plan/shift/ble_gateway/family_proxy 四个模块 0 测试
3. **Web 测试质量**: 62 文件需评估断言覆盖率和 mock 质量
### 6.3 Phase 2 前置条件
Phase 2患者体验重构可启动但需先完成 P0 修复项C1/C2/H5/M3。理由
- P0 均为安全问题,不修复则在生产环境存在数据泄露/越权风险
- Phase 2 涉及老年患者 UI 重设计,安全基础必须先行
## 七、报告索引
| # | 文件 | 行数 | 内容 |
|---|------|------|------|
| 1 | `00-baseline-refresh.md` | 150 | 基线数字 + V1 对比 |
| 2 | `01-business-value-analysis.md` | 200 | 20 功能域业务画像 |
| 3 | `02-feature-inventory-refresh.md` | 120 | 三端对齐矩阵 |
| 4 | `03-data-flow-traces.md` | 320 | 12 条数据流 + Mermaid 图 |
| 5 | `04-backend-integrity.md` | 122 | 后端完整性 |
| 6 | `05-security-performance.md` | 130 | 安全合规 + 性能 |
| 7 | `06-gap-patterns-refresh.md` | 100 | 差距模式重验 |
| 8 | `07-observability.md` | 60 | 日志/错误/可观测性 |
| 9 | `08-test-coverage-refresh.md` | 70 | 测试覆盖率 |
| 10 | `10-ux-consistency.md` | 87 | UX 一致性 |
| 11 | `11-tech-debt.md` | 98 | 技术债务 |
| 12 | `12-expert-review.md` | 待定 | 多角色评审 |
| 13 | `13-final-report.md` | 本文件 | 综合报告 |