- Add platform infrastructure chapter to frontend-backend architecture design - Update system architecture document with 6 new infrastructure modules - Update AI onboarding guide with infrastructure overview - Link to backend/src/common/README.md for detailed usage guide Key Updates: - Storage service (LocalAdapter + OSSAdapter) - Logging system (Winston + JSON format) - Cache service (Memory + Redis) - Async job queue (Memory + Database) - Health check endpoints - Monitoring metrics - Database connection pool - Environment config management All modules support zero-code switching between local and cloud environments. Related: #Platform-Infrastructure
14 KiB
14 KiB
AIA - AI智能问答模块:数据库设计
版本: v1.0
更新时间: 2025-11-12
数据库Schema:aia_schema
状态: ✅ 已实施并迁移
📋 目录
模块概述
功能定位
AIA(AI Intelligent Assistant)- AI智能问答模块是平台的核心对话引擎,提供:
- 项目管理 - 研究项目的创建和管理
- 智能对话 - 基于LLM的专业领域对话
- 通用问答 - 不绑定项目的通用AI对话
- 消息管理 - 对话历史记录和检索
核心业务场景
- 用户创建临床研究项目
- 在项目内与AI进行专业对话
- 使用通用对话功能快速咨询
- 查看和管理对话历史
Schema信息
Schema名称
aia_schema
创建语句
CREATE SCHEMA IF NOT EXISTS aia_schema;
GRANT ALL ON SCHEMA aia_schema TO aiclinical_admin;
数据迁移
- 迁移时间: 2025-11-12
- 源Schema: public
- 迁移脚本:
docs/09-架构实施/migration-scripts/003-migrate-aia.sql - 数据完整性: ✅ 100%迁移成功
数据库表设计
表列表
| 表名 | 用途 | 行数(估计) | 状态 |
|---|---|---|---|
projects |
研究项目 | 1-100/用户 | ✅ 已部署 |
conversations |
项目对话 | 10-500/项目 | ✅ 已部署 |
messages |
对话消息 | 10-1000/对话 | ✅ 已部署 |
general_conversations |
通用对话 | 10-100/用户 | ✅ 已部署 |
general_messages |
通用对话消息 | 10-1000/对话 | ✅ 已部署 |
总计: 5个表
1. projects - 研究项目表
用途: 存储用户创建的临床研究项目
表结构
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | 项目唯一标识(UUID) |
| user_id | TEXT | NOT NULL, FK | 所属用户ID |
| name | TEXT | NOT NULL | 项目名称 |
| background | TEXT | NULL | 研究背景 |
| research_type | TEXT | NULL | 研究类型(observational/experimental等) |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 |
| deleted_at | TIMESTAMPTZ | NULL | 软删除时间 |
Prisma Model
model Project {
id String @id @default(uuid())
userId String @map("user_id")
name String
background String?
researchType String? @map("research_type")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
conversations Conversation[]
@@index([userId])
@@index([createdAt])
@@index([deletedAt])
@@map("projects")
@@schema("aia_schema")
}
业务规则
- 软删除机制 - 使用
deleted_at标记删除,不物理删除 - 级联删除 - 删除项目时,关联的对话也被软删除
- 用户隔离 - 通过
user_id实现数据隔离
2. conversations - 项目对话表
用途: 存储项目内的AI对话会话
表结构
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | 对话唯一标识(UUID) |
| user_id | TEXT | NOT NULL, FK | 所属用户ID |
| project_id | TEXT | NULL, FK | 所属项目ID(可选) |
| agent_id | TEXT | NOT NULL | 智能体ID |
| title | TEXT | NOT NULL | 对话标题 |
| model_name | TEXT | NOT NULL, DEFAULT 'deepseek-v3' | 使用的LLM模型 |
| message_count | INTEGER | NOT NULL, DEFAULT 0 | 消息数量 |
| total_tokens | INTEGER | NOT NULL, DEFAULT 0 | 累计token数 |
| metadata | JSONB | NULL | 扩展元数据 |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 |
| deleted_at | TIMESTAMPTZ | NULL | 软删除时间 |
Prisma Model
model Conversation {
id String @id @default(uuid())
userId String @map("user_id")
projectId String? @map("project_id")
agentId String @map("agent_id")
title String
modelName String @default("deepseek-v3") @map("model_name")
messageCount Int @default(0) @map("message_count")
totalTokens Int @default(0) @map("total_tokens")
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
messages Message[]
@@index([userId])
@@index([projectId])
@@index([agentId])
@@index([createdAt])
@@index([deletedAt])
@@map("conversations")
@@schema("aia_schema")
}
业务规则
- 项目关联可选 -
project_id可为空,支持项目内外对话 - 计数器字段 -
message_count和total_tokens用于统计,需要实时更新 - 模型选择 - 支持多种LLM模型(deepseek-v3/gpt-5-pro/claude-4.5等)
- 扩展元数据 -
metadata用于存储配置参数、上下文等
3. messages - 对话消息表
用途: 存储对话中的每条消息
表结构
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | 消息唯一标识(UUID) |
| conversation_id | TEXT | NOT NULL, FK | 所属对话ID |
| role | TEXT | NOT NULL | 角色(user/assistant/system) |
| content | TEXT | NOT NULL | 消息内容 |
| model | TEXT | NULL | 使用的模型(assistant消息) |
| metadata | JSONB | NULL | 扩展元数据 |
| tokens | INTEGER | NULL | 消息token数 |
| is_pinned | BOOLEAN | NOT NULL, DEFAULT false | 是否置顶 |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
Prisma Model
model Message {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String @db.Text
model String?
metadata Json?
tokens Int?
isPinned Boolean @default(false) @map("is_pinned")
createdAt DateTime @default(now()) @map("created_at")
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
@@index([conversationId])
@@index([createdAt])
@@index([isPinned])
@@map("messages")
@@schema("aia_schema")
}
业务规则
- 角色类型 -
role固定为user、assistant或system - 只读性 - 消息一旦创建不可修改(只有
is_pinned可修改) - 级联删除 - 删除对话时,消息自动删除
- 置顶功能 - 重要消息可通过
is_pinned标记
4. general_conversations - 通用对话表
用途: 存储不绑定项目的通用AI对话
表结构
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | 对话唯一标识(UUID) |
| user_id | TEXT | NOT NULL, FK | 所属用户ID |
| title | TEXT | NOT NULL | 对话标题 |
| model_name | TEXT | NOT NULL, DEFAULT 'qwen-long' | 使用的LLM模型 |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| updated_at | TIMESTAMPTZ | NOT NULL | 更新时间 |
| deleted_at | TIMESTAMPTZ | NULL | 软删除时间 |
Prisma Model
model GeneralConversation {
id String @id @default(uuid())
userId String @map("user_id")
title String
modelName String @default("qwen-long") @map("model_name")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
messages GeneralMessage[]
@@index([userId])
@@index([createdAt])
@@index([updatedAt])
@@map("general_conversations")
@@schema("aia_schema")
}
业务规则
- 轻量级对话 - 不需要项目和智能体关联
- 快速咨询 - 用于用户的临时问题和快速查询
- 独立管理 - 与项目对话分开管理
5. general_messages - 通用对话消息表
用途: 存储通用对话中的每条消息
表结构
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
| id | TEXT | PRIMARY KEY | 消息唯一标识(UUID) |
| conversation_id | TEXT | NOT NULL, FK | 所属对话ID |
| role | TEXT | NOT NULL | 角色(user/assistant/system) |
| content | TEXT | NOT NULL | 消息内容 |
| metadata | JSONB | NULL | 扩展元数据 |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
Prisma Model
model GeneralMessage {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String @db.Text
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
conversation GeneralConversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
@@index([conversationId])
@@index([createdAt])
@@map("general_messages")
@@schema("aia_schema")
}
业务规则
- 简化设计 - 相比项目消息,去掉了token统计和置顶功能
- 级联删除 - 删除对话时,消息自动删除
表关系图
erDiagram
PLATFORM_USERS ||--o{ PROJECTS : "owns"
PLATFORM_USERS ||--o{ CONVERSATIONS : "owns"
PLATFORM_USERS ||--o{ GENERAL_CONVERSATIONS : "owns"
PROJECTS ||--o{ CONVERSATIONS : "contains"
CONVERSATIONS ||--o{ MESSAGES : "contains"
GENERAL_CONVERSATIONS ||--o{ GENERAL_MESSAGES : "contains"
PLATFORM_USERS {
text id PK
text email
text password
}
PROJECTS {
text id PK
text user_id FK
text name
text research_type
timestamptz created_at
timestamptz deleted_at
}
CONVERSATIONS {
text id PK
text user_id FK
text project_id FK
text agent_id
text title
text model_name
int message_count
timestamptz created_at
}
MESSAGES {
text id PK
text conversation_id FK
text role
text content
int tokens
boolean is_pinned
timestamptz created_at
}
GENERAL_CONVERSATIONS {
text id PK
text user_id FK
text title
text model_name
timestamptz created_at
}
GENERAL_MESSAGES {
text id PK
text conversation_id FK
text role
text content
timestamptz created_at
}
跨Schema引用
外键关系:
projects.user_id→platform_schema.users.idconversations.user_id→platform_schema.users.idgeneral_conversations.user_id→platform_schema.users.id
说明: Prisma自动处理跨Schema外键,应用代码无需关心Schema前缀
索引设计
主键索引
所有表的id字段自动创建B-tree主键索引。
外键索引
| 表名 | 索引字段 | 用途 |
|---|---|---|
| projects | user_id | 查询用户的所有项目 |
| conversations | user_id | 查询用户的所有对话 |
| conversations | project_id | 查询项目内的对话 |
| conversations | agent_id | 按智能体过滤对话 |
| messages | conversation_id | 查询对话的所有消息 |
| general_conversations | user_id | 查询用户的通用对话 |
| general_messages | conversation_id | 查询对话的所有消息 |
时间索引
| 表名 | 索引字段 | 用途 |
|---|---|---|
| projects | created_at | 按时间排序项目 |
| projects | deleted_at | 过滤已删除项目 |
| conversations | created_at | 按时间排序对话 |
| conversations | updated_at | 按更新时间排序 |
| conversations | deleted_at | 过滤已删除对话 |
| messages | created_at | 按时间排序消息 |
| general_conversations | created_at | 按时间排序对话 |
| general_conversations | updated_at | 按更新时间排序 |
| general_messages | created_at | 按时间排序消息 |
功能索引
| 表名 | 索引字段 | 用途 |
|---|---|---|
| messages | is_pinned | 快速查询置顶消息 |
数据类型说明
主键类型:TEXT vs UUID
当前实现: TEXT
id TEXT PRIMARY KEY
UUID生成: Prisma @default(uuid())
id String @id @default(uuid())
说明:
- 存储格式:字符串形式的UUID(如
"a6ce8b46-bac6-4284-a9ae-031d636086bc") - 优点:与现有代码兼容,无需迁移
- 索引性能:与原生UUID类型相当
时间类型:TIMESTAMPTZ
所有时间字段使用TIMESTAMPTZ(带时区的时间戳):
- 自动存储UTC时间
- 支持时区转换
- Prisma映射为
DateTime
JSONB类型
用途: 存储扩展元数据和配置
conversations.metadatamessages.metadatageneral_messages.metadata
优点:
- 灵活的数据结构
- 支持GIN索引(按需添加)
- 支持JSONB操作符查询
变更历史
v1.0 - 2025-11-12 - 初始版本 ✅
变更内容:
- 从
publicschema迁移到aia_schema - 5个表全部迁移:
- projects
- conversations
- messages
- general_conversations
- general_messages
- 在Prisma中添加
@@schema("aia_schema")标签 - 所有数据100%完整迁移
迁移脚本: docs/09-架构实施/migration-scripts/003-migrate-aia.sql
验证状态: ✅ 已验证,功能正常
📚 相关文档
文档维护者: AI助手
最后更新: 2025-11-12
文档状态: ✅ 已完成并验证