Files
hms/docs/superpowers/specs/2026-04-26-platform-retrospective-and-evolution-design.md
iven 1265935fa3 chore: 设计规格文档 + 销售数据 + 脚本工具 + 根目录 monorepo 配置
- docs/: 设计规格、讨论记录、销售数据、健康管理文档
- scripts/: 辅助脚本
- package.json + pnpm-lock.yaml: monorepo 根配置
2026-04-28 00:20:37 +08:00

19 KiB
Raw Blame History

HMS 平台基座回顾与演进设计

日期: 2026-04-26 | 状态: Draft | 方法: 三专家多视角评审


1. 概述

1.1 回顾目的

HMS 健康管理平台经过 17 天密集开发2026-04-10 ~ 2026-04-26从 ERP 底座演进到包含 16 个 Rust crate、62 个前端页面、27 个小程序页面的综合医疗 SaaS 平台。本次回顾旨在:

  • 验证基座设计 — 星形依赖拓扑、ErpModule trait、事件总线、多租户策略是否经得起实践检验
  • 评估演进路径 — 从插件开发模式到原生模块开发的决策是否正确
  • 识别缺口与风险 — 通过多专家视角发现盲点
  • 制定演进路线 — 基于 P0/P1/P2 优先级指导后续迭代

1.2 评审方法

采用三专家独立评审,每个专家从不同视角分析相同的诊断和建议:

专家 视角 关注点
高级系统架构师 架构可持续性 模块边界、事件可靠性、技术债
医疗信息化专家 临床安全与合规 患者安全、PIPL 合规、领域模型
产品策略专家 ROI 与开发节奏 优先级、技术债量化、路线图现实性

1.3 核心结论

基座设计方向正确,但深度不足。 星形依赖、trait 抽象、事件总线等基础架构经受住了实践检验。但在临床安全(危急值告警未闭环)、合规(知情同意缺失)、事件可靠性(无重放机制)方面存在需立即修复的缺口。插件系统已验证可行性但对 HMS 核心业务贡献有限,建议有条件冻结。


2. 基座设计验证

2.1 评分总览

维度 评分 说明
模块边界 ★★★★ 星形拓扑零循环依赖trait 契约清晰
ErpModule trait ★★★★ 生命周期/权限/事件/健康检查统一接口
事件总线 ★★★☆ 基础设施扎实broadcast+outbox但无重放机制消费侧不完整
多租户 ★★★☆ JWT→TenantContext 全链路贯通,但缺 RLS 兜底和集成测试
权限体系 ★★★★ RBAC + 行级数据权限 + 按钮级控制
插件系统 ★★★☆ CRUD 场景验证通过,医疗场景天花板明显
API 一致性 ★★★★ 统一 envelope、分页、OpenAPI 自动文档
数据库迁移 ★★★★ 59 个迁移幂等、可回滚、fixup 模式健康
测试覆盖 ★☆☆☆ 36 后端 + 3 前端,覆盖率 < 5%
合规性 ★☆☆☆ 知情同意缺失审计不完整PIE 加密范围不足

2.2 星形依赖拓扑

                    erp-core (L1)
                   /   |    \    \      \        \
          erp-auth  workflow  message  config  erp-health  erp-plugin  erp-ai
                   \   |    /    /      /        /        /
                        erp-server (L3, 组装入口)
  • erp-core:零业务依赖,纯净基础层
  • 7 个业务 crate各只依赖 erp-core,兄弟间无横向依赖
  • erp-server:唯一组装点,负责路由合并和模块初始化
  • 无循环依赖 — 架构师验证通过

2.3 ErpModule trait

当前 trait 提供统一的模块接口:

  • 身份name() / id() / version()
  • 依赖声明dependencies() — 用于拓扑排序启动顺序
  • 生命周期on_startup() / on_shutdown() / health_check()
  • 多租户on_tenant_created() / on_tenant_deleted()
  • 权限自描述permissions() — 模块声明自己需要的权限码
  • 事件订阅register_event_handlers() / as_any()

已知张力:路由注册不在 trait 中,而是通过各模块的 inherent method (public_routes() / protected_routes()) 手动在 main.rs 中合并。原因是 Axum 的 Router<S> 泛型约束不适合 trait object。这是务实的妥协但在添加新模块时有 boilerplate 成本。

2.4 事件总线

实现机制tokio::sync::broadcast (容量 1024) + domain_events 表持久化best-effort+ Outbox relay (5秒轮询3次重试)

发布侧(已识别的事件类型):

模块 事件类型数 示例
erp-auth 10 user.login, user.created, role.created
erp-workflow 4 process_instance.started, task.completed
erp-message 1 message.sent
erp-health 13 patient.created, health_data.critical_alert, follow_up.overdue
erp-plugin 2+ plugin.config.updated, plugin.trigger.*

