Files
AIclinicalresearch/docs/04-开发规范/09-数据库开发规范.md
HaHafeng 66255368b7 feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1):
- Database: Add user_modules table for fine-grained module permissions
- Database: Add 4 user permissions (view/create/edit/delete) to role_permissions
- Backend: UserService (780 lines) - CRUD with tenant isolation
- Backend: UserController + UserRoutes (648 lines) - 13 API endpoints
- Backend: Batch import users from Excel
- Frontend: UserListPage (412 lines) - list/filter/search/pagination
- Frontend: UserFormPage (341 lines) - create/edit with module config
- Frontend: UserDetailPage (393 lines) - details/tenant/module management
- Frontend: 3 modal components (592 lines) - import/assign/configure
- API: GET/POST/PUT/DELETE /api/admin/users/* endpoints

Architecture Upgrade - Module Permission System:
- Backend: Add getUserModules() method in auth.service
- Backend: Login API returns modules array in user object
- Frontend: AuthContext adds hasModule() method
- Frontend: Navigation filters modules based on user.modules
- Frontend: RouteGuard checks requiredModule instead of requiredVersion
- Frontend: Remove deprecated version-based permission system
- UX: Only show accessible modules in navigation (clean UI)
- UX: Smart redirect after login (avoid 403 for regular users)

Fixes:
- Fix UTF-8 encoding corruption in ~100 docs files
- Fix pageSize type conversion in userService (String to Number)
- Fix authUser undefined error in TopNavigation
- Fix login redirect logic with role-based access check
- Update Git commit guidelines v1.2 with UTF-8 safety rules

Database Changes:
- CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled)
- ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code)
- INSERT 4 permissions + role assignments
- UPDATE PUBLIC tenant with 8 module subscriptions

Technical:
- Backend: 5 new files (~2400 lines)
- Frontend: 10 new files (~2500 lines)
- Docs: 1 development record + 2 status updates + 1 guideline update
- Total: ~4900 lines of code

Status: User management 100% complete, module permission system operational
2026-01-16 13:42:10 +08:00

7.7 KiB
Raw Blame History

数据库开发规范

版本: v1.0 更新日期: 2026-01-11 编写背景: 2026-01-11 数据库事故后总结


1. 核心原则

1.1 安全第一

⚠️ 黄金法则:任何数据库操作前,必须先备份!

1.2 禁止使用的危险命令

命令 危险等级 说明
prisma db push --force-reset 🔴 极高 会删除所有数据和非Prisma管理的对象
prisma migrate reset 🔴 极高 重置整个数据库
DROP DATABASE 🔴 极高 删除整个数据库
TRUNCATE TABLE 🟠 清空表数据

1.3 推荐的安全命令

命令 用途 安全性
prisma migrate dev 开发环境迁移 安全
prisma migrate deploy 生产环境迁移 安全
prisma db push (无 --force-reset) 同步schema到数据库 ⚠️ 谨慎使用
prisma generate 生成客户端 安全

2. 数据库备份规范

2.1 备份命令

# 通过 Docker 备份(推荐)
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > backup_$(date +%Y%m%d_%H%M%S).sql

# PowerShell 版本
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > "backup_$timestamp.sql"

2.2 备份时机

时机 是否必须
执行任何 prisma migrate 必须
执行 prisma db push 必须
部署到生产环境前 必须
每日自动备份 推荐
重大功能发布前 必须

2.3 备份文件管理

AIclinicalresearch/
├── backup_20260111_131506.sql     # 日期_时间命名
├── rds_init_20251224_154529.sql   # 历史备份
└── ...

3. Schema 变更流程

3.1 标准流程

graph TD
    A[修改 schema.prisma] --> B[备份数据库]
    B --> C[运行 prisma migrate dev]
    C --> D{迁移成功?}
    D -->|是| E[测试功能]
    D -->|否| F[从备份恢复]
    E --> G{测试通过?}
    G -->|是| H[提交代码]
    G -->|否| F

3.2 具体步骤

# 1. 备份数据库
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > backup_before_migration.sql

# 2. 修改 schema.prisma

# 3. 创建迁移
npx prisma migrate dev --name describe_your_change

# 4. 检查生成的迁移 SQL
cat prisma/migrations/xxx_describe_your_change/migration.sql

# 5. 测试

# 6. 如果失败,恢复备份
cat backup_before_migration.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research

4. Prisma 与数据库不一致问题

4.1 Prisma 不管理的对象

以下数据库对象不在 schema.prisma 中定义,需要单独管理:

对象 类型 来源 恢复脚本
platform_schema.job_common pg-boss 运行时创建 restore_job_common.sql
platform_schema.create_queue() 函数 pg-boss 初始化 restore_pgboss_functions.sql
platform_schema.delete_queue() 函数 pg-boss 初始化 restore_pgboss_functions.sql

4.2 恢复非 Prisma 管理的对象

# 如果误删了 pg-boss 相关对象,执行:
npx prisma db execute --file restore_job_common.sql --schema prisma/schema.prisma
npx prisma db execute --file restore_pgboss_functions.sql --schema prisma/schema.prisma

4.3 检查数据库与 Prisma 一致性

# 查看数据库中的函数
SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'platform_schema';

# 查看数据库中的表
SELECT table_name FROM information_schema.tables WHERE table_schema = 'platform_schema';

# 对比 schema.prisma 定义

5. 多 Schema 架构规范

5.1 Schema 命名规范

Schema 用途 示例表
platform_schema 平台基础设施 users, tenants, app_cache
admin_schema 运营管理 admin_operation_logs
aia_schema AI智能问答 conversations, messages
asl_schema 文献筛选 screening_projects, literatures
dc_schema 数据清洗 dc_templates, dc_extraction_tasks
pkb_schema 个人知识库 knowledge_bases, documents
iit_schema IIT项目 projects, audit_logs
rvw_schema 论文预审 review_tasks
capability_schema 通用能力 prompt_templates
public 旧数据/兼容 users (旧), admin_logs

5.2 表命名规范

{schema_name}.{module_prefix}_{entity_name}

示例:
- dc_schema.dc_templates
- dc_schema.dc_extraction_tasks
- asl_schema.screening_projects

6. 外键与数据完整性

6.1 跨 Schema 外键

// ✅ 正确:明确指定关系
model ReviewTask {
  userId String @map("user_id")
  user   PublicUser @relation(fields: [userId], references: [id])
  
  @@schema("rvw_schema")
}

model PublicUser {
  id String @id
  reviewTasks ReviewTask[]
  
  @@schema("public")
}

6.2 外键指向检查

在使用 prisma db push 后,检查外键是否正确:

SELECT 
  tc.table_schema, tc.table_name, kcu.column_name,
  ccu.table_schema AS foreign_schema, ccu.table_name AS foreign_table
FROM information_schema.table_constraints AS tc 
JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY';

7. 事故恢复流程

7.1 误删数据恢复

# 1. 停止应用
# 2. 从备份恢复
cat backup_xxx.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research

# 3. 验证数据
npx tsx verify_system.ts

# 4. 重启应用

7.2 Schema 不一致恢复

# 1. 检查差异
npx tsx compare_schema_db.ts

# 2. 恢复缺失的对象
npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma

# 3. 验证

8. 开发环境 vs 生产环境

8.1 开发环境

  • 可以使用 prisma migrate dev
  • 可以使用 prisma db push(谨慎)
  • 定期同步生产数据库结构

8.2 生产环境

  • 只能使用 prisma migrate deploy
  • 禁止使用任何 --force--reset 参数
  • 变更前必须有回滚计划
  • 必须有最新备份

9. 检查清单

9.1 数据库变更前检查

  • 已备份数据库
  • 已审查 schema.prisma 变更
  • 已检查是否影响非 Prisma 管理的对象
  • 已准备回滚方案
  • 已在开发环境测试

9.2 部署后检查

  • 应用正常启动
  • 数据库连接正常
  • pg-boss 队列正常工作
  • 核心功能测试通过

10. 常用脚本

10.1 验证脚本位置

backend/
├── verify_system.ts           # 系统完整性验证
├── compare_schema_db.ts       # Schema与数据库对比
├── check_iit_asl_data.ts      # 检查模块数据
├── restore_job_common.sql     # 恢复 job_common 表
└── restore_pgboss_functions.sql # 恢复 pg-boss 函数

10.2 快速验证命令

# 设置环境变量
$env:DATABASE_URL="postgresql://postgres:postgres123@localhost:5432/ai_clinical_research"

# 验证系统
npx tsx verify_system.ts

# 检查数据
npx tsx check_iit_asl_data.ts

附录:事故案例

案例12026-01-11 数据库重置事故

原因:使用 prisma db push --force-reset 导致非 Prisma 管理的对象丢失

影响

  • pg-boss 函数丢失,队列无法注册
  • job_common 表丢失
  • 用户数据丢失(已通过 seed 恢复)

教训

  1. 永远不要使用 --force-reset
  2. 操作前必须备份
  3. 了解 Prisma 的管理边界

详见:docs/08-项目管理/2026-01-11-数据库事故总结.md