Files
hms/wiki/erp-server.md
iven 75cd305996
Some checks failed
CI / security-audit (push) Has been cancelled
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
docs(wiki): 全景梳理 — 更新 9 个 wiki + CLAUDE.md scope + 头脑风暴记录
基于 3 个并行探索代理的全面扫描结果,更新 wiki 数据至实际状态:
- index.md: 18 crate / 76 迁移 / 44 实体 / 77k 行 / 409 提交
- erp-health.md: 44 实体 / 21 handler / 22 权限 / 25 事件 / 6 消费者
- erp-server.md: 9 后台任务 / RLS 中间件栈
- architecture.md: 新增 erp-ai/dialysis 到依赖图 / 测试覆盖表
- testing.md: 225 单元 + 159 集成 / 4 模块零测试警告
- database.md: 76 迁移 / RLS+哈希链+盲索引+Dead Letter
- erp-core.md: PiiCrypto 加密体系 / EventBus 完整描述
- frontend.md: 163 文件 / 5 store / 10 API 文件
- CLAUDE.md: 新增 health/ai/dialysis/assessment scope

头脑风暴 4 个议题决策:
- dialysis: 接入激活
- 测试: 按风险排序(workflow > ai > message > config)
- AI: 数据桥接优先
- 路线图: AI 驱动 3 个月 5 Phase
2026-04-28 14:53:04 +08:00

128 lines
4.7 KiB
Markdown
Raw Permalink 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-server
updated: 2026-04-28
status: stable
tags: [server, axum, assembly, entry-point]
---
# erp-server
> 从 [[index]] 导航。关联: [[erp-core]] [[infrastructure]] [[database]] [[frontend]]
## 1. 设计决策
- **唯一组装点** — 不含业务逻辑,只负责把所有模块组装成可运行服务
- **配置优先** — `config` crate 从 TOML + 环境变量加载,`ERP__` 前缀覆盖
- **严格启动序列** — 每步失败即终止,不做部分启动
- **安全检查** — 拒绝默认 JWT 密钥 / 数据库 URL / 加密密钥
## 2. 关键文件 + 数据流
### 核心文件
| 文件 | 职责 |
|------|------|
| `crates/erp-server/src/main.rs` | 服务启动入口639 行) |
| `crates/erp-server/src/state.rs` | AppState 定义117 行) |
| `crates/erp-server/src/config.rs` | 配置 struct + 加载逻辑87 行) |
| `crates/erp-server/src/db.rs` | SeaORM 连接池配置 |
| `crates/erp-server/src/outbox.rs` | Domain event outbox 处理器 |
| `crates/erp-server/src/middleware/rate_limit.rs` | IP/用户限流176 行) |
| `crates/erp-server/config/default.toml` | 默认配置(密钥为占位符) |
### 启动流程
```
AppConfig::load() → 安全检查 → init_tracing → db::connect → Migrator::up
→ 种子数据(默认租户+管理员) → Redis客户端 → EventBus(容量1024)
→ 注册7个模块 → 初始化插件引擎+恢复插件 → 8+后台任务
→ 构建Router → bind + serve → 优雅关闭(CTRL+C/SIGTERM)
```
### 注册的 7 个模块
AuthModule → ConfigModule → WorkflowModule → MessageModule → PluginModule → **HealthModule****AiModule**
### AppState
```
AppState {
db: DatabaseConnection,
config: AppConfig,
event_bus: EventBus,
module_registry: ModuleRegistry,
redis: redis::Client,
default_tenant_id: Uuid,
plugin_engine: PluginEngine,
plugin_entity_cache: moka::Cache (1000容量, 5分钟TTL),
// HealthModule 状态通过 FromRef 提取
}
```
### 集成契约
| 方向 | 模块 | 接口 | 触发时机 |
|------|------|------|---------|
| 组装 → | erp-auth | `AuthModule` | 启动时注册 |
| 组装 → | erp-config | `ConfigModule` | 启动时注册 |
| 组装 → | erp-workflow | `WorkflowModule` | 启动时注册 |
| 组装 → | erp-message | `MessageModule` | 启动时注册 |
| 组装 → | erp-plugin | `PluginModule` | 启动时注册 |
| 组装 → | [[erp-health]] | `HealthModule` | 启动时注册 |
| 组装 → | [[erp-ai]] | `AiModule` | 启动时注册 |
| 依赖 ← | [[erp-core]] | ErpModule trait, EventBus | 所有模块 |
| 依赖 ← | [[infrastructure]] | PostgreSQL, Redis | 连接 |
### 后台任务
1. 消息监听器 — EventBus → MessageModule
2. 插件通知 — EventBus → PluginModule
3. Outbox relay — domain_events → 外部LISTEN/NOTIFY + 30s 兜底轮询)
4. 事件清理 — 归档 + 清理过期事件
5. 超时检查器 — 工作流任务超时处理60s
6. 随访逾期检查 — HealthModule 每 6 小时扫描过期随访任务
7. 积分过期清理 — HealthModule 每 24 小时处理过期积分
8. 预约提醒 — HealthModule 每 1 小时扫描即将到来的预约
9. 插件恢复 — 启动时恢复已安装插件
## 3. 代码逻辑
### 中间件栈
```
CORS(可配置 origins) → Tenant RLS(SET app.current_tenant_id) → JWT认证 → 用户限流(100 req/min/user, Redis)
```
公开路由额外IP 限流 + 账户锁定
### 配置结构
```
AppConfig
├── server: { host: "0.0.0.0", port: 3000 }
├── database: { url, max_connections: 20, min_connections: 5 }
├── redis: { url }
├── jwt: { secret, access_token_ttl: 15min, refresh_token_ttl: 7d }
├── auth: { super_admin_password }
├── wechat: { appid, secret }
├── health: { aes_key, hmac_key }
└── log: { level: "info" }
```
**不变量**: 8 个环境变量在 default.toml 中都是 `__MUST_SET_VIA_ENV__` 占位符必须通过环境变量设置database.url, jwt.secret, redis.url, auth.super_admin_password, wechat.appid, wechat.secret, health.aes_key, health.hmac_key
**不变量**: 启动顺序不可变更 — 数据库必须先于迁移,迁移必须先于模块注册
## 4. 活跃问题 + 陷阱
⚠️ 后端必须从 `crates/erp-server/` 目录启动(或通过环境变量覆盖所有配置)
⚠️ 种子数据自动创建默认租户和管理员,重复启动幂等
## 5. 变更记录
| 日期 | 变更 |
|------|------|
| 2026-04-28 | 更新后台任务为 9 个、中间件栈含 RLS、outbox relay 机制完善 |
| 2026-04-25 | 更新为 7 模块注册8 个环境变量,新增随访逾期检查后台任务 |
| 2026-04-23 | 重构为 5 节结构,更新为当前集成状态 |