消费侧(已识别的订阅者):

订阅者 订阅方式 处理的事件
erp-message subscribe() 全量 appointment.*, process_instance.*, task.*
erp-health register_handlers_with_state workflow.task.completed
erp-plugin 通知 subscribe_filtered("plugin.trigger.*") 插件触发通知
outbox relay 轮询 DB 重发 pending 事件

已识别缺陷

  1. 无重放机制 — 内存 broadcast服务重启后未消费的事件丢失
  2. 无幂等保护follow_up.overdue 每 6 小时检查会重复发布同一条逾期事件
  3. 全量订阅 — erp-message 使用 subscribe() 而非 subscribe_filtered(),所有事件都经过消息模块

2.5 多租户

已实现

  • JWT claims 提取 tenant_idTenantContext 注入请求扩展
  • 所有 Entity 含 tenant_id 字段BaseFields 统一
  • 所有 DomainEvent 携带 tenant_id
  • on_tenant_created() / on_tenant_deleted() 钩子auth 和 health 已实现)
  • 部门级数据范围(department_ids 在 TenantContext 中)

缺失

  • 无 PostgreSQL RLS policy 作为兜底层
  • 无强制 tenant_id 过滤的查询层机制 — 依赖每个 service 手动 .filter()
  • 当前实际只有 default_tenant微信登录硬编码使用 default_tenant_id
  • 无多租户管理 API创建/配置/迁移)

3. 演进路径回顾

3.1 时间线

4/10-4/16  基座搭建 (Phase 1-6)
           → core → auth → config → workflow → message
           → 全部原生 Rust 模块30+ 数据库表

4/13-4/18  WASM 插件实验
           → 插件系统设计与实现 (Wasmtime + WIT bindgen)
           → CRM (5实体) → Inventory (6实体) → Freelance → ITOps
           → 证明CRUD 密集型领域可行,沙盒隔离有效
           → 跨插件数据引用未解决

4/23-4/26  HMS 分叉 — 健康模块原生开发
           → 18+ 强类型实体 (患者/家属/医生/预约/排班/随访/咨询/体征/化验/透析/诊断/积分...)
           → PII 加密 (AES-256-GCM)、脱敏管道
           → AI 模块 (4 SSE 流式端点 + 3 REST 端点)
           → 微信小程序 (27 页面)
           → 按钮级权限控制

3.2 从插件到原生的决策链

原始插件愿景(设计规格 2026-04-13

  • 平台模块原生,行业模块 WASM 插件
  • 插件通过 9 个 Host API 函数通信db_insert/query/update/delete、event_publish、config_get 等)
  • 数据存 JSONB 动态表,路由自动生成
  • UI 配置驱动,通用 PluginCRUDPage 组件

健康模块原生的 5 个硬限制(设计规格 2026-04-23 §1.3

限制 影响 不可妥协原因
20 实体上限 健康平台轻松超过 18+ 实体已是最低合理粒度
JSONB 存储 无强类型、无外键约束 医疗数据需要引用完整性和精确索引
无自定义 API 只有自动 CRUD 趋势分析/统计报表/日历视图无法实现
无文件上传 沙盒阻止文件系统访问 化验单/体检报告需要文件存储
WASM 沙盒限制 无 native crypto/外部 API/后台任务 PII 加密、微信集成、定时任务全部需要

3.3 得失评估

得 — 正确的决策:

决策 收益
星形依赖拓扑 模块独立性强,可独立测试和替换
ErpModule 统一接口 新模块注册流程标准化
事件总线 跨模块解耦通信的基础设施已就绪
JWT→TenantContext 多租户全链路贯通
健康模块原生 不受沙盒限制,加密/文件/后台任务全部可用
插件实验 验证了平台灵活性CRM/库存可正常使用

失 — 需要修正的问题:

决策 代价
插件系统投入过大 22,000 行代码41% Rust 总量),对 HMS 核心业务贡献接近零
积分系统混入 health 8 实体/12+ 路由,增加合规复杂度和数据泄露面
事件消费侧忽视 13 个事件只有 3 个被消费,危急告警和逾期通知空转
测试覆盖极薄 36 后端 + 3 前端测试,覆盖率 < 5%
合规意识不足 知情同意缺失、审计不完整、PIE 加密范围不足

4. 三专家评审摘要

4.1 高级系统架构师

诊断准确度7/10 — 四个张力都真实存在,但优先级和细节有偏差。

关键补充:

发现 严重程度
WIT 接口是同步调用阻塞WASM 运行时嵌入主进程(故障隔离不足) 架构隐患
EventBus 内存 broadcast 无重放机制,服务重启丢事件 P1
follow_up.overdue 无幂等保护,每 6h 检查重复发布 P0
erp-message 用 subscribe() 全量订阅,性能隐患 P1
RLS 不是 P0多租户集成测试才是 观点
积分系统8 独立实体、12+ 路由)不应在 erp-health 内 共识
缺监控/可观测性、数据备份策略、API 版本升级路线图 盲点

