- 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
394 lines
13 KiB
Plaintext
394 lines
13 KiB
Plaintext
// 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")
|
||
}
|