基于 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
128 lines
4.7 KiB
Markdown
128 lines
4.7 KiB
Markdown
---
|
||
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 节结构,更新为当前集成状态 |
|