feat(admin): Complete tenant management and module access control system

Major Features:
- Tenant management CRUD (list, create, edit, delete, module configuration)
- Dynamic module management system (modules table with 8 modules)
- Multi-tenant module permission merging (ModuleService)
- Module access control middleware (requireModule)
- User module permission API (GET /api/v1/auth/me/modules)
- Frontend module permission filtering (HomePage + TopNavigation)

Module Integration:
- RVW module integrated with PromptService (editorial + methodology)
- All modules (RVW/PKB/ASL/DC) added authenticate + requireModule middleware
- Fixed ReviewTask foreign key constraint (cross-schema issue)
- Removed all MOCK_USER_ID, unified to request.user?.userId

Prompt Management Enhancements:
- Module names displayed in Chinese (RVW -> 智能审稿)
- Enhanced version history with view content and rollback features
- List page shows both activeVersion and draftVersion columns

Database Changes:
- Added platform_schema.modules table
- Modified tenant_modules table (added index and UUID)
- Removed ReviewTask foreign key to public.users (cross-schema fix)
- Seeded 8 modules: RVW, PKB, ASL, DC, IIT, AIA, SSA, ST

Documentation Updates:
- Updated ADMIN module development status
- Updated TODO checklist (89% progress)
- Updated Prompt management plan (Phase 3.5.5 completed)
- Added module authentication specification

Files Changed: 80+
Status: All features tested and verified locally
Next: User management module development
This commit is contained in:
2026-01-13 07:34:30 +08:00
parent 5523ef36ea
commit d595037316
51 changed files with 3550 additions and 287 deletions

View File

@@ -102,16 +102,20 @@ model Conversation {
}
model Message {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String
model String?
metadata Json?
tokens Int?
isPinned Boolean @default(false) @map("is_pinned")
createdAt DateTime @default(now()) @map("created_at")
conversation Conversation @relation("ConversationMessages", fields: [conversationId], references: [id], onDelete: Cascade)
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String
model String?
metadata Json?
tokens Int?
isPinned Boolean @default(false) @map("is_pinned")
createdAt DateTime @default(now()) @map("created_at")
// V2.1 新增字段
thinkingContent String? @map("thinking_content") @db.Text // 深度思考内容 <think>...</think>
attachments Json? @db.JsonB // 附件数组上限5个单个≤20MB提取文本≤30K tokens
conversation Conversation @relation("ConversationMessages", fields: [conversationId], references: [id], onDelete: Cascade)
@@index([conversationId], map: "idx_aia_messages_conversation_id")
@@index([createdAt], map: "idx_aia_messages_created_at")
@@ -258,37 +262,8 @@ model AdminLog {
@@schema("public")
}
model GeneralConversation {
id String @id @default(uuid())
userId String @map("user_id")
title String
modelName String? @map("model_name")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
@@index([createdAt], map: "idx_aia_general_conversations_created_at")
@@index([updatedAt], map: "idx_aia_general_conversations_updated_at")
@@index([userId], map: "idx_aia_general_conversations_user_id")
@@map("general_conversations")
@@schema("aia_schema")
}
model GeneralMessage {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String
model String?
metadata Json?
tokens Int?
createdAt DateTime @default(now()) @map("created_at")
@@index([conversationId], map: "idx_aia_general_messages_conversation_id")
@@index([createdAt], map: "idx_aia_general_messages_created_at")
@@map("general_messages")
@@schema("aia_schema")
}
// GeneralConversation 和 GeneralMessage 已删除2026-01-11
// 原因:与 Conversation/Message 功能重叠,使用 conversations.project_id = NULL 表示无项目对话
model ReviewTask {
id String @id @default(uuid())
@@ -316,7 +291,8 @@ model ReviewTask {
errorMessage String? @map("error_message")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user users @relation(fields: [userId], references: [id], onDelete: Cascade)
// 注意userId 暂不添加外键约束,因为用户来自不同 schema (platform_schema.users)
// 跨 schema 外键在 PostgreSQL 中需要特殊处理
@@index([userId])
@@index([status])
@@ -799,7 +775,7 @@ model users {
created_at DateTime @default(now())
updated_at DateTime
adminLogs AdminLog[]
reviewTasks ReviewTask[]
// reviewTasks 已移除,因为 ReviewTask.userId 现在不再引用此表
@@index([created_at])
@@index([email])
@@ -1034,8 +1010,25 @@ model tenant_members {
@@schema("platform_schema")
}
/// 系统模块配置表(动态管理可用模块)
model modules {
code String @id // 模块代码: RVW, PKB, ASL, DC, IIT, AIA
name String // 显示名称
description String? // 模块描述
icon String? // 图标(可选)
is_active Boolean @default(true) // 是否上线
sort_order Int @default(0) // 排序
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([is_active])
@@index([sort_order])
@@schema("platform_schema")
}
/// 租户模块订阅表
model tenant_modules {
id String @id
id String @id @default(uuid())
tenant_id String
module_code String
is_enabled Boolean @default(true)
@@ -1044,6 +1037,8 @@ model tenant_modules {
tenants tenants @relation(fields: [tenant_id], references: [id], onDelete: Cascade)
@@unique([tenant_id, module_code])
@@index([tenant_id])
@@index([module_code])
@@schema("platform_schema")
}