Files
hms/wiki/erp-core.md
iven 40b5141832
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
docs: 全面更新 wiki 文档至当前实现状态
9 个 wiki 页面全部更新:
- index: 关键数字更新(15 crate/48 表/50 迁移/6 模块)
- erp-health: 从"规划中"更新为"已实现"(18 实体/14 权限)
- erp-server: 6 模块注册/8 环境变量/5 后台任务
- database: 50 迁移/48 表/健康模块迁移(m000042-m000050)
- frontend: 10 健康路由/12 共享组件/7 健康 API/3 单元测试
- miniprogram: 20 页面/10 服务/9 组件
- testing: 93 后端测试+3 前端测试/全链路验证结果
- erp-core: 新增 erp-health 集成契约
- architecture: 6 模块实现状态表/预约 CAS/PII 加密
2026-04-25 11:57:20 +08:00

103 lines
4.0 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-25
status: stable
tags: [core, error, event-bus, module-trait, shared-types]
---
# erp-core
> 从 [[index]] 导航。关联: [[erp-server]] [[database]] [[wasm-plugin]] [[architecture]] [[erp-health]]
## 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/sanitize.rs` | strip_html_tags()、sanitize_string() |
| `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-health]] | ErpModule trait, AppError, EventBus, sanitize | 模块实现 |
| 消费 ← | [[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`
健康模块事件:`patient.created`, `appointment.confirmed`, `appointment.cancelled`
### 模块注册
```
ErpModule trait → ModuleRegistry::register() →
build_router(): 折叠所有模块路由 → Axum Router
register_handlers(): 注册事件处理器 → EventBus
```
已注册模块AuthModule → ConfigModule → WorkflowModule → MessageModule → PluginModule → **HealthModule**
### 共享类型
- `TenantContext` — 租户上下文tenant_id, user_id, roles, permissions, department_ids
- `Pagination` / `PaginatedResponse<T>` — 分页标准化(每页上限 100
- `ApiResponse<T>` — 统一信封 `{ success, data, message }`
- `sanitize_string()` — HTML 标签过滤,用于用户输入清理
**不变量**: erp-core 不依赖任何业务 crate只被依赖
**不变量**: 所有 API 使用 `/api/v1/` 前缀
**不变量**: tenant_id 从 JWT 中间件注入,应用层不可伪造
## 4. 活跃问题 + 陷阱
⚠️ crate 内部可用 `anyhow`,但跨 crate 边界必须转 `AppError`
⚠️ EventBus 当前为内存 broadcastoutbox 持久化通过后台任务实现
⚠️ 微信注册路径的 display_name 需调用 `sanitize_string()` 防止 XSS
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-04-25 | 添加 erp-health 集成契约、健康模块事件、sanitize 模块引用 |
| 2026-04-23 | 重构为 5 节结构,更新为已完全集成状态 |