Files
AIclinicalresearch/docs/09-架构实施/01-Schema隔离架构设计(10个).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

31 KiB
Raw Permalink Blame History

Schema隔离架构设计10个Schema

文档版本: V1.0
制定日期: 2025-11-09
实施策略: 3个详细迁移 + 7个空Schema预留
架构原则: Just-in-time设计聚焦当前需求架构预留扩展


📋 目录

  1. 架构概述
  2. 10个Schema全景
  3. Schema依赖关系
  4. 详细设计3个迁移Schema
  5. 预留7个空Schema
  6. 迁移策略
  7. 现有表分配方案
  8. 外键和跨Schema引用
  9. Prisma配置策略

架构概述

设计目标

  1. 模块化隔离 - 每个业务模块独立Schema支持独立部署
  2. 数据安全 - Schema级别的权限控制
  3. 扩展性强 - 新模块快速接入只需创建新Schema
  4. 渐进式实施 - 优先迁移核心3个Schema其余按需扩展

实施策略3详细+7空

Week 1重点
┌─────────────────────────────────────────────┐
│  3个详细Schema完整设计+数据迁移)         │
│  ✅ platform_schema  - 1个表users       │
│  ✅ aia_schema       - 5个表对话相关    │
│  ✅ pkb_schema       - 5个表知识库相关  │
├─────────────────────────────────────────────┤
│  7个空Schema只创建命名空间             │
│  📋 asl_schema       - Week 3再设计表       │
│  📋 common_schema    - 需要时再创建表       │
│  📋 dc_schema        - 数据清洗模块         │
│  📋 rvw_schema       - 审稿系统(含现有表) │
│  📋 admin_schema     - 运营管理(含现有表) │
│  📋 ssa_schema       - 智能统计分析         │
│  📋 st_schema        - 统计分析工具         │
└─────────────────────────────────────────────┘

核心原则

  • 聚焦当前 - 只详细设计和迁移现在需要的Platform/AIA/PKB
  • 架构预留 - 创建7个空Schema命名空间占位
  • Just-in-time - ASL等模块在开发前再详细设计避免过度设计
  • 降低风险 - Week 1工作量从2天降到1.5天

10个Schema全景

# Schema名称 中文名称 状态 用途 Week 1任务
1 platform_schema 平台基础层 详细设计 用户、权限、认证 迁移1个表
2 aia_schema AI智能问答 详细设计 对话、项目管理 迁移5个表
3 pkb_schema 个人知识库 详细设计 知识库、文档、批处理 迁移5个表
4 asl_schema AI智能文献 📋 空Schema 文献筛选 只创建Schema
5 common_schema 通用能力层 📋 空Schema LLM使用记录、Feature Flags 只创建Schema
6 dc_schema 数据清洗 📋 空Schema 数据清洗工具 只创建Schema
7 rvw_schema 审稿系统 📋 空Schema 稿件审查 只创建Schema+迁移1表
8 admin_schema 运营管理 📋 空Schema 管理后台、日志 只创建Schema+迁移1表
9 ssa_schema 智能统计分析 📋 空Schema 智能数据分析 只创建Schema
10 st_schema 统计分析工具 📋 空Schema 统计工具集 只创建Schema

Schema依赖关系

层级结构

┌─────────────────────────────────────────────────────────────┐
│  L3: 业务模块层                                              │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐│
│  │   AIA   │ │   PKB   │ │   ASL   │ │   RVW   │ │ ADMIN  ││
│  └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬───┘│
│       │           │           │           │           │     │
│       └───────────┴───────────┴───────────┴───────────┘     │
│                             ↓                                │
├─────────────────────────────────────────────────────────────┤
│  L2: 通用能力层                                              │
│  ┌──────────────┐  ┌──────────────┐                        │
│  │   Common     │  │   DC/SSA/ST  │                        │
│  │  (通用数据)   │  │  (通用工具)   │                        │
│  └──────┬───────┘  └──────────────┘                        │
│         │                                                   │
│         └───────────────────────────────────────────────────│
│                             ↓                                │
├─────────────────────────────────────────────────────────────┤
│  L1: 平台基础层                                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │   Platform Schema                                    │  │
│  │   - 用户管理 (users)                                  │  │
│  │   - 权限控制 (RBAC)                                   │  │
│  │   - 认证服务 (JWT/Session)                           │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

引用关系说明