核心原则:先补测试再重构,先修事件再上功能,先验证再加固。

4.2 医疗信息化专家

发现了比原始诊断更深层的临床安全风险。

新发现 严重程度
危急值阈值全部硬编码(收缩压 180/80、心率 150/40不可配置 P0
daily_monitoring 表体征数据不经过危急值检测(合并前遗留) P0
过敏史更新直接覆盖,无变更历史 P0
知情同意完全缺失(搜索 consent/同意/授权/隐私 零结果) P0 — PIPL 违规
只有身份证号存储加密,姓名/过敏史/诊断/咨询内容明文 P1
审计日志不完整 — 只有预约状态变更记录前后值 P1
ip_addressuser_agent 从未被填充 P1
读操作(查看患者详情/化验报告)完全没有审计记录 P1
诊断记录 icd_code 只做字符串约束,无格式校验,无同行审核 P1

合规评估PIPL 第 29 条要求处理敏感个人信息须取得单独同意。医疗数据属于敏感个人信息。知情同意缺失是法律红线。

领域模型建议积分系统6 实体 + 2 线下活动实体)应拆分为独立 erp-pointserp-engagement 模块,与健康数据分离以降低合规复杂度。

4.3 产品策略专家

开发节奏不可持续但不必恐慌。

分析 结论
峰值 68 提交/天fix 提交占 21.6% 短期冲刺可以,长期人会耗竭
41% Rust 代码在插件系统,对核心业务贡献接近零 最大 ROI 失衡
单人 + AI 的"速度幻觉" 68 提交/天 = 审查不足,积分混入 health 就是例证
测试覆盖 < 5% 正确水位不是 80%,而是关键路径不回退(目标 50-80 用例3-4 天)

关键风险缓解建议:

  • ADR架构决策记录强制化
  • 医疗安全代码双人外部 review
  • 每日提交上限 15 次
  • 每月需求裁剪

V2 血透路线图评估:技术储备已够(dialysis_service 286 行骨架在),但缺市场验证。建议先做 3-5 家目标客户调研,确认需求后再做 2 周 MVP 试运行。


5. 共识优先级

5.1 三专家加权共识矩阵

议题 架构师 医疗专家 产品策略 共识等级
危急值告警闭环 P0 P0 + 硬编码 P0 三方一致
知情同意 (PIPL) 未涉及 P0 P0 两方一致
审计日志补全 未涉及 P1 P0 P0-P1
EventBus 可靠性 P1 未涉及 P0 P0-P1
随访逾期通知 P0 P0 P0 三方一致
积分系统拆分 应拆 应拆(合规) 占 19.5% 三方一致
RLS 不是 P0 P1 P0 有分歧
插件系统 有条件冻结 未涉及 冻结 两方一致
测试覆盖 先补测试 上线前必修 50-80 用例 三方一致
V2 血透 未涉及 缺标准流程 先调研 两方一致

5.2 P0 — 上线前必修(估计 2-3 周)

序号 工作量 负责 crate 说明
1 危急值告警消费者 1 天 erp-health + erp-message health_data.critical_alert → 推送通知给责任医护
2 危急值阈值可配置化 2 天 erp-health 硬编码阈值改为数据库配置,支持科室/年龄差异化
3 daily_monitoring 合并后告警验证 1 天 erp-health 确认合并到 vital_signs 后所有体征数据都经过告警检测
4 随访逾期通知 1 天 erp-health + erp-message follow_up.overdue → 催办通知 + 幂等保护
5 知情同意记录 3 天 erp-health 患者数据处理同意获取和记录机制
6 审计日志补全 3 天 erp-core + erp-health 临床数据变更记录前后值、读操作审计、IP/UA 填充
7 EventBus 持久化增强 2 天 erp-core 服务重启不丢事件 + overdue 事件幂等

5.3 P1 — 治理2-4 周)

序号 工作量 说明
8 积分系统剥离 5 天 从 erp-health 拆分为独立 erp-engagement crate
9 关键路径测试 4 天 多租户隔离、患者安全路径、预约并发50-80 用例)
10 插件系统冻结声明 0.5 天 保留代码README 声明实验性,不再投入
11 erp-message 改用 subscribe_filtered 1 天 减少无效事件传递
12 统一事件消费模式 2 天 消除 register_event_handlers vs on_startup 双路径
13 过敏史变更历史 1 天 更新时记录旧值

5.4 P2 — 扩展(后续迭代)

序号 前置条件
14 PostgreSQL RLS P1 测试覆盖完成
15 血透专科 3-5 家客户调研完成
16 OCR 化验单提取 血透验证后
17 IM 咨询 血透验证后
18 health 模块按子域重组目录 P1 测试覆盖完成
19 前端测试覆盖提升 P1 后端测试完成
20 动态菜单系统 现有计划可用

