18 KiB
HMS 健康管理平台 — 全项目深度分析与多专家组头脑风暴
日期: 2026-05-03 | 类型: 分析报告 | 数据截止: commit 554 | 状态: 草稿
TL;DR: HMS 项目整体健康度 B+。架构边界满分,安全基础扎实,文档体系完善。核心风险:前端测试 <5%、55% 事件孤立、审计整改率 8%、73 个未提交文件。建议立即止血(P0)→ 本周补短板(P1)→ 本月治本(P2)。
1. 背景与目标
为什么做这次分析
HMS 项目经过 3 周密集开发(554 次提交,41 份设计规格),已进入功能基本完整的阶段。2026-04-30 完成的全系统审计发现 25 个问题(2 CRITICAL + 3 HIGH + 8 MEDIUM + 12 LOW),但审计后 3 天整改率仅 8%。此时需要一个全面的「体检」来:
- 识别系统性风险而非单点问题
- 从多维度(架构/安全/前端/质量/管理)交叉验证
- 建立清晰的优先级行动矩阵
分析范围
| 维度 | 覆盖范围 |
|---|---|
| 后端架构 | 17 Rust crates / ~87k 行 / 484 源文件 |
| 前端 Web | 199 文件(113 TSX + 86 TS) |
| 微信小程序 | 113 文件 / 40 页面 / 5 TabBar |
| 数据库 | 103 迁移 / 77+ 表 |
| 文档体系 | 12 页 wiki + 41 specs + 38 plans + 18 discussions |
方法论
- 静态分析: 文件大小、代码模式搜索、依赖图梳理
- 模式识别: 重复代码、缺失测试、不一致的命名
- 多专家视角: 5 个虚拟专家组从不同角度审查同一代码库
- 数据来源: Cargo.toml / git log / Grep 搜索 / Wiki 内容 / 审计报告
2. 项目全景扫描
2.1 规模与复杂度
| 维度 | 数据 | 评估 |
|---|---|---|
| Rust 代码 | ~87k 行 / 17 crates / 484 源文件 | 中大型单体,模块边界清晰 |
| Web 前端 | 199 文件 (113 TSX + 86 TS) | 中等规模,API 层完整 |
| 微信小程序 | 113 文件 / 40 页面 / 5 TabBar | 功能丰富,分包合理 |
| 数据库 | 103 迁移 / 77+ 表 | 高频 schema 迭代 |
| API 路由 | 328 (8 公开 + 320 受保护) | 全面的业务覆盖 |
| 测试 | 772 后端 + 11 前端 | 后端尚可,前端极低 |
| 事件系统 | 25 类型 / 44 发布 / 14 消费者 | 设计精良但有孤立事件 |
| 设计文档 | 41 specs / 38 plans | 文档驱动,管理有序 |
| Git 历史 | 554 次提交 | AI 辅助密集开发 |
2.2 架构评分矩阵
| 评估维度 | 得分 (1-5) | 说明 |
|---|---|---|
| 模块边界 | ⭐⭐⭐⭐⭐ | 零循环依赖,crates 间仅依赖 erp-core |
| 安全姿态 | ⭐⭐⭐⭐☆ | Argon2 + AES-256-GCM + RLS + 审计哈希链,限流失败模式待改进 |
| 错误处理 | ⭐⭐⭐⭐⭐ | 统一 AppError + 跨 crate 转换 + HTTP 映射 |
| 事件系统 | ⭐⭐⭐⭐☆ | Outbox + 死信 + 幂等,但 14 个孤立事件无消费者 |
| 前端架构 | ⭐⭐⭐⭐☆ | API/Store/Hook 三层分离,但零 i18n、低测试覆盖 |
| 代码质量 | ⭐⭐⭐⭐☆ | 4 个 TODO、无 FIXME/HACK,但存在 6 个千行文件 |
| 测试覆盖 | ⭐⭐⭐☆☆ | 后端 772 测试尚可,前端 <5%、小程序 0% |
| 文档完整性 | ⭐⭐⭐⭐☆ | 12 页 wiki + 41 specs,但 wiki 数据存在不一致 |
| 运维成熟度 | ⭐⭐⭐☆☆ | Docker + 原生双轨但不同步,单分支开发,大量未提交文件 |
3. 专家组 1:架构与基础设施
成员画像: Rust 系统架构师 + 数据库工程师 + DevOps 工程师
3.1 模块依赖分析
依赖结构: 所有 16 个 crate 形成以 erp-core 为底座的星型依赖图。erp-server 是唯一的组合根,依赖所有业务 crate。每个业务 crate(auth / config / workflow / message / health / ai / dialysis / plugin)只依赖 erp-core,不存在横向依赖。
结论: 依赖图干净,零循环依赖,具备未来拆分为微服务的前置条件。当前单体架构合理,无需急于拆分。
关注点: erp-server 依赖全部 crate,任何变更都触发完整重编译。erp-health/module.rs(1130 行路由注册)和 erp-message/module.rs(1054 行)是路由注册的单文件瓶颈。
3.2 数据库迁移治理
现状: 21 天内产生 100 个迁移(日均 5 个),其中单次健康表迁移达 1532 行(m20260423_000042)。
风险:
- 超大迁移在生产环境执行失败时,回滚成本极高
- 高频迭代表明 schema 尚未稳定
testing.md仍写着"迁移记录应为 50 条"(实际已 100 条)
建议:
- 建立迁移文件大小上限(单文件 < 500 行)
- 每个 Phase 结束后冻结 schema,后续走 ALTER 而非重建
- 生产环境迁移前必须 dry-run 验证
优先级: P2
3.3 事件系统补全
现状: 25 个事件类型中 14 个无消费者(55% 孤立率)。erp-health/event.rs 828 行集中了所有事件处理器注册逻辑,且零测试覆盖。
核心风险: 事件孤立率超过 50% 意味着大量事件发布是无效操作 — 写入数据库、消耗存储、但无人消费。更危险的是可能掩盖业务流程断裂。
建议:
- 对 14 个孤立事件逐一评估:删除无效事件 / 实现缺失消费者
- 为
erp-health/event.rs补充单元测试(至少覆盖每个消费者的核心路径) - 建立事件注册表:每个事件必须关联至少一个消费者(CLAUDE.md 铁律已在但未执行)
优先级: P1 — 事件是模块间通信的核心,孤立事件 = 功能缺失
4. 专家组 2:安全与合规
成员画像: 安全工程师 + 医疗合规专家 + 隐私保护专家
4.1 生产安全配置审计
| 项目 | 状态 | 风险 |
|---|---|---|
| JWT 密钥 | 启动时强制检查 __MUST_SET_VIA_ENV__ |
✅ 安全 |
| PII 加密 | AES-256-GCM + KEK 层级 + 开发模式拒绝生产 | ✅ 安全 |
| 密码哈希 | Argon2 + 随机 salt | ✅ 安全 |
| PostgreSQL RLS | 所有表启用 + 严格策略 | ✅ 安全 |
| 审计日志 | 哈希链防篡改 | ✅ 安全 |
| 限流失败模式 | Redis 不可用时默认 fail-open | ⚠️ 高风险 |
| SSE Token | 通过 query parameter 传递 JWT | ⚠️ 中风险 |
| AI API 密钥 | api_key = "" 空字符串(非强制占位符) |
⚠️ 中风险 |
| SQL 注入 | sanitize_identifier() + 参数化查询 |
✅ 安全 |
关键建议:
- P0 — 限流 fail-close: 生产环境必须设置
ERP__RATE_LIMIT__FAIL_CLOSE=true,否则 Redis 宕机 = 无限流 - P1 — SSE Token 安全: 改用短期一次性 ticket 替代 JWT query param,避免 token 出现在日志/历史记录
- P1 — AI 密钥统一: 与 JWT 密钥一样使用
__MUST_SET_VIA_ENV__占位符模式 - P2 — 审计日志写入: fire-and-forget 模式可能导致静默丢失,改为带重试队列
4.2 医疗数据合规性
已有能力:
- PII 加密体系完善(KEK → DEK → 数据加密 + HMAC 盲索引)
- PostgreSQL RLS 已在所有表启用
- 审计日志实现哈希链防篡改
- 多租户隔离通过 JWT 中间件 +
tenant_id列过滤
缺口:
| 缺口 | 影响 | 优先级 |
|---|---|---|
| 小程序知情同意页面缺失 | 医疗合规底线,后端 consent 实体存在但前端完全空白 | P1 |
| 数据保留策略缺失 | 无自动化数据过期/匿名化机制 | P2 |
| 访问日志粒度不足 | audit_logs 记录 API 调用但不记录具体访问了哪些患者数据 |
P3 |
5. 专家组 3:前端工程与用户体验
成员画像: 前端架构师 + UX 研究员 + 测试工程师
5.1 测试覆盖率分析
前端测试现状(Web + 小程序):
| 层面 | 文件数 | 测试文件数 | 覆盖率 |
|---|---|---|---|
| Web 页面 | 40+ | 0 | 0% |
| Web Store | 6 | 0 | 0% |
| Web Hook | 9 | 2 | ~22% |
| Web API | 30+ | 1 | ~3% |
| Web 组件 | 10 | 1 | ~10% |
| 小程序页面 | 40 | 0 | 0% |
| 小程序服务 | 25+ | 0 | 0% |
已有的 E2E 覆盖:
- Web:13 个 Playwright spec(患者旅程、预约、随访、体征、告警等核心流程)
- 小程序:4 个 automator spec(商城、健康查看、积分、体征录入)
核心判断: 前端测试覆盖率 <5% 是项目最大的质量风险。后端有 772 个测试保障,但前端 163 个文件几乎裸跑。E2E 测试慢且脆弱,不能替代单元测试 — 任何重构都可能引入不可检测的回归。
建议:
- P1 — Store 测试: 6 个 Zustand Store 是状态管理核心,每个至少 10 个测试
- P1 — API 契约测试: 30+ API 模块验证 URL / Method / 参数序列化
- P2 — 关键 Hook 测试:
usePaginatedData、usePermission、useApiRequest - P3 — 小程序测试: 从 BLE 管理器和安全存储工具开始
5.2 国际化评估
现状: 整个项目零 i18n — 所有 UI 字符串硬编码中文,无 i18n 框架。
影响评估:
- 短期:不影响 — 目标用户就是中文用户
- 中期:如有国际医疗机构客户,改造成本巨大
- 长期:取决于商业策略
建议: 不急于实施,但提取 antd.locale(zhCN) 和 dayjs.locale('zh-cn') 为可配置入口,建立防腐层。优先级 P4。
5.3 组件质量与大文件
Web 前端大文件(>500 行):
| 文件 | 行数 | 问题 | 建议 |
|---|---|---|---|
| Organizations.tsx | 622 | 组织树+部门树+岗位三合一 | 拆为 OrgTree + DeptTree + PositionPanel |
| ArticleEditor.tsx | 554 | 富文本+图片上传+表单 | 拆为 ArticleForm + ImageUploader |
| MainLayout.tsx | 554 | 菜单+侧边栏+头部+面包屑 | 拆为 Sidebar + Header + Breadcrumb |
| AppointmentList.tsx | 518 | 列表+筛选+创建弹窗 | 拆为 AppointmentFilter + AppointmentForm |
| VitalSignsChart.tsx | 485 | 多系列图表 | 拆为 ChartConfig + DataTransformer |
正面发现:
- 零
console.log残留 - 零硬编码 mock 数据
- API 层与页面层分离良好
- Zustand Store 职责清晰,无 god store
6. 专家组 4:代码质量与技术债
成员画像: 资深工程师 + 代码审查专家
6.1 后端热点文件治理
千行以上文件(按风险排序):
| 文件 | 行数 | 风险 | 说明 |
|---|---|---|---|
erp-health/service/points_service.rs |
1863 | 🔴 | 积分业务核心,所有积分逻辑集中 |
erp-plugin/manifest.rs |
1781 | 🟡 | 插件清单解析,变更频率低 |
erp-plugin/dynamic_table.rs |
1768 | 🟡 | DDL 生成,含安全防护 |
erp-plugin/data_service.rs |
1693 | 🟡 | 插件通用 CRUD |
erp-health/module.rs |
1130 | 🟠 | 路由注册瓶颈 |
erp-health/service/stats_service.rs |
1117 | 🟡 | 统计服务 |
erp-health/service/patient_service.rs |
1111 | 🟠 | 患者核心业务,tracing 已补全(20 条) |
erp-health/service/health_data_service.rs |
986 | 🟠 | 健康数据核心 |
erp-health/service/action_inbox_service.rs |
930 | 🟡 | Action inbox |
建议拆分策略:
points_service.rs→points_account+points_rule+points_exchange+points_checkinpatient_service.rs→patient_crud+patient_family+patient_tag+patient_exportmodule.rs(health) → 按子域拆路由组
优先级: P2 — 在下一次大改动时顺带重构
6.2 前端错误处理统一化
重复模式(18+ 文件):
// 被 18+ 个页面文件重复的内联错误提取
(err as { response?: { data?: { message?: string } } })?.response?.data?.message
已有的正确方案: api/client.ts 中的 handleApiError() 函数 — 但多数页面未使用。
建议:
- 统一使用
handleApiError()或useApiRequesthook - 批量替换 18 个文件中的内联模式
- 建立 ESLint 规则禁止该模式
优先级: P2
6.3 TypeScript 类型安全
any 使用统计:
- Web:10 处(3 个文件)— 集中在
usePaginatedData(5 处)和插件看板(4 处) - 小程序:28 处(12 个文件)— 集中在 BLE API 类型缺失(11 处)和微信登录响应(5 处)
根因分析:
usePaginatedData:Hook 重载签名问题,可通过泛型收窄解决- 小程序 BLE:Taro 的 BLE 类型定义不完整,需补充类型声明文件
优先级: P3 — 不影响运行时,但影响类型安全性
其他技术债:
| 项目 | 数量 | 优先级 |
|---|---|---|
| 编译器警告 | 40 个 | P3 |
unwrap() 调用(service 层生产风险) |
2 处(PluginHost::db / semaphore acquire) | P2 |
| TODO 注释 | 4 个(全部合理) | P4 |
| 过时迁移注释("应为 50 条") | 1 处 | P2 |
7. 专家组 5:项目管理与交付效率
成员画像: 项目经理 + 产品负责人
7.1 未提交工作积压
严重程度: 🔴 CRITICAL
现状: 工作树中存在 24 个已修改未提交文件 + 48 个未跟踪新文件(共 73 个),包括:
- 8 个 wiki 文件(文档更新)
- 4 个小程序源文件
- 2 个 Web 前端文件
- 8 个 Rust 业务代码文件(跨 5 个 crate)
- 7 个新的小程序医生端服务文件
- 8 个审计报告文档
- 5 个讨论记录
- 临时文件(
_temp/、mp_error.png、tmp_chart.png等)
风险: 本地故障 = 大量工作丢失 + 无法回溯变更历史 + 违反 CLAUDE.md 闭环工作法。
建议: 立即执行分类提交 — 按功能 / 文档 / 配置分组,并清理临时文件。
7.2 审计整改进度
整改率: 25 个审计发现中仅 1-2 个已处理(~8%,3 天后)
CRITICAL 项状态:
| ID | 问题 | 天数 | 状态 |
|---|---|---|---|
| C1 | 晚间血压数据丢失 | 3 | 已修复但 wiki 文档未更新 |
| C2 | 告警权限码拼写错误 (alert → alerts) |
3 | 未修复(5 分钟改动) |
HIGH 项状态:
| ID | 问题 | 状态 |
|---|---|---|
| H1 | 小程序透析模块完全缺失 | 未开始 |
| H2 | 小程序知情同意页面完全缺失 | 未开始 |
| H3 | 健康服务运行时日志严重不足 | 部分修复(patient_service tracing 已补全,其他大文件待跟进) |
建议:
- C2 立即修复 — 改
health.alert.manage→health.alerts.manage - 建立审计整改看板 — 每个 finding 分配责任人和截止日期
- 严格按 CRITICAL → HIGH → MEDIUM 顺序处理
7.3 Wiki 一致性
发现的不一致:
| 位置 | 问题 |
|---|---|
architecture.md:28-29 |
重复的插件列表行(一行有 assessment,一行没有) |
architecture.md:25 |
权限码数量 22(实际 erp-health 有 39 个) |
testing.md:124 |
迁移数 "应为 50 条"(实际已 96 条) |
database.md |
迁移文档仅覆盖到 m000091(实际 m000100) |
infrastructure.md |
更新日期停留在 2026-04-23 |
| Docker compose | PostgreSQL 16 vs wiki 声称的 18 |
| entity 计数 | architecture.md 说 44,实际列表有 45 个 |
建议: 安排 wiki 刷新会话,逐一校对数据。优先级 P2。
8. 优先级行动矩阵
🔴 P0 — 立即处理(今天)
| # | 行动 | 工作量 | 影响 |
|---|---|---|---|
| 1 | 提交并推送 73 个未提交文件 | 30 min | 防止工作丢失 |
| 2 | 修复 C2 告警权限码拼写 | 5 min | 消除最后一个 CRITICAL |
| 3 | 确认 C1 晚间血压修复并更新 wiki | 15 min | 关闭审计 CRITICAL |
🟠 P1 — 本周内
| # | 行动 | 工作量 | 影响 |
|---|---|---|---|
| 4 | 生产限流 fail-close 配置 | 1h | 生产安全 |
| 5 | 补全 erp-health/event.rs 测试 | 4h | 事件系统可靠性 |
| 6 | 孤立事件清理(14 个) | 8h | 消除功能断裂风险 |
| 7 | 前端 Store 单元测试(6 个 store) | 8h | 前端回归安全网 |
| 8 | 小程序透析模块(审计 HIGH H1) | 16h | 医疗完整性 |
| 9 | 小程序知情同意模块(审计 HIGH H2) | 8h | 合规底线 |
| 10 | health_data_service / action_inbox 补充 tracing | 4h | 可观测性 |
🟡 P2 — 本月内
| # | 行动 | 工作量 | 影响 |
|---|---|---|---|
| 11 | 前端错误处理统一化(18 个文件) | 4h | 代码一致性 |
| 12 | 大文件拆分(后端 6 个千行文件) | 16h | 可维护性 |
| 13 | 前端 API 契约测试 | 8h | 集成可靠性 |
| 14 | Wiki 数据一致性刷新 | 4h | 文档可信度 |
| 15 | 数据库迁移治理策略 | 8h | 运维安全 |
| 16 | unwrap() 调用替换(2 处) | 2h | 生产稳定性 |
🟢 P3 — 季度规划
| # | 行动 | 工作量 | 影响 |
|---|---|---|---|
| 17 | 编译器警告清理(40 个) | 8h | 代码清洁度 |
| 18 | 前端大组件拆分(20 个文件) | 16h | 可维护性 |
| 19 | TypeScript any 消除 | 8h | 类型安全 |
| 20 | 小程序测试基础设施 | 16h | 小程序质量保障 |
| 21 | Docker 配置与文档对齐 | 4h | 部署一致性 |
| 22 | 数据保留策略设计 | 16h | 合规准备 |
9. 总结与建议
整体评分:B+(良好,有明确的提升空间)
核心优势
- 架构设计出色 — 分层清晰、模块边界严格、事件驱动解耦、零循环依赖
- 安全基础扎实 — Argon2 + AES-256-GCM + PostgreSQL RLS + 审计哈希链
- 文档驱动开发 — 41 份设计规格、18 份讨论记录、12 页 wiki,决策有据可查
- API 层完整 — 328 路由覆盖所有业务,前端 API 层与后端 1:1 对应
- 前端架构清晰 — API / Store / Hook 三层分离,无 god store、无硬编码数据、无 console.log 残留
核心风险
- 前端测试空白 — <5% 覆盖率,任何重构都是冒险
- 审计整改缓慢 — 3 天仅处理 8% 的审计发现,CRITICAL C2(5 分钟改动)仍未修复
- 工作积压 — 55+ 文件未提交,违反闭环工作法
- 孤立事件 — 55% 的事件无消费者,可能是功能断裂的信号
- 可观测性不足 — 多个核心 service 文件仍缺 tracing 日志(patient_service 已补全)
下一步方向
当前阶段应遵循 「止血 → 补短板 → 治本」 路径:
- 止血(P0,今天): 提交积压文件 + 关闭审计 CRITICAL
- 补短板(P1,本周): 事件系统 + 前端测试 + 小程序透析/知情同意 + 安全配置
- 治本(P2,本月): 代码重构 + 文档刷新 + 迁移治理
- 持续改善(P3,季度): 类型安全 + 警告清理 + 测试扩展
一句话总结: 架构扎实、文档丰富的项目,当前需要暂停新功能开发,用 1-2 周集中补强测试和运维纪律,为下一阶段的功能扩展建立可靠的基础。