Files
hms/wiki/erp-server.md
iven d22ad6088a
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+spec): 项目全景分析 + 功能完善设计规格
- 新增 wiki/erp-ai.md (AI 模块知识库页面)
- 修正 wiki/index.md 数据不一致 (crate 数 16、迁移 55、模块含 ai)
- 更新 wiki/erp-server.md (7 模块注册)
- 新增功能完善设计规格 (按钮权限 + AI 3 页面 + 小程序报告)
2026-04-25 20:22:24 +08:00

121 lines
4.2 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-server
updated: 2026-04-25
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)
→ 注册6个模块 → 初始化插件引擎+恢复插件 → 5个后台任务
→ 构建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 → 外部
4. 超时检查器 — 工作流任务超时处理
5. 随访逾期检查 — HealthModule 每 5 分钟扫描过期随访任务
## 3. 代码逻辑
### 中间件栈
```
CORS(可配置 origins) → IP限流(公开路由) → 用户限流(受保护路由) → JWT认证
```
### 配置结构
```
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-25 | 更新为 6 模块注册8 个环境变量,新增随访逾期检查后台任务 |
| 2026-04-23 | 重构为 5 节结构,更新为当前集成状态 |