Files
hms/wiki/architecture.md
iven ca50d32f6e
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
feat(health): 添加 erp-health 健康管理模块骨架
新建 erp-health 原生 Rust crate,覆盖设计规格中定义的 5 大业务域:

- 16 个 SeaORM Entity(患者/家属/标签/医生/健康档案/体征/化验单/预约/排班/随访/咨询等)
- 16 表数据库迁移(含索引、外键、默认值、可回滚)
- 40+ API 路由骨架(患者管理/健康数据/预约排班/随访/咨询/医生管理)
- 12 个权限声明(health.patient/health-data/appointment/follow-up/consultation/doctor 各 .list/.manage)
- DTO / Service / Handler / Event 四层架构,Service 使用 todo!() 占位
- erp-server 集成:模块注册 + AppState FromRef 桥接 + 路由挂载

同步更新 CLAUDE.md 项目进度、wiki 知识库、设计规格文档。
2026-04-23 19:59:22 +08:00

103 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 架构决策记录
updated: 2026-04-23
status: stable
tags: [architecture, decisions, design-principles]
---
# 架构决策记录
> 从 [[index]] 导航。关联: [[erp-core]] [[erp-server]] [[database]] [[wasm-plugin]] [[erp-health]]
## 1. 设计决策
### 模块化单体 + 渐进式拆分
模块间零直接依赖,跨模块通信通过事件总线和 trait 接口。`ErpModule` trait 天然支持未来按模块拆分为微服务。
### HMS 架构:原生模块 + 插件并存
HMS 继承 ERP 底座的所有基础模块,`erp-health` 作为原生 Rust 模块承载医疗业务。WASM 插件系统保留但非 HMS 主要扩展方式。
```
HMS 平台
├── 基础模块(继承 ERP: auth, config, workflow, message, plugin
├── 核心业务模块: erp-health原生 Rust
└── 可选插件: crm, inventory, freelance, itopsWASM
```
### 为什么 erp-health 用原生模块?
医疗业务需要 16+ 强类型实体、自定义 API趋势分析/统计报表)、文件上传、未来 AI 集成。WASM 插件的 JSONB 动态存储和 20 实体上限无法满足。详见 [[erp-health]]。
### 为什么用 UUIDv7
时间排序 + UUID 唯一性 + 接近自增 ID 的索引性能。多租户 SaaS 下不同租户数据不会因 ID 冲突互相影响。
### 为什么 tenant_id 不在 API 路径中?
从 JWT 提取,中间件注入 `TenantContext`。防止:手动改 URL 越权 / API 暴露租户信息 / 忘记检查权限。管理员接口例外。
### 为什么错误类型跨 crate 用 thiserror
`anyhow` 无类型信息,无法精确映射 HTTP 状态码。`thiserror``AppError` → 400/401/403/404/409/500。
## 2. 关键文件 + 数据流
### 模块依赖图
```
erp-core (L1)
|
+--------------+--------------+--------------+-----------+
| | | | |
erp-auth erp-config erp-workflow erp-message erp-health (L2)
| | | | |
+--------------+--------------+--------------+-----------+
|
erp-server (L3: 唯一组装点)
|
erp-plugin (WASM 插件运行时)
```
**禁止**: L2 间直接依赖 / L1 依赖业务模块 / 绕过事件总线
### 技术选型
| 选择 | 理由 |
|------|------|
| Axum 0.8 | Tokio 团队维护tower 生态,类型安全路由 |
| SeaORM 1.1 | 异步、类型安全、迁移工具完善 |
| PostgreSQL 18 | 企业级JSON 支持,扩展丰富 |
| Redis 7 | 缓存 + 限流 token bucket |
| React 19 + Ant Design 6 | 企业后台 UI 标配 |
| Zustand 5 | 极简状态管理 |
| Wasmtime 43 | WASM 沙箱Component ModelFuel 限制 |
### 集成契约
| 方向 | 模块 | 触发时机 |
|------|------|---------|
| 定义 → | [[erp-core]] | 所有模块的 trait 和类型 |
| 组装 ← | [[erp-server]] | 模块注册和启动 |
| 扩展 ← | [[wasm-plugin]] | 插件通过 Host Bridge 桥接 |
## 3. 代码逻辑
**不变量**: 模块间只通过 EventBus 和 trait 通信,无直接依赖
**不变量**: 所有数据表必须含 `tenant_id`,查询自动过滤
**不变量**: UUID v7 作为主键
**不变量**: 软删除,不硬删除
**不变量**: 所有 API 使用 `/api/v1/` 前缀
## 4. 活跃问题 + 陷阱
⚠️ 当前共享数据库 + tenant_id 过滤,未来可扩展为 Schema 隔离或数据库隔离
⚠️ EventBus 内存 broadcast 需 outbox 持久化保障(已通过后台任务实现)
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-04-23 | 重构为 5 节结构,删除 erp-common 引用,精简技术选型表 |