核心规则:单向依赖,向下引用

  1. 所有业务模块 → platform_schema.users

    • 所有表的 user_id 字段引用 platform_schema.users(id)
    • 跨Schema外键PostgreSQL支持
  2. 业务模块内部表之间

    • 同Schema内的表可以相互引用如aia_schema.conversations → aia_schema.projects
  3. 禁止反向依赖

    • platform_schema 不能引用业务模块Schema
    • 业务模块之间不应相互引用(保持独立性)

详细设计3个迁移Schema

1 platform_schema平台基础层

用途: 用户管理、权限控制、认证服务

迁移表: 1个

  • users - 从 public.users 迁移

表结构users

字段名 类型 说明 索引
id UUID 主键 PK
email VARCHAR(255) 邮箱(唯一) UNIQUE, INDEX
password VARCHAR(255) 密码哈希 -
name VARCHAR(255) 用户名 -
avatar_url VARCHAR(500) 头像URL -
role VARCHAR(50) 角色user/admin INDEX
status VARCHAR(50) 状态active/inactive INDEX
kb_quota INT 知识库配额 -
kb_used INT 已使用配额 -
trial_ends_at TIMESTAMP 试用结束时间 -
is_trial BOOLEAN 是否试用 -
last_login_at TIMESTAMP 最后登录时间 -
created_at TIMESTAMP 创建时间 INDEX
updated_at TIMESTAMP 更新时间 -

SQL DDL

CREATE SCHEMA IF NOT EXISTS platform_schema;

CREATE TABLE platform_schema.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    name VARCHAR(255),
    avatar_url VARCHAR(500),
    role VARCHAR(50) NOT NULL DEFAULT 'user',
    status VARCHAR(50) DEFAULT 'active',
    kb_quota INT DEFAULT 3,
    kb_used INT DEFAULT 0,
    trial_ends_at TIMESTAMP,
    is_trial BOOLEAN DEFAULT true,
    last_login_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 索引
CREATE INDEX idx_users_email ON platform_schema.users(email);
CREATE INDEX idx_users_role ON platform_schema.users(role);
CREATE INDEX idx_users_status ON platform_schema.users(status);
CREATE INDEX idx_users_created_at ON platform_schema.users(created_at);

2 aia_schemaAI智能问答

用途: AI对话、项目管理、通用对话

迁移表: 5个

  • projects - 从 public.projects 迁移
  • conversations - 从 public.conversations 迁移
  • messages - 从 public.messages 迁移
  • general_conversations - 从 public.general_conversations 迁移
  • general_messages - 从 public.general_messages 迁移

表结构概览

1. projects项目表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
name VARCHAR(255) 项目名称 -
background TEXT 研究背景 -
research_type VARCHAR(50) 研究类型 -
conversation_count INT 对话数 -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -
deleted_at TIMESTAMP 删除时间(软删除) -

2. conversations对话表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
project_id UUID 项目ID aia_schema.projects(id)
agent_id VARCHAR(100) 智能体ID -
title VARCHAR(255) 对话标题 -
model_name VARCHAR(50) 模型名称 -
message_count INT 消息数 -
total_tokens INT 总Token数 -
metadata JSONB 元数据 -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -
deleted_at TIMESTAMP 删除时间 -

3. messages消息表

字段名 类型 说明 外键
id UUID 主键 -
conversation_id UUID 对话ID aia_schema.conversations(id)
role VARCHAR(20) 角色user/assistant -
content TEXT 消息内容 -
model VARCHAR(50) 使用的模型 -
metadata JSONB 元数据 -
tokens INT Token数 -
is_pinned BOOLEAN 是否置顶 -
created_at TIMESTAMP 创建时间 -

4. general_conversations通用对话表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
title VARCHAR(255) 对话标题 -
model_name VARCHAR(50) 模型名称 -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -
deleted_at TIMESTAMP 删除时间 -

5. general_messages通用消息表

字段名 类型 说明 外键
id UUID 主键 -
conversation_id UUID 对话ID aia_schema.general_conversations(id)
role VARCHAR(20) 角色 -
content TEXT 消息内容 -
model VARCHAR(50) 使用的模型 -
metadata JSONB 元数据 -
tokens INT Token数 -
created_at TIMESTAMP 创建时间 -

SQL DDL

CREATE SCHEMA IF NOT EXISTS aia_schema;

