feat(health): 添加 erp-health 健康管理模块骨架
新建 erp-health 原生 Rust crate,覆盖设计规格中定义的 5 大业务域: - 16 个 SeaORM Entity(患者/家属/标签/医生/健康档案/体征/化验单/预约/排班/随访/咨询等) - 16 表数据库迁移(含索引、外键、默认值、可回滚) - 40+ API 路由骨架(患者管理/健康数据/预约排班/随访/咨询/医生管理) - 12 个权限声明(health.patient/health-data/appointment/follow-up/consultation/doctor 各 .list/.manage) - DTO / Service / Handler / Event 四层架构,Service 使用 todo!() 占位 - erp-server 集成:模块注册 + AppState FromRef 桥接 + 路由挂载 同步更新 CLAUDE.md 项目进度、wiki 知识库、设计规格文档。
This commit is contained in:
123
wiki/database.md
123
wiki/database.md
@@ -1,73 +1,92 @@
|
||||
# database (数据库迁移与模式)
|
||||
---
|
||||
title: 数据库迁移与模式
|
||||
updated: 2026-04-23
|
||||
status: stable
|
||||
tags: [database, seaorm, migration, multi-tenant]
|
||||
---
|
||||
|
||||
## 设计思想
|
||||
# 数据库迁移与模式
|
||||
|
||||
数据库迁移使用 SeaORM Migration 框架,遵循以下原则:
|
||||
> 从 [[index]] 导航。关联: [[erp-core]] [[erp-server]] [[infrastructure]]
|
||||
|
||||
- **所有表必须包含标准字段** — `id`(UUIDv7), `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by`, `deleted_at`, `version`
|
||||
- **软删除** — 不执行硬删除,设置 `deleted_at` 时间戳
|
||||
## 1. 设计决策
|
||||
|
||||
- **SeaORM Migration** — 异步、类型安全、幂等(`if_not_exists`),每个迁移必须实现 `down()` 可回滚
|
||||
- **所有表必须含标准字段** — `id`(UUIDv7), `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by`, `deleted_at`, `version`
|
||||
- **软删除** — 不硬删除,设置 `deleted_at` 时间戳
|
||||
- **乐观锁** — 更新时检查 `version` 字段
|
||||
- **多租户隔离** — 所有业务表必须含 `tenant_id`,查询时自动过滤
|
||||
- **幂等迁移** — 使用 `if_not_exists` 确保可重复执行
|
||||
- **可回滚** — 每个迁移必须实现 `down()` 方法
|
||||
- **多租户** — 所有业务表含 `tenant_id`,中间件自动过滤
|
||||
|
||||
## 代码逻辑
|
||||
## 2. 关键文件 + 数据流
|
||||
|
||||
### 核心文件
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `crates/erp-server/migration/src/lib.rs` | Migrator 注册所有迁移 |
|
||||
| `crates/erp-server/migration/src/m*.rs` | 41 个迁移文件 |
|
||||
| `crates/erp-core/src/types.rs` | BaseFields 标准字段定义 |
|
||||
|
||||
### 迁移命名规则
|
||||
|
||||
### 迁移文件命名规则
|
||||
```
|
||||
m{YYYYMMDD}_{6位序号}_{描述}.rs
|
||||
例: m20260410_000001_create_tenant.rs
|
||||
```
|
||||
|
||||
### 当前表结构
|
||||
### 当前表概览(30 张)
|
||||
|
||||
**tenant 表** (唯一已实现的表):
|
||||
| 列名 | 类型 | 约束 |
|
||||
|------|------|------|
|
||||
| id | UUID | PK, NOT NULL |
|
||||
| name | STRING | NOT NULL |
|
||||
| code | STRING | NOT NULL, UNIQUE |
|
||||
| status | STRING | NOT NULL, DEFAULT 'active' |
|
||||
| settings | JSON | NULLABLE |
|
||||
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() |
|
||||
| updated_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() |
|
||||
| deleted_at | TIMESTAMPTZ | NULLABLE |
|
||||
| 模块 | 表 |
|
||||
|------|-----|
|
||||
| 基础 | tenant |
|
||||
| 认证 (auth) | users, user_credentials, user_tokens, roles, permissions, role_permissions, user_roles, organizations, departments, positions, user_departments |
|
||||
| 配置 (config) | dictionaries, dictionary_items, menus, menu_roles, settings, numbering_rules |
|
||||
| 工作流 (workflow) | process_definitions, process_instances, tokens, tasks, process_variables |
|
||||
| 消息 (message) | message_templates, messages, message_subscriptions |
|
||||
| 审计 | audit_logs, domain_events |
|
||||
| 插件 (plugin) | plugins, entity_registry, plugin_market, plugin_user_views |
|
||||
|
||||
### 已知缺失字段
|
||||
tenant 表缺少 `BaseFields` 要求的:
|
||||
- `created_by` — 创建人
|
||||
- `updated_by` — 最后修改人
|
||||
- `version` — 乐观锁版本号
|
||||
### 集成契约
|
||||
|
||||
### 迁移执行
|
||||
```
|
||||
erp-server 启动 → Migrator::up(&db_conn) → 自动运行所有 pending 迁移
|
||||
```
|
||||
| 方向 | 模块 | 触发时机 |
|
||||
|------|------|---------|
|
||||
| 消费 ← | [[erp-server]] | 启动时自动运行 `Migrator::up()` |
|
||||
| 依赖 ← | [[erp-core]] | BaseFields 定义标准字段规范 |
|
||||
| 提供 → | 所有业务模块 | 表结构供 SeaORM Entity 使用 |
|
||||
|
||||
## 关联模块
|
||||
## 3. 代码逻辑
|
||||
|
||||
- **[[erp-core]]** — `BaseFields` 定义了标准字段规范,迁移表结构必须对齐
|
||||
- **[[erp-server]]** — 启动时自动运行迁移
|
||||
- **[[erp-auth]]** — Phase 2 将创建 users, roles, permissions 表
|
||||
- **[[erp-config]]** — Phase 3 将创建 system_configs 表
|
||||
- **[[erp-workflow]]** — Phase 4 将创建 workflow_definitions, workflow_instances 表
|
||||
- **[[erp-message]]** — Phase 5 将创建 messages, notification_settings 表
|
||||
⚡ **不变量**: 所有业务表必须含 `tenant_id` 列 — 多租户是核心能力,不可事后补
|
||||
|
||||
## 关键文件
|
||||
⚡ **不变量**: 迁移必须幂等 — 使用 `if_not_exists`,可重复执行
|
||||
|
||||
| 文件 | 职责 |
|
||||
⚡ **不变量**: 迁移执行由 erp-server 启动自动触发,不手动执行 SQL
|
||||
|
||||
### 关键结构变更迁移
|
||||
|
||||
| 迁移 | 变更 |
|
||||
|------|------|
|
||||
| `crates/erp-server/migration/src/lib.rs` | Migrator 注册所有迁移 |
|
||||
| `crates/erp-server/migration/src/m20260410_000001_create_tenant.rs` | tenant 表迁移 |
|
||||
| `crates/erp-core/src/types.rs` | BaseFields 标准字段定义 |
|
||||
| `docker/docker-compose.yml` | PostgreSQL 16 服务定义 |
|
||||
| m000027 | 修复唯一索引 + 软删除冲突 |
|
||||
| m000034 | 种子插件权限 |
|
||||
| m000035 | pg_trgm 扩展 + entity 列 |
|
||||
| m000036 | role_permissions 添加 data_scope(行级数据权限) |
|
||||
| m000038 | 修复 CRM 权限码 |
|
||||
| m000039 | entity_registry 列 |
|
||||
| m000041 | plugin_user_views |
|
||||
|
||||
## 未来迁移计划 (按 Phase)
|
||||
## 4. 活跃问题 + 陷阱
|
||||
|
||||
| Phase | 表 | 说明 |
|
||||
|-------|-----|------|
|
||||
| Phase 2 | users, roles, permissions, user_roles, role_permissions | RBAC + ABAC |
|
||||
| Phase 3 | system_configs, config_histories | 层级配置 |
|
||||
| Phase 4 | workflow_definitions, workflow_instances, workflow_tasks | BPMN 工作流 |
|
||||
| Phase 5 | messages, notification_settings, message_templates | 多渠道消息 |
|
||||
| 持续 | domain_events | 事件 outbox 表 |
|
||||
### 历史教训
|
||||
|
||||
- 唯一索引 + 软删除冲突 — 已删除记录的 unique key 阻止新建(m000027 修复)
|
||||
- tenant 表缺少 `created_by`/`updated_by`/`version` 字段 — 首个迁移早于 BaseFields 规范
|
||||
|
||||
⚠️ settings 表的唯一索引曾需修复(m000032)
|
||||
⚠️ 新增表时务必对齐 `crates/erp-core/src/types.rs` 中的 BaseFields
|
||||
|
||||
## 5. 变更记录
|
||||
|
||||
| 日期 | 变更 |
|
||||
|------|------|
|
||||
| 2026-04-23 | 重构为 5 节结构,更新表清单至 41 个迁移 |
|
||||
| 2026-04-19 | CRM 权限码修复迁移 (m000038) |
|
||||
|
||||
Reference in New Issue
Block a user