// 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[] // 稿件审查任务 aslProjects AslScreeningProject[] @relation("AslProjects") // ASL智能文献项目 @@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? @map("raw_output") @db.Text // AI原始输出(备份) errorMessage String? @map("error_message") @db.Text // 错误信息 // 性能指标 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") } // ==================== ASL智能文献模块 ==================== // ASL 筛选项目表 model AslScreeningProject { id String @id @default(uuid()) userId String @map("user_id") user User @relation("AslProjects", fields: [userId], references: [id], onDelete: Cascade) projectName String @map("project_name") // PICO标准 picoCriteria Json @map("pico_criteria") // { population, intervention, comparison, outcome, studyDesign } // 筛选标准 inclusionCriteria String @map("inclusion_criteria") @db.Text exclusionCriteria String @map("exclusion_criteria") @db.Text // 状态 status String @default("draft") // draft, screening, completed // 筛选配置 screeningConfig Json? @map("screening_config") // { models: ["deepseek", "qwen"], temperature: 0 } // 关联 literatures AslLiterature[] screeningTasks AslScreeningTask[] screeningResults AslScreeningResult[] fulltextScreeningTasks AslFulltextScreeningTask[] fulltextScreeningResults AslFulltextScreeningResult[] createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([userId]) @@index([status]) @@map("screening_projects") @@schema("asl_schema") } // ASL 文献条目表 model AslLiterature { id String @id @default(uuid()) projectId String @map("project_id") project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade) // 文献基本信息 pmid String? title String @db.Text abstract String @db.Text authors String? journal String? publicationYear Int? @map("publication_year") doi String? // 文献阶段(生命周期管理) stage String @default("imported") @map("stage") // imported, title_screened, title_included, pdf_acquired, fulltext_screened, data_extracted // 云原生存储字段(V1.0 阶段使用,MVP阶段预留) pdfUrl String? @map("pdf_url") // PDF访问URL pdfOssKey String? @map("pdf_oss_key") // OSS存储Key(用于删除) pdfFileSize Int? @map("pdf_file_size") // 文件大小(字节) // PDF存储(Dify/OSS双适配) hasPdf Boolean @default(false) @map("has_pdf") pdfStorageType String? @map("pdf_storage_type") // "dify" | "oss" pdfStorageRef String? @map("pdf_storage_ref") // Dify: document_id, OSS: object_key pdfStatus String? @map("pdf_status") // "uploading" | "ready" | "failed" pdfUploadedAt DateTime? @map("pdf_uploaded_at") // 全文内容存储(云原生:存储引用而非内容) fullTextStorageType String? @map("full_text_storage_type") // "dify" | "oss" fullTextStorageRef String? @map("full_text_storage_ref") // document_id 或 object_key fullTextUrl String? @map("full_text_url") // 访问URL fullTextFormat String? @map("full_text_format") // "markdown" | "plaintext" fullTextSource String? @map("full_text_source") // "nougat" | "pymupdf" fullTextTokenCount Int? @map("full_text_token_count") fullTextExtractedAt DateTime? @map("full_text_extracted_at") // 关联 screeningResults AslScreeningResult[] fulltextScreeningResults AslFulltextScreeningResult[] createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@unique([projectId, pmid]) @@index([projectId]) @@index([doi]) @@index([stage]) @@index([hasPdf]) @@index([pdfStatus]) @@map("literatures") @@schema("asl_schema") } // ASL 筛选结果表 model AslScreeningResult { id String @id @default(uuid()) projectId String @map("project_id") project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade) literatureId String @map("literature_id") literature AslLiterature @relation(fields: [literatureId], references: [id], onDelete: Cascade) // DeepSeek模型判断 dsModelName String @map("ds_model_name") // "deepseek-chat" dsPJudgment String? @map("ds_p_judgment") // "match" | "partial" | "mismatch" dsIJudgment String? @map("ds_i_judgment") dsCJudgment String? @map("ds_c_judgment") dsSJudgment String? @map("ds_s_judgment") dsConclusion String? @map("ds_conclusion") // "include" | "exclude" | "uncertain" dsConfidence Float? @map("ds_confidence") // 0-1 // DeepSeek模型证据 dsPEvidence String? @map("ds_p_evidence") @db.Text dsIEvidence String? @map("ds_i_evidence") @db.Text dsCEvidence String? @map("ds_c_evidence") @db.Text dsSEvidence String? @map("ds_s_evidence") @db.Text dsReason String? @map("ds_reason") @db.Text // Qwen模型判断 qwenModelName String @map("qwen_model_name") // "qwen-max" qwenPJudgment String? @map("qwen_p_judgment") qwenIJudgment String? @map("qwen_i_judgment") qwenCJudgment String? @map("qwen_c_judgment") qwenSJudgment String? @map("qwen_s_judgment") qwenConclusion String? @map("qwen_conclusion") qwenConfidence Float? @map("qwen_confidence") // Qwen模型证据 qwenPEvidence String? @map("qwen_p_evidence") @db.Text qwenIEvidence String? @map("qwen_i_evidence") @db.Text qwenCEvidence String? @map("qwen_c_evidence") @db.Text qwenSEvidence String? @map("qwen_s_evidence") @db.Text qwenReason String? @map("qwen_reason") @db.Text // 冲突状态 conflictStatus String @default("none") @map("conflict_status") // "none" | "conflict" | "resolved" conflictFields Json? @map("conflict_fields") // ["P", "I", "conclusion"] // 最终决策 finalDecision String? @map("final_decision") // "include" | "exclude" | "pending" finalDecisionBy String? @map("final_decision_by") // userId finalDecisionAt DateTime? @map("final_decision_at") exclusionReason String? @map("exclusion_reason") @db.Text // AI处理状态 aiProcessingStatus String @default("pending") @map("ai_processing_status") // "pending" | "processing" | "completed" | "failed" aiProcessedAt DateTime? @map("ai_processed_at") aiErrorMessage String? @map("ai_error_message") @db.Text // 可追溯信息 promptVersion String @default("v1.0.0") @map("prompt_version") rawOutput Json? @map("raw_output") // 原始LLM输出(备份) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@unique([projectId, literatureId]) @@index([projectId]) @@index([literatureId]) @@index([conflictStatus]) @@index([finalDecision]) @@map("screening_results") @@schema("asl_schema") } // ASL 筛选任务表(标题摘要初筛) model AslScreeningTask { id String @id @default(uuid()) projectId String @map("project_id") project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade) taskType String @map("task_type") // "title_abstract" | "full_text" status String @default("pending") // "pending" | "running" | "completed" | "failed" // 进度统计 totalItems Int @map("total_items") processedItems Int @default(0) @map("processed_items") successItems Int @default(0) @map("success_items") failedItems Int @default(0) @map("failed_items") conflictItems Int @default(0) @map("conflict_items") // 时间信息 startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") estimatedEndAt DateTime? @map("estimated_end_at") // 错误信息 errorMessage String? @map("error_message") @db.Text createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([projectId]) @@index([status]) @@map("screening_tasks") @@schema("asl_schema") } // ASL 全文复筛任务表 model AslFulltextScreeningTask { id String @id @default(uuid()) projectId String @map("project_id") project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade) // 任务配置 modelA String @map("model_a") // "deepseek-v3" modelB String @map("model_b") // "qwen-max" promptVersion String @default("v1.0.0") @map("prompt_version") // 任务状态 status String @default("pending") // "pending" | "running" | "completed" | "failed" | "cancelled" // 进度统计 totalCount Int @map("total_count") processedCount Int @default(0) @map("processed_count") successCount Int @default(0) @map("success_count") failedCount Int @default(0) @map("failed_count") degradedCount Int @default(0) @map("degraded_count") // 单模型成功 // 成本统计 totalTokens Int @default(0) @map("total_tokens") totalCost Float @default(0) @map("total_cost") // 时间信息 startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") estimatedEndAt DateTime? @map("estimated_end_at") // 错误信息 errorMessage String? @map("error_message") @db.Text errorStack String? @map("error_stack") @db.Text // 关联 results AslFulltextScreeningResult[] createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([projectId]) @@index([status]) @@index([createdAt]) @@map("fulltext_screening_tasks") @@schema("asl_schema") } // ASL 全文复筛结果表(12字段评估) model AslFulltextScreeningResult { id String @id @default(uuid()) taskId String @map("task_id") task AslFulltextScreeningTask @relation(fields: [taskId], references: [id], onDelete: Cascade) projectId String @map("project_id") project AslScreeningProject @relation(fields: [projectId], references: [id], onDelete: Cascade) literatureId String @map("literature_id") literature AslLiterature @relation(fields: [literatureId], references: [id], onDelete: Cascade) // ====== 模型A结果(DeepSeek-V3)====== modelAName String @map("model_a_name") modelAStatus String @map("model_a_status") // "success" | "failed" modelAFields Json @map("model_a_fields") // 12字段评估 { field1: {...}, field2: {...}, ... } modelAOverall Json @map("model_a_overall") // 总体评估 { decision, confidence, keyIssues } modelAProcessingLog Json? @map("model_a_processing_log") modelAVerification Json? @map("model_a_verification") modelATokens Int? @map("model_a_tokens") modelACost Float? @map("model_a_cost") modelAError String? @map("model_a_error") @db.Text // ====== 模型B结果(Qwen-Max)====== modelBName String @map("model_b_name") modelBStatus String @map("model_b_status") // "success" | "failed" modelBFields Json @map("model_b_fields") // 12字段评估 modelBOverall Json @map("model_b_overall") // 总体评估 modelBProcessingLog Json? @map("model_b_processing_log") modelBVerification Json? @map("model_b_verification") modelBTokens Int? @map("model_b_tokens") modelBCost Float? @map("model_b_cost") modelBError String? @map("model_b_error") @db.Text // ====== 验证结果 ====== medicalLogicIssues Json? @map("medical_logic_issues") // MedicalLogicValidator输出 evidenceChainIssues Json? @map("evidence_chain_issues") // EvidenceChainValidator输出 // ====== 冲突检测 ====== isConflict Boolean @default(false) @map("is_conflict") conflictSeverity String? @map("conflict_severity") // "high" | "medium" | "low" conflictFields String[] @map("conflict_fields") // ["field1", "field9", "overall"] conflictDetails Json? @map("conflict_details") // 详细冲突描述 reviewPriority Int? @map("review_priority") // 0-100复核优先级 reviewDeadline DateTime? @map("review_deadline") // ====== 最终决策 ====== finalDecision String? @map("final_decision") // "include" | "exclude" | null finalDecisionBy String? @map("final_decision_by") // userId finalDecisionAt DateTime? @map("final_decision_at") exclusionReason String? @map("exclusion_reason") @db.Text reviewNotes String? @map("review_notes") @db.Text // ====== 处理状态 ====== processingStatus String @default("pending") @map("processing_status") // "pending" | "processing" | "completed" | "failed" | "degraded" isDegraded Boolean @default(false) @map("is_degraded") // 单模型成功 degradedModel String? @map("degraded_model") // "modelA" | "modelB" processedAt DateTime? @map("processed_at") // ====== 可追溯信息 ====== promptVersion String @default("v1.0.0") @map("prompt_version") rawOutputA Json? @map("raw_output_a") // 模型A原始输出 rawOutputB Json? @map("raw_output_b") // 模型B原始输出 createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@unique([projectId, literatureId]) // 一篇文献只有一个全文复筛结果 @@index([taskId]) @@index([projectId]) @@index([literatureId]) @@index([isConflict]) @@index([finalDecision]) @@index([reviewPriority]) @@map("fulltext_screening_results") @@schema("asl_schema") } // ==================== DC数据清洗模块 - Tool B (病历结构化机器人) ==================== // 健康检查缓存表 model DCHealthCheck { id String @id @default(uuid()) userId String @map("user_id") fileName String @map("file_name") columnName String @map("column_name") // 统计指标 emptyRate Float @map("empty_rate") // 空值率 (0-1) avgLength Float @map("avg_length") // 平均文本长度 totalRows Int @map("total_rows") estimatedTokens Int @map("estimated_tokens") // 检查结果 status String @map("status") // 'good' | 'bad' message String @map("message") createdAt DateTime @default(now()) @map("created_at") @@index([userId, fileName]) @@map("dc_health_checks") @@schema("dc_schema") } // 预设模板表 model DCTemplate { id String @id @default(uuid()) diseaseType String @map("disease_type") // 'lung_cancer', 'diabetes', 'hypertension' reportType String @map("report_type") // 'pathology', 'admission', 'outpatient' displayName String @map("display_name") // '肺癌病理报告' fields Json @map("fields") // [{name, desc, width}] promptTemplate String @map("prompt_template") @db.Text createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@unique([diseaseType, reportType]) @@map("dc_templates") @@schema("dc_schema") } // 提取任务表 model DCExtractionTask { id String @id @default(uuid()) userId String @map("user_id") projectName String @map("project_name") sourceFileKey String @map("source_file_key") // Storage中的路径 textColumn String @map("text_column") // 模板配置 diseaseType String @map("disease_type") reportType String @map("report_type") targetFields Json @map("target_fields") // [{name, desc}] // 双模型配置 modelA String @default("deepseek-v3") @map("model_a") modelB String @default("qwen-max") @map("model_b") // 任务状态 status String @default("pending") @map("status") // 'pending'|'processing'|'completed'|'failed' totalCount Int @default(0) @map("total_count") processedCount Int @default(0) @map("processed_count") cleanCount Int @default(0) @map("clean_count") // 一致数 conflictCount Int @default(0) @map("conflict_count") // 冲突数 failedCount Int @default(0) @map("failed_count") // 成本统计 totalTokens Int @default(0) @map("total_tokens") totalCost Float @default(0) @map("total_cost") // 错误信息 error String? @map("error") // 时间戳 createdAt DateTime @default(now()) @map("created_at") startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") items DCExtractionItem[] @@index([userId, status]) @@map("dc_extraction_tasks") @@schema("dc_schema") } // 提取记录表 (每条病历记录) model DCExtractionItem { id String @id @default(uuid()) taskId String @map("task_id") // 原始数据 rowIndex Int @map("row_index") originalText String @map("original_text") @db.Text // 双模型结果 (V2核心) resultA Json? @map("result_a") // DeepSeek结果 {"肿瘤大小": "3cm"} resultB Json? @map("result_b") // Qwen结果 {"肿瘤大小": "3.0cm"} // 冲突检测 status String @default("pending") @map("status") // 'pending'|'clean'|'conflict'|'resolved'|'failed' conflictFields String[] @default([]) @map("conflict_fields") // ["肿瘤大小"] // 最终结果 (用户裁决后或自动采纳) finalResult Json? @map("final_result") // Token统计 tokensA Int @default(0) @map("tokens_a") tokensB Int @default(0) @map("tokens_b") // 错误信息 error String? @map("error") createdAt DateTime @default(now()) @map("created_at") resolvedAt DateTime? @map("resolved_at") task DCExtractionTask @relation(fields: [taskId], references: [id], onDelete: Cascade) @@index([taskId, status]) @@map("dc_extraction_items") @@schema("dc_schema") } // ==================== DC数据清洗模块 - Tool C (科研数据编辑器) ==================== // Tool C Session 会话表 model DcToolCSession { id String @id @default(uuid()) userId String @map("user_id") fileName String @map("file_name") fileKey String @map("file_key") // OSS存储key: dc/tool-c/sessions/{timestamp}-{fileName} // 数据元信息 totalRows Int @map("total_rows") totalCols Int @map("total_cols") columns Json @map("columns") // ["age", "gender", "diagnosis"] 列名数组 encoding String? @map("encoding") // 文件编码 utf-8, gbk等 fileSize Int @map("file_size") // 文件大小(字节) // 时间戳 createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") expiresAt DateTime @map("expires_at") // 过期时间(创建后10分钟) @@index([userId]) @@index([expiresAt]) @@map("dc_tool_c_sessions") @@schema("dc_schema") } // Tool C AI对话历史表 model DcToolCAiHistory { id String @id @default(uuid()) sessionId String @map("session_id") // 关联Tool C Session userId String @map("user_id") role String @map("role") // user/assistant/system content String @db.Text // 消息内容 // Tool C特有字段 generatedCode String? @db.Text @map("generated_code") // AI生成的代码 codeExplanation String? @db.Text @map("code_explanation") // 代码解释 executeStatus String? @map("execute_status") // pending/success/failed executeResult Json? @map("execute_result") // 执行结果 executeError String? @db.Text @map("execute_error") // 错误信息 retryCount Int @default(0) @map("retry_count") // 重试次数 // LLM相关 model String? @map("model") // deepseek-v3/qwen3等 createdAt DateTime @default(now()) @map("created_at") @@index([sessionId]) @@index([userId]) @@index([createdAt]) @@map("dc_tool_c_ai_history") @@schema("dc_schema") }