diff --git a/CLAUDE.md b/CLAUDE.md index 822d907..71fe0fe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -158,6 +158,7 @@ - 事件必须持久化到 `domain_events` 表(outbox 模式) - 事件处理失败记录到 dead-letter 存储 - 事件类型命名:`{模块}.{动作}` 如 `user.created`, `workflow.task.completed` +- **铁律:每个事件必须有至少一个消费者,否则功能不算完成。** 新增事件发布时必须同步实现消费者和对应测试。详见 `docs/discussions/2026-04-28-architecture-retrospective.md` §4。 ### 3.5 Rust 代码规范 diff --git a/docs/discussions/2026-04-28-architecture-retrospective.md b/docs/discussions/2026-04-28-architecture-retrospective.md new file mode 100644 index 0000000..9a65306 --- /dev/null +++ b/docs/discussions/2026-04-28-architecture-retrospective.md @@ -0,0 +1,91 @@ +# 架构反思讨论 — 17 天后审视设计决策 + +> 日期: 2026-04-28 | 参与者: 用户 + Claude + +## 背景 + +HMS 健康管理平台经过 17 天密集开发(301+ 次提交,63k 行 Rust,15 crate,67 表),功能层面已建成完整的医疗 SaaS 骨架。技术债清理策略已在另一次讨论中确定(安全→事件→测试三批次),本次聚焦于架构层面的反思和调整。 + +## 讨论要点 + +### 1. 架构做对的事 + +- **模块隔离** — ErpModule trait + EventBus + 事件驱动,模块间零直接依赖,撑住了 15 crate 的复杂度 +- **多租户从第一天设计** — tenant_id 在所有表、所有查询、中间件层统一处理 +- **UUID v7 主键** — 时间排序 + 分布式友好 +- **软删除 + 乐观锁** — 医疗数据不可丢失,审计追溯需要 + +### 2. 插件系统(WASM)的价值 + +**现状:** erp-plugin 运行时 + 动态表引擎 + 4 个示例插件(CRM/inventory/freelance/itops),约 5k-8k 行 Rust 投入,但 HMS 核心业务(erp-health 34 实体)使用原生模块。 + +**结论:积极使用,而非冻结或移除。** + +适合 WASM 插件的医疗场景: +- **标准化评估量表**(PHQ-9、GAD-7、SF-36)— 动态表定义 + CRUD + 评分逻辑 + 事件触发,最契合 WASM 能力 +- **医院自定义表单** — 不同医院的自定义入院问诊表、满意度问卷,多租户天然支持 + +落地路径: +- Phase 1:标准化评估量表插件(PHQ-9 先行) +- Phase 2:医院自定义表单(需要插件生成器) + +### 3. health 模块边界 + +**问题:** erp-health 承载 34 个实体,部分业务不属于"健康管理核心"。 + +**结论:** + +| 模块 | 去向 | 理由 | +|------|------|------| +| 积分商城(6 实体) | → 独立 erp-points | 通用积分能力,不应耦合在健康模块 | +| 透析管理(2-3 实体) | → 独立 erp-dialysis | 专科模块化,未来可扩展其他专科(慢病、康复) | +| 内容管理 | → 留在 health | 作为"健康宣教"功能的一部分,与患者教育紧密 | +| 线下活动 | → 留在 health | 社区义诊、体检活动是健康管理的一部分 | +| 危急值告警 | → 留在 health | 与体征数据强关联 | + +**erp-dialysis 的意义:** 专科模块化模式。未来可能有 erp-chronic(慢病)、erp-rehab(康复)等,通过事件与 health 核心交互。 + +### 4. 事件驱动架构的定位 + +**问题:** 13 种事件只消费了 3 个。事件驱动被当作"锦上添花"而非"核心机制"。 + +**根因分析:** +- 开发顺序是"API → 顺手发事件 → 消费者以后再写" +- 应该是"定义事件契约 → 实现消费者 → 实现发布者 → 测试闭环" +- 功能完成标准只有"API 返回 200",缺少"事件已被消费" + +**结论:建立制度约束。** + +规则:**每个事件必须有至少一个消费者,否则功能不算完成。** + +执行方式: +- PR 检查清单:新增事件发布必须同时实现消费者 +- event.rs 注册检查:每个常量必须有对应订阅 +- 测试覆盖:消费者必须有集成测试 +- 文档同步:事件契约在 wiki 维护 + +**旧事件补全优先级:** + +| 优先级 | 事件 | 消费者 | +|--------|------|--------| +| P0 | `health_data.critical_alert` | 危急值告警(已在技术债计划中) | +| P1 | `patient.created` | 欢迎消息 + 默认随访 | +| P1 | `appointment.confirmed` | 通知医护 + 通知患者 | +| P1 | `appointment.cancelled` | 释放号源 + 通知排队 | +| P1 | `follow_up.overdue` | 升级通知 | +| P2 | `lab_report.uploaded` | AI 解读 + 积分 | +| P2 | `article.published` | 推送通知 | +| P2 | `points.earned` | 余额变动通知 | + +## 结论 / 待定 + +**已决策:** +1. WASM 插件系统积极使用,评估量表作为第一个业务插件 +2. 积分拆 erp-points(已启动),透析拆 erp-dialysis(后续任务) +3. 事件驱动制度约束写入 CLAUDE.md + +**待定:** +- erp-dialysis 的拆分时机(建议在技术债清理完成后) +- 评估量表插件的详细设计(需单独讨论) +- 前后端是否需要 BFF 层(未展开讨论) +- 小程序技术选型(Taro 跨端能力未被利用)是否需要调整