6. 风险与缓解

6.1 开发模式风险

风险 影响 缓解措施
单人认知单点 一人理解 16 个 cratebus factor = 1 ADR 强制化,关键决策留文档
AI 生成"编译对但逻辑错" 危急值阈值硬编码、积分混入 health 就是例证 医疗安全代码双人外部 review
速度幻觉 68 提交/天 = 审查不足 每日提交上限 15 次
AI 回音壁 AI 不质疑需求合理性 每月需求裁剪,引入真实用户反馈

6.2 临床安全风险

风险 影响 缓解措施
危急值告警未闭环 危急体征值无人响应,可致患者安全事故 P0-1实现消费者 + 阈值可配置
逾期随访无催办 患者失访,影响医疗质量指标 P0-4实现通知 + 幂等保护
过敏史无变更记录 无法追溯过敏史变更,用药风险 P1-13添加变更历史
告警阈值硬编码 无法适应儿科/老年科/血透科不同范围 P0-2数据库配置

6.3 合规风险

风险 法规依据 缓解措施
知情同意缺失 PIPL 第 29 条 P0-5实现同意记录机制
审计不完整 医疗机构信息化建设要求 P0-6补全审计日志
PIE 加密范围不足 PIPL 第 51 条 P1扩展加密到姓名/过敏史/诊断
数据删除权缺失 PIPL 第 47 条 P2实现患者数据导出/删除

6.4 架构风险

风险 影响 缓解措施
EventBus 无重放 服务重启丢事件 P0-7增强持久化
全量订阅 性能隐患,所有事件经消息模块 P1-11改用过滤订阅
路由手动合并 新模块 boilerplate 成本 长期ErpModule trait v2
erp-health 过大 18+ 实体,维护复杂度上升 P2-18按子域重组

7. 附录

7.1 关键文件索引

文件 说明
crates/erp-core/src/module.rs ErpModule trait + ModuleRegistry (拓扑排序)
crates/erp-core/src/events.rs EventBus 实现 (broadcast + outbox)
crates/erp-core/src/types.rs TenantContext, BaseFields, Pagination
crates/erp-core/src/rbac.rs 权限/角色检查
crates/erp-server/src/main.rs 服务组装和手动路由合并
crates/erp-server/src/state.rs AppState + FromRef 桥接
crates/erp-server/src/outbox.rs Outbox relay (5s 轮询, 3 次重试)
crates/erp-auth/src/middleware/jwt_auth.rs JWT 认证 + TenantContext 注入
crates/erp-health/src/module.rs HealthModule (ErpModule 实现 + 后台任务)
crates/erp-health/src/event.rs 健康模块事件订阅
crates/erp-health/src/crypto.rs AES-256-GCM 加密
crates/erp-health/src/service/masking.rs PII 脱敏管道
crates/erp-plugin/src/engine.rs WASM 插件引擎
docs/superpowers/specs/2026-04-13-wasm-plugin-system-design.md 插件系统设计规格
docs/superpowers/specs/2026-04-23-health-management-module-design.md 健康模块设计规格
docs/discussions/2026-04-18-plugin-platform-brainstorm.md 插件平台演进讨论

7.2 迁移历史时间线

日期 迁移范围 说明
4/10-11 核心平台 租户、用户、凭证、角色、权限、组织、部门、岗位
4/12 配置 + 工作流 字典、菜单、设置、编号规则 + 流程定义/实例/令牌/任务
4/13 消息 + 审计 模板、消息、订阅 + 审计日志
4/14 修复 唯一索引与软删除冲突、标准字段补全
4/16 领域事件 domain_events 表
4/17 插件系统 插件表、动态表
4/18 搜索 + 权限 pg_trgm、实体注册表、数据范围
4/19 关联修复 用户部门、CRM 修复、插件市场
4/23 健康表 患者、微信用户、文章
4/24 索引修复 3 个 fixup 迁移
4/25 健康扩展 患者ID哈希、医生名、透析/化验增强、AI 表、积分
4/26 业务改进 诊断、列重命名、daily_monitoring 合并、菜单种子

总计59 个迁移17 天内。 fixup 迁移模式健康(不编辑旧迁移,单独修复)。

7.3 项目统计快照 (2026-04-26)

指标
Rust crate 数 16
Rust 代码行 ~57,000
前端文件数 174 (TSX/TS)
前端页面 62
小程序页面 27
数据库迁移 59
数据库表 30 基础 + 18 健康 + 3 AI
后端测试 36
前端单元测试 3
Git 提交 237
开发周期 17 天

本文档由三专家多视角评审生成,作为 HMS 平台基座演进的参考基准。后续实施计划将基于本文档的优先级排序展开。