Files
AIclinicalresearch/backend/prisma/schema.prisma
HaHafeng 0c5310fb77 refactor(backend): incremental architecture evolution (Task 19)
- Add common/ layer for shared capabilities (LLM, RAG, document, middleware)
- Add legacy/ layer for existing business code
- Move files to new structure (controllers, routes, services)
- Update index.ts for new route registration
- System remains fully functional
2025-11-16 15:42:44 +08:00

394 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["platform_schema", "aia_schema", "pkb_schema", "asl_schema", "common_schema", "dc_schema", "rvw_schema", "admin_schema", "ssa_schema", "st_schema", "public"]
}
// ==================== 用户模块 ====================
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
avatarUrl String? @map("avatar_url")
role String @default("user")
status String @default("active")
kbQuota Int @default(3) @map("kb_quota")
kbUsed Int @default(0) @map("kb_used")
trialEndsAt DateTime? @map("trial_ends_at")
isTrial Boolean @default(true) @map("is_trial")
lastLoginAt DateTime? @map("last_login_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
projects Project[]
conversations Conversation[]
knowledgeBases KnowledgeBase[]
documents Document[]
adminLogs AdminLog[]
generalConversations GeneralConversation[]
batchTasks BatchTask[] // Phase 3: 批处理任务
taskTemplates TaskTemplate[] // Phase 3: 任务模板
reviewTasks ReviewTask[] // 稿件审查任务
@@index([email])
@@index([status])
@@index([createdAt])
@@map("users")
@@schema("platform_schema")
}
// ==================== 项目模块 ====================
model Project {
id String @id @default(uuid())
userId String @map("user_id")
name String
background String @default("") @db.Text
researchType String @default("observational") @map("research_type")
conversationCount Int @default(0) @map("conversation_count")
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")
}
// ==================== 对话模块 ====================
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")
}
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")
}
// ==================== 知识库模块 ====================
model KnowledgeBase {
id String @id @default(uuid())
userId String @map("user_id")
name String
description String?
difyDatasetId String @map("dify_dataset_id")
fileCount Int @default(0) @map("file_count")
totalSizeBytes BigInt @default(0) @map("total_size_bytes")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
documents Document[]
batchTasks BatchTask[] // Phase 3: 批处理任务
@@index([userId])
@@index([difyDatasetId])
@@map("knowledge_bases")
@@schema("pkb_schema")
}
model Document {
id String @id @default(uuid())
kbId String @map("kb_id")
userId String @map("user_id")
filename String
fileType String @map("file_type")
fileSizeBytes BigInt @map("file_size_bytes")
fileUrl String @map("file_url")
difyDocumentId String @map("dify_document_id")
status String @default("uploading")
progress Int @default(0)
errorMessage String? @map("error_message")
segmentsCount Int? @map("segments_count")
tokensCount Int? @map("tokens_count")
// Phase 2: 全文阅读模式新增字段
extractionMethod String? @map("extraction_method") // pymupdf/nougat/mammoth/direct
extractionQuality Float? @map("extraction_quality") // 0-1质量分数
charCount Int? @map("char_count") // 字符数
language String? // 检测到的语言 (chinese/english)
extractedText String? @map("extracted_text") @db.Text // 提取的文本内容
uploadedAt DateTime @default(now()) @map("uploaded_at")
processedAt DateTime? @map("processed_at")
knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
batchResults BatchResult[] // Phase 3: 批处理结果
@@index([kbId])
@@index([userId])
@@index([status])
@@index([difyDocumentId])
@@index([extractionMethod])
@@map("documents")
@@schema("pkb_schema")
}
// ==================== Phase 3: 批处理模块 ====================
// 批处理任务
model BatchTask {
id String @id @default(uuid())
userId String @map("user_id")
kbId String @map("kb_id")
// 任务基本信息
name String // 任务名称(用户可自定义)
templateType String @map("template_type") // 'preset' | 'custom'
templateId String? @map("template_id") // 预设模板ID如'clinical_research'
prompt String @db.Text // 提示词(完整的)
// 执行状态
status String // 'processing' | 'completed' | 'failed' | 'paused'
totalDocuments Int @map("total_documents")
completedCount Int @default(0) @map("completed_count")
failedCount Int @default(0) @map("failed_count")
// 配置
modelType String @map("model_type") // 使用的模型
concurrency Int @default(3) // 固定为3
// 时间统计
startedAt DateTime? @map("started_at")
completedAt DateTime? @map("completed_at")
durationSeconds Int? @map("duration_seconds") // 执行时长(秒)
// 关联
results BatchResult[]
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([userId])
@@index([kbId])
@@index([status])
@@index([createdAt])
@@map("batch_tasks")
@@schema("pkb_schema")
}
// 批处理结果(每篇文献一条)
model BatchResult {
id String @id @default(uuid())
taskId String @map("task_id")
documentId String @map("document_id")
// 执行结果
status String // 'success' | 'failed'
data Json? // 提取的结构化数据(预设模板)或文本(自定义)
rawOutput String? @db.Text @map("raw_output") // AI原始输出备份
errorMessage String? @db.Text @map("error_message") // 错误信息
// 性能指标
processingTimeMs Int? @map("processing_time_ms") // 处理时长(毫秒)
tokensUsed Int? @map("tokens_used") // Token使用量
// 关联
task BatchTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
@@index([taskId])
@@index([documentId])
@@index([status])
@@map("batch_results")
@@schema("pkb_schema")
}
// 任务模板(暂不实现,预留)
model TaskTemplate {
id String @id @default(uuid())
userId String @map("user_id")
name String
description String?
prompt String @db.Text
outputFields Json // 期望的输出字段定义
isPublic Boolean @default(false) @map("is_public")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([userId])
@@map("task_templates")
@@schema("pkb_schema")
}
// ==================== 运营管理模块 ====================
model AdminLog {
id Int @id @default(autoincrement())
adminId String @map("admin_id")
action String
resourceType String? @map("resource_type")
resourceId String? @map("resource_id")
details Json?
ipAddress String? @map("ip_address")
userAgent String? @map("user_agent")
createdAt DateTime @default(now()) @map("created_at")
admin User @relation(fields: [adminId], references: [id], onDelete: Cascade)
@@index([adminId])
@@index([createdAt])
@@index([action])
@@map("admin_logs")
@@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")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
messages GeneralMessage[]
@@index([userId])
@@index([createdAt])
@@index([updatedAt])
@@map("general_conversations")
@@schema("aia_schema")
}
model GeneralMessage {
id String @id @default(uuid())
conversationId String @map("conversation_id")
role String
content String @db.Text
model String?
metadata Json?
tokens Int?
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")
}
// ==================== 稿件审查模块 ====================
// 稿件审查任务
model ReviewTask {
id String @id @default(uuid())
userId String @map("user_id")
// 文件信息
fileName String @map("file_name")
fileSize Int @map("file_size")
filePath String? @map("file_path")
// 文档内容
extractedText String @map("extracted_text") @db.Text
wordCount Int? @map("word_count")
// 执行状态
status String @default("pending")
// pending, extracting, reviewing_editorial, reviewing_methodology, completed, failed
// 评估结果JSON
editorialReview Json? @map("editorial_review")
methodologyReview Json? @map("methodology_review")
overallScore Float? @map("overall_score")
// 执行信息
modelUsed String? @map("model_used")
startedAt DateTime? @map("started_at")
completedAt DateTime? @map("completed_at")
durationSeconds Int? @map("duration_seconds")
errorMessage String? @map("error_message") @db.Text
// 元数据
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([status])
@@index([createdAt])
@@map("review_tasks")
@@schema("public")
}