-- 1. projects
CREATE TABLE aia_schema.projects (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL, -- 引用platform_schema.users
    name VARCHAR(255) NOT NULL,
    background TEXT DEFAULT '',
    research_type VARCHAR(50) DEFAULT 'observational',
    conversation_count INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE
);

-- 2. conversations
CREATE TABLE aia_schema.conversations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    project_id UUID,
    agent_id VARCHAR(100) NOT NULL,
    title VARCHAR(255) NOT NULL,
    model_name VARCHAR(50) DEFAULT 'deepseek-v3',
    message_count INT DEFAULT 0,
    total_tokens INT DEFAULT 0,
    metadata JSONB,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE,
    FOREIGN KEY (project_id) REFERENCES aia_schema.projects(id) ON DELETE CASCADE
);

-- 3. messages
CREATE TABLE aia_schema.messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id UUID NOT NULL,
    role VARCHAR(20) NOT NULL,
    content TEXT NOT NULL,
    model VARCHAR(50),
    metadata JSONB,
    tokens INT,
    is_pinned BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (conversation_id) REFERENCES aia_schema.conversations(id) ON DELETE CASCADE
);

-- 4. general_conversations
CREATE TABLE aia_schema.general_conversations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    title VARCHAR(255) NOT NULL,
    model_name VARCHAR(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE
);

-- 5. general_messages
CREATE TABLE aia_schema.general_messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id UUID NOT NULL,
    role VARCHAR(20) NOT NULL,
    content TEXT NOT NULL,
    model VARCHAR(50),
    metadata JSONB,
    tokens INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (conversation_id) REFERENCES aia_schema.general_conversations(id) ON DELETE CASCADE
);

-- 索引
CREATE INDEX idx_aia_projects_user_id ON aia_schema.projects(user_id);
CREATE INDEX idx_aia_projects_created_at ON aia_schema.projects(created_at);
CREATE INDEX idx_aia_conversations_user_id ON aia_schema.conversations(user_id);
CREATE INDEX idx_aia_conversations_project_id ON aia_schema.conversations(project_id);
CREATE INDEX idx_aia_messages_conversation_id ON aia_schema.messages(conversation_id);
CREATE INDEX idx_aia_general_conversations_user_id ON aia_schema.general_conversations(user_id);
CREATE INDEX idx_aia_general_messages_conversation_id ON aia_schema.general_messages(conversation_id);

3 pkb_schema个人知识库

用途: 知识库管理、文档管理、批处理任务

迁移表: 5个

  • knowledge_bases - 从 public.knowledge_bases 迁移
  • documents - 从 public.documents 迁移
  • batch_tasks - 从 public.batch_tasks 迁移
  • batch_results - 从 public.batch_results 迁移
  • task_templates - 从 public.task_templates 迁移

表结构概览

1. knowledge_bases知识库表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
name VARCHAR(255) 知识库名称 -
description TEXT 描述 -
dify_dataset_id VARCHAR(255) Dify知识库ID -
file_count INT 文件数 -
total_size_bytes BIGINT 总大小(字节) -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -

2. documents文档表 包含Phase 2全文阅读字段

字段名 类型 说明 外键
id UUID 主键 -
kb_id UUID 知识库ID pkb_schema.knowledge_bases(id)
user_id UUID 用户ID platform_schema.users(id)
filename VARCHAR(255) 文件名 -
file_type VARCHAR(50) 文件类型 -
file_size_bytes BIGINT 文件大小 -
file_url TEXT 文件URL -
dify_document_id VARCHAR(255) Dify文档ID -
status VARCHAR(50) 状态 -
progress INT 进度0-100 -
error_message TEXT 错误信息 -
segments_count INT 分段数 -
tokens_count INT Token数 -
Phase 2字段
extraction_method VARCHAR(50) 提取方法pymupdf/nougat/mammoth/direct -
extraction_quality FLOAT 提取质量0-1 -
char_count INT 字符数 -
language VARCHAR(20) 语言chinese/english -
extracted_text TEXT 提取的文本 -
uploaded_at TIMESTAMP 上传时间 -
processed_at TIMESTAMP 处理完成时间 -

3. batch_tasks批处理任务表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
kb_id UUID 知识库ID pkb_schema.knowledge_bases(id)
name VARCHAR(255) 任务名称 -
template_type VARCHAR(50) 模板类型 -
template_id VARCHAR(100) 模板ID -
prompt TEXT 提示词 -
status VARCHAR(50) 状态 -
total_documents INT 总文档数 -
completed_count INT 完成数 -
failed_count INT 失败数 -
model_type VARCHAR(50) 模型类型 -
concurrency INT 并发数 -
started_at TIMESTAMP 开始时间 -
completed_at TIMESTAMP 完成时间 -
duration_seconds INT 执行时长(秒) -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -

4. batch_results批处理结果表

字段名 类型 说明 外键
id UUID 主键 -
task_id UUID 任务ID pkb_schema.batch_tasks(id)
document_id UUID 文档ID pkb_schema.documents(id)
status VARCHAR(50) 状态 -
data JSONB 结构化数据 -
raw_output TEXT 原始输出 -
error_message TEXT 错误信息 -
processing_time_ms INT 处理时长(毫秒) -
tokens_used INT Token使用量 -
created_at TIMESTAMP 创建时间 -

5. task_templates任务模板表

字段名 类型 说明 外键
id UUID 主键 -
user_id UUID 用户ID platform_schema.users(id)
name VARCHAR(255) 模板名称 -
description TEXT 描述 -
prompt TEXT 提示词 -
output_fields JSONB 输出字段定义 -
is_public BOOLEAN 是否公开 -
created_at TIMESTAMP 创建时间 -
updated_at TIMESTAMP 更新时间 -

SQL DDL

CREATE SCHEMA IF NOT EXISTS pkb_schema;

-- 1. knowledge_bases
CREATE TABLE pkb_schema.knowledge_bases (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    dify_dataset_id VARCHAR(255) NOT NULL,
    file_count INT DEFAULT 0,
    total_size_bytes BIGINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE
);

-- 2. documents (包含Phase 2字段)
CREATE TABLE pkb_schema.documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    kb_id UUID NOT NULL,
    user_id UUID NOT NULL,
    filename VARCHAR(255) NOT NULL,
    file_type VARCHAR(50) NOT NULL,
    file_size_bytes BIGINT NOT NULL,
    file_url TEXT NOT NULL,
    dify_document_id VARCHAR(255) NOT NULL,
    status VARCHAR(50) DEFAULT 'uploading',
    progress INT DEFAULT 0,
    error_message TEXT,
    segments_count INT,
    tokens_count INT,
    -- Phase 2字段
    extraction_method VARCHAR(50),
    extraction_quality FLOAT,
    char_count INT,
    language VARCHAR(20),
    extracted_text TEXT,
    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    processed_at TIMESTAMP,
    
    FOREIGN KEY (kb_id) REFERENCES pkb_schema.knowledge_bases(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE
);

-- 3. batch_tasks
CREATE TABLE pkb_schema.batch_tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    kb_id UUID NOT NULL,
    name VARCHAR(255) NOT NULL,
    template_type VARCHAR(50) NOT NULL,
    template_id VARCHAR(100),
    prompt TEXT NOT NULL,
    status VARCHAR(50) NOT NULL,
    total_documents INT NOT NULL,
    completed_count INT DEFAULT 0,
    failed_count INT DEFAULT 0,
    model_type VARCHAR(50) NOT NULL,
    concurrency INT DEFAULT 3,
    started_at TIMESTAMP,
    completed_at TIMESTAMP,
    duration_seconds INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE,
    FOREIGN KEY (kb_id) REFERENCES pkb_schema.knowledge_bases(id) ON DELETE CASCADE
);

-- 4. batch_results
CREATE TABLE pkb_schema.batch_results (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    task_id UUID NOT NULL,
    document_id UUID NOT NULL,
    status VARCHAR(50) NOT NULL,
    data JSONB,
    raw_output TEXT,
    error_message TEXT,
    processing_time_ms INT,
    tokens_used INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (task_id) REFERENCES pkb_schema.batch_tasks(id) ON DELETE CASCADE,
    FOREIGN KEY (document_id) REFERENCES pkb_schema.documents(id) ON DELETE CASCADE
);

-- 5. task_templates
CREATE TABLE pkb_schema.task_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    prompt TEXT NOT NULL,
    output_fields JSONB NOT NULL,
    is_public BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    FOREIGN KEY (user_id) REFERENCES platform_schema.users(id) ON DELETE CASCADE
);

-- 索引
CREATE INDEX idx_pkb_knowledge_bases_user_id ON pkb_schema.knowledge_bases(user_id);
CREATE INDEX idx_pkb_documents_kb_id ON pkb_schema.documents(kb_id);
CREATE INDEX idx_pkb_documents_user_id ON pkb_schema.documents(user_id);
CREATE INDEX idx_pkb_documents_status ON pkb_schema.documents(status);
CREATE INDEX idx_pkb_batch_tasks_user_id ON pkb_schema.batch_tasks(user_id);
CREATE INDEX idx_pkb_batch_tasks_kb_id ON pkb_schema.batch_tasks(kb_id);
CREATE INDEX idx_pkb_batch_results_task_id ON pkb_schema.batch_results(task_id);
CREATE INDEX idx_pkb_task_templates_user_id ON pkb_schema.task_templates(user_id);

预留7个空Schema

创建策略

只执行 CREATE SCHEMA,不创建表结构

-- 4. AI智能文献Week 3再详细设计
CREATE SCHEMA IF NOT EXISTS asl_schema;
COMMENT ON SCHEMA asl_schema IS 'AI智能文献筛选模块 - Week 3开发前再设计表结构';

-- 5. 通用能力层(需要时再创建表)
CREATE SCHEMA IF NOT EXISTS common_schema;
COMMENT ON SCHEMA common_schema IS '通用能力层 - LLM使用记录、Feature Flags等';

-- 6. 数据清洗模块
CREATE SCHEMA IF NOT EXISTS dc_schema;
COMMENT ON SCHEMA dc_schema IS '数据清洗工具模块';

-- 7. 审稿系统包含现有review_tasks表
CREATE SCHEMA IF NOT EXISTS rvw_schema;
COMMENT ON SCHEMA rvw_schema IS '稿件审查系统模块';

-- 8. 运营管理包含现有admin_logs表
CREATE SCHEMA IF NOT EXISTS admin_schema;
COMMENT ON SCHEMA admin_schema IS '运营管理后台模块';

-- 9. 智能统计分析
CREATE SCHEMA IF NOT EXISTS ssa_schema;
COMMENT ON SCHEMA ssa_schema IS '智能统计分析模块';

-- 10. 统计分析工具
CREATE SCHEMA IF NOT EXISTS st_schema;
COMMENT ON SCHEMA st_schema IS '统计分析工具集模块';

各空Schema的用途

Schema 用途说明 何时设计表结构
asl_schema AI智能文献筛选 Week 3 Day 1 - ASL开发前详细设计
common_schema 通用能力LLM使用记录、Feature Flags 需要时再设计
dc_schema 数据清洗工具 Week 5+或按需
rvw_schema 稿件审查系统 Week 1迁移review_tasks其他表按需
admin_schema 运营管理后台 Week 1迁移admin_logs其他表按需
ssa_schema 智能统计分析 Week 5+或按需
st_schema 统计分析工具集 Week 5+或按需

迁移策略

迁移优先级

优先级 Schema 表数量 数据量估算 迁移时间
P0 platform_schema 1 ~10条 15分钟
P0 aia_schema 5 ~500条 30分钟
P0 pkb_schema 5 ~100条 30分钟
P1 rvw_schema 1review_tasks ~20条 10分钟
P1 admin_schema 1admin_logs ~50条 10分钟

迁移步骤4步法

Step 1创建10个Schema5分钟

-- 执行脚本001-create-all-10-schemas.sql
-- 创建10个Schema3详细+7空

Step 2创建表结构30分钟

-- 执行脚本:
-- 002-migrate-platform.sql  - 创建platform_schema.users
-- 003-migrate-aia.sql       - 创建aia_schema的5个表
-- 004-migrate-pkb.sql       - 创建pkb_schema的5个表

Step 3迁移数据30分钟

-- 使用 INSERT INTO ... SELECT FROM 方式
-- 保持ID不变确保引用关系不变

Step 4验证30分钟

-- 执行脚本005-validate-all.sql
-- 验证数据完整性、外键约束

数据迁移示例

platform_schema.users

INSERT INTO platform_schema.users 
SELECT * FROM public.users;

aia_schema.projects

INSERT INTO aia_schema.projects 
SELECT * FROM public.projects;

验证:

-- 验证数据量
SELECT 'users' AS table_name, COUNT(*) FROM platform_schema.users
UNION ALL
SELECT 'projects', COUNT(*) FROM aia_schema.projects
UNION ALL
SELECT 'conversations', COUNT(*) FROM aia_schema.conversations;

现有表分配方案

当前public schema中的13个表

# 表名 目标Schema 迁移时机 说明
1 users platform_schema Week 1 P0核心表
2 projects aia_schema Week 1 P0核心表
3 conversations aia_schema Week 1 P0核心表
4 messages aia_schema Week 1 P0核心表
5 general_conversations aia_schema Week 1 P0核心表
6 general_messages aia_schema Week 1 P0核心表
7 knowledge_bases pkb_schema Week 1 P0核心表
8 documents pkb_schema Week 1 P0核心表
9 batch_tasks pkb_schema Week 1 P0核心表
10 batch_results pkb_schema Week 1 P0核心表
11 task_templates pkb_schema Week 1 P0核心表
12 review_tasks rvw_schema Week 1或保留 📋 P1可选
13 admin_logs admin_schema Week 1或保留 📋 P1可选

说明:

  • 优先迁移11个表到3个详细SchemaPlatform/AIA/PKB
  • review_tasks和admin_logs可以:
    • 选项AWeek 1一并迁移到对应的空Schema简单
    • 选项B暂时保留在public需要时再迁移务实
    • 建议选项A:一次性迁移完成,避免残留

外键和跨Schema引用

PostgreSQL跨Schema外键支持

PostgreSQL 完全支持跨Schema的外键约束

-- 示例aia_schema.projects 引用 platform_schema.users
CREATE TABLE aia_schema.projects (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL,
    name VARCHAR(255),
    
    FOREIGN KEY (user_id) 
        REFERENCES platform_schema.users(id) 
        ON DELETE CASCADE
);

引用规则

允许的引用:

  • 业务模块Schema → platform_schema.users(id)
  • 同Schema内的表相互引用

禁止的引用:

  • platform_schema → 业务模块Schema反向依赖
  • 业务模块Schema之间相互引用保持独立性

数据一致性保证

  1. CASCADE删除 - 用户删除时,关联数据自动删除
  2. 外键索引 - 所有外键字段创建索引
  3. 事务保护 - 迁移在事务中执行,全成功或全失败

Prisma配置策略

Week 1的Prisma配置

在schema.prisma中

  1. 启用multiSchema预览特性
generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["multiSchema"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  schemas  = [
    "platform_schema",
    "aia_schema",
    "pkb_schema",
    "asl_schema",      // 空Schema预留
    "common_schema",   // 空Schema预留
    "dc_schema",       // 空Schema预留
    "rvw_schema",      // 空Schema预留
    "admin_schema",    // 空Schema预留
    "ssa_schema",      // 空Schema预留
    "st_schema"        // 空Schema预留
  ]
}
  1. 只为3个详细Schema定义模型
// Platform Schema
model User {
  // ...
  @@map("users")
  @@schema("platform_schema")
}

// AIA Schema
model Project {
  // ...
  @@map("projects")
  @@schema("aia_schema")
}

// PKB Schema
model KnowledgeBase {
  // ...
  @@map("knowledge_bases")
  @@schema("pkb_schema")
}
  1. 7个空Schema不定义模型
    • 只在schemas列表中声明
    • Week 3再为asl_schema添加模型
    • 其他按需添加

详细Prisma配置参考

  • 见V2.2完整版文档的 Day 4 Prisma配置示例

📊 工作量估算

任务 预计时间 说明
Day 1-2上午架构规划与设计 8小时 本文档 + 3个Schema SQL
Day 2下午编写迁移脚本 1.5小时 5个SQL脚本
Day 3上午执行迁移 2-3小时 备份 + 迁移 + 验证
Day 3下午功能测试 2小时 测试现有功能
Day 4Prisma配置 3小时 更新schema.prisma
总计 约16-17小时2天

🎯 成功标准

Week 1结束时应达到

  • 10个Schema全部创建成功
  • 3个详细Schema的11个表数据100%迁移
  • 所有外键约束正确建立
  • 现有功能AIA、PKB正常运行
  • Prisma Client生成成功
  • 7个空Schema验证通过可查询、可创建表

📝 后续步骤

Week 2

  • 前端统一架构
  • 后端代码分层
  • 适配新的Schema结构

Week 3

  • 详细设计asl_schema
  • 为asl_schema创建表结构
  • 开发ASL核心功能

Week 5+

  • 按需为其他空Schema设计表结构
  • LLM网关统一
  • 其他模块开发

文档制定: AI助手
审核: 待审核
最后更新: 2025-11-09

核心策略:聚焦当前 + 架构预留 + Just-in-time设计