Files
hms/wiki/erp-core.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

94 lines
3.3 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: erp-core
updated: 2026-04-23
status: stable
tags: [core, error, event-bus, module-trait, shared-types]
---
# erp-core
> 从 [[index]] 导航。关联: [[erp-server]] [[database]] [[wasm-plugin]] [[architecture]]
## 1. 设计决策
`erp-core` 是 L1 基础层,所有业务模块的唯一共同依赖。定义**跨模块共享的契约**,不含业务逻辑。
核心决策:
- **AppError 统一错误体系** — 6 种变体映射 HTTP 状态码,`?` 传播 + Axum `IntoResponse` 自动转换
- **EventBus 进程内广播** — `tokio::sync::broadcast` 实现零耦合通信
- **ErpModule 插件 trait** — 统一注册路由和事件处理器
- **BaseFields 强制多租户** — 所有实体基础字段模板
## 2. 关键文件 + 数据流
### 核心文件
| 文件 | 职责 |
|------|------|
| `crates/erp-core/src/error.rs` | AppError 定义、HTTP 映射、From 转换 |
| `crates/erp-core/src/events.rs` | DomainEvent、EventBus、EventHandler trait |
| `crates/erp-core/src/module.rs` | ErpModule trait、ModuleRegistry |
| `crates/erp-core/src/types.rs` | BaseFields、Pagination、ApiResponse、TenantContext |
| `crates/erp-core/src/lib.rs` | 模块导出入口 |
### 集成契约
| 方向 | 模块 | 接口 | 触发时机 |
|------|------|------|---------|
| 提供 → | erp-auth | ErpModule trait, AppError, EventBus | 模块实现 |
| 提供 → | erp-config | ErpModule trait, AppError | 模块实现 |
| 提供 → | erp-workflow | ErpModule trait, AppError, EventBus | 模块实现 |
| 提供 → | erp-message | ErpModule trait, AppError, EventBus | 模块实现 |
| 提供 → | erp-plugin | ErpModule trait, AppError, EventBus | 模块实现 |
| 消费 ← | [[erp-server]] | ModuleRegistry 组装 | 启动时 |
| 桥接 ← | [[wasm-plugin]] | EventBus → 插件 handle_event | 运行时 |
## 3. 代码逻辑
### 错误处理链
```
业务 crate (thiserror) → AppError → IntoResponse → HTTP JSON
数据库 (sea_orm::DbErr) → From 转换 → AppError (自动识别 duplicate key → Conflict)
```
响应格式:`{ "error": "not_found", "message": "资源不存在", "details": null }`
### 事件总线
```
EventBus::publish(DomainEvent) → broadcast channel → Receiver<DomainEvent>
事件字段: id(UUIDv7), event_type("user.created"), tenant_id, payload(JSON), timestamp
```
命名规则:`{模块}.{动作}``user.created`, `workflow.task.completed`
### 模块注册
```
ErpModule trait → ModuleRegistry::register() →
build_router(): 折叠所有模块路由 → Axum Router
register_handlers(): 注册事件处理器 → EventBus
```
### 共享类型
- `TenantContext` — 租户上下文tenant_id, user_id, roles, permissions, department_ids
- `Pagination` / `PaginatedResponse<T>` — 分页标准化(每页上限 100
- `ApiResponse<T>` — 统一信封 `{ success, data, message }`
**不变量**: erp-core 不依赖任何业务 crate只被依赖
**不变量**: 所有 API 使用 `/api/v1/` 前缀
**不变量**: tenant_id 从 JWT 中间件注入,应用层不可伪造
## 4. 活跃问题 + 陷阱
⚠️ crate 内部可用 `anyhow`,但跨 crate 边界必须转 `AppError`
⚠️ EventBus 当前为内存 broadcastoutbox 持久化通过后台任务实现
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-04-23 | 重构为 5 节结构,更新为已完全集成状态 |