- T40 UI 审计计划和结果文档(docs/qa/) - wiki 更新:miniprogram 设计系统合规审计记录 + index 关键数字更新 - 审计 V2 完整报告(docs/audits/v2/) - 讨论记录文档(docs/discussions/) - 设计规格和实施计划(docs/superpowers/) - 角色测试计划和结果(docs/qa/role-test-*) - Docker 生产部署配置
181 lines
9.0 KiB
Markdown
181 lines
9.0 KiB
Markdown
# 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 审计发现总览
|
||
|
||
### CRITICAL(2 个)
|
||
|
||
| # | 问题 | 位置 | 影响 |
|
||
|---|------|------|------|
|
||
| C1 | **SQL 注入**: `patient_id`/`user_id` 通过 `format!` 拼接 SQL | `action_inbox_service.rs:272-306` | 数据泄露/篡改风险 |
|
||
| C2 | **FHIR 越权**: `allowed_patient_ids` 未在查询层强制执行 | `fhir/handler.rs` | 第三方应用可访问非授权患者数据 |
|
||
|
||
### HIGH(6 个)
|
||
|
||
| # | 问题 | 位置 | 影响 |
|
||
|---|------|------|------|
|
||
| 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/` | 回归风险极高 |
|
||
|
||
### MEDIUM(8 个)
|
||
|
||
| # | 问题 | 位置 |
|
||
|---|------|------|
|
||
| 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 多处 |
|
||
|
||
### LOW(5 个)
|
||
|
||
| # | 问题 | 位置 |
|
||
|---|------|------|
|
||
| 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` | 本文件 | 综合报告 |
|