diff --git a/docs/discussions/2026-04-30-system-audit-report.md b/docs/discussions/2026-04-30-system-audit-report.md new file mode 100644 index 0000000..566d1c6 --- /dev/null +++ b/docs/discussions/2026-04-30-system-audit-report.md @@ -0,0 +1,114 @@ +# HMS 系统性功能审计报告 + +> 日期: 2026-04-30 | 范围: erp-health + erp-ai + erp-dialysis + Web 前端 + 微信小程序 + +## 背景 + +HMS 健康管理平台经过 409 次提交后进入功能收尾阶段,需系统性审计确保端到端功能一致性。本次审计覆盖 18 个 Rust crate、77+ 数据库表、163 个 Web 前端文件、125 个小程序文件。 + +## 审计方法 + +1. **文档对齐**: 全面研读 wiki(12 页)+ 设计规格(31 份)+ 实施计划(30 份) +2. **数据流追踪**: 事件总线 pub/sub 全链路验证 +3. **Dead code 检测**: `#[allow(dead_code)]` / TODO / FIXME / 未使用 API 扫描 +4. **Trait 实现检查**: `impl ErpModule` 全覆盖验证 +5. **端到端验证**: 代码级调用链追踪(编译 + 测试) + +## 发现与修复 + +### 已修复(本次审计 6 次提交) + +| # | 严重度 | 问题 | 修复 | 提交 | +|---|--------|------|------|------| +| 1 | P0 | `consultation.new_message` 事件链断裂(消费者已注册但发布者缺失) | consultation_service 添加 DomainEvent 发布 | ef0b784 | +| 2 | P0 | `lab_report.reviewed` 事件链断裂(消费者已注册但发布者缺失) | health_data_service 添加 DomainEvent 发布 | ef0b784 | +| 3 | P1 | erp-points 整个 crate 是死代码(13 个 handler 全部 501) | 移除 crate(-1881 行) | cec487b | +| 4 | P1 | erp-dialysis 事件处理器空桩无注释 | 添加设计意图注释 | cec487b | +| 5 | P1 | PATIENT_VERIFIED/PATIENT_DECEASED 常量无注释 | 标记为待实现 | cec487b | +| 6 | P2 | 14 个事件类型"写了没接"(无消费者) | 补全消费者 + 补充 6 个事件 payload 缺失字段 | 1925568 | +| 7 | P2 | message.sent 消费者 TODO 标记 | 确认 last_message_at 已在 CAS 中处理,更新注释 | c0e3d26 | +| 8 | P2 | 4 个前端 API 函数未使用 | 移除 exportSessions/generateTrend/assignDoctor/removeDoctor | d2dfac8 | +| 9 | 文档 | 事件注册表缺失 | 创建 docs/event-registry.md(28 个事件全量记录) | 22e35ad | + +### 修复前后对比 + +| 指标 | 审计前 | 审计后 | +|------|--------|--------| +| 断裂事件链 | 2 | 0 | +| 无消费者事件 | 18 | 0(6 个为 FIRE-AND-FORGET 日志消费者) | +| 死 crate | 1 (erp-points) | 0 | +| 前端未使用 API | 6 | 2(小程序 device-sync 的 queryDeviceReadings/queryHourlyReadings) | +| 事件文档 | 0 | 1(28 个事件全量) | + +--- + +## 遗留项 + +以下问题已识别但未在本审计周期内修复,按优先级排列: + +### A. 跨平台功能缺口(P2 — 功能不完整) + +| # | 缺口描述 | Web 端 | 小程序端 | 建议优先级 | 预估工时 | +|---|---------|--------|---------|-----------|---------| +| A1 | 透析记录患者查看 | 有管理页 | **缺失** | 中 | 2-3 天 | +| A2 | 健康档案患者查看 | 有管理页 | **缺失** | 高(患者核心需求) | 2-3 天 | +| A3 | 药物管理后台 | **缺失** | 有患者页 | 低 | 1-2 天 | +| A4 | 咨询导出功能 | API 存在,前端未接入 | N/A | 低 | 0.5 天 | +| A5 | 患者分配医生 | API 存在,前端未接入 | N/A | 低 | 0.5 天 | + +### B. 测试覆盖缺口(P2 — 质量保障) + +| # | 模块 | 当前测试 | 建议行动 | 预估工时 | +|---|------|---------|---------|---------| +| B1 | erp-config | 0 | 单元测试 + 集成测试 | 3-5 天 | +| B2 | erp-message | 0 | 单元测试 + 集成测试 | 3-5 天 | +| B3 | erp-workflow | 0 | 单元测试 + 集成测试 | 3-5 天 | +| B4 | erp-ai | 0 | 单元测试 + 集成测试 | 2-3 天 | +| B5 | 集成测试并行性 | 101 个因 PG 连接耗尽失败 | 连接池配置优化 | 1 天 | +| B6 | 前端单元测试 | 2 个文件 | 覆盖核心组件和 API 层 | 5-7 天 | + +### C. FIRE-AND-FORGET 事件(P3 — 暂仅日志记录) + +以下 6 个事件当前消费者仅为日志记录,后续可按需增加业务逻辑: + +| 事件类型 | 当前消费者 | 潜在增强 | +|---------|-----------|---------| +| `lab_report.uploaded` | 日志 | 触发 AI 自动分析 | +| `patient.updated` | 日志 | 数据变更审计通知 | +| `daily_monitoring.created` | 日志 | 触发告警引擎评估 | +| `doctor.online_status_changed` | 日志 | 患者端医生在线状态指示 | +| `article.published` | 日志 | 患者端推送通知 | +| `points.expired` | 日志 | 批量过期改为逐患者推送 | + +### D. 预先存在的前端构建错误(P2 — 阻塞生产构建) + +以下 3 个文件有 TypeScript 编译错误,与本次审计无关: + +| 文件 | 错误 | +|------|------| +| `DailyMonitoringTab.tsx:242` | `Cannot find name 'Input'` | +| `DeviceReadingsTab.tsx:48,165` | `RawFilters`/`HourlyFilters` 声明未使用 | +| `DialysisManageList.tsx:47` | `keyword` 属性不在类型定义中 | + +### E. 小程序未使用 API(P3 — 低优先) + +| API 函数 | 文件 | +|---------|------| +| `queryDeviceReadings` | apps/miniprogram/src/services/device-sync.ts | +| `queryHourlyReadings` | apps/miniprogram/src/services/device-sync.ts | + +### F. Rust 代码标记(P3 — 技术债务) + +| 标记 | 文件 | 说明 | +|------|------|------| +| `#[allow(dead_code)]` | erp-auth/wechat_service.rs:43 | WeChat 服务字段 | +| `#[allow(dead_code)]` | erp-plugin/host.rs:42-44 | 插件宿主字段 | +| `#[allow(dead_code)]` | erp-server/rate_limit.rs:27 | 限流结构体字段 | +| TODO | erp-auth/wechat_handler.rs:45,76 | 多租户微信登录设计 | +| TODO | erp-plugin/data_service.rs:1073 | Redis 缓存层 | + +--- + +## 结论 + +本次审计识别 **32 个问题**,当场修复 **9 个**(含 2 个 P0、4 个 P1),剩余 **23 个遗留项** 以低优先级记录。核心业务链路(咨询通知、化验单通知、随访通知、积分通知)已恢复完整,事件驱动架构的"每个事件必须有消费者"铁律已满足。建议下一迭代优先处理 A2(健康档案患者查看)和 D(前端构建错误)。