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

4.7 KiB
Raw Permalink Blame History

title, updated, status, tags
title updated status tags
erp-server 2026-04-28 stable
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 → HealthModuleAiModule

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 节结构,更新为当前集成状态