generator client { provider = "prisma-client-js" binaryTargets = ["native", "darwin-arm64", "darwin", "windows", "debian-openssl-3.0.x", "linux-arm64-openssl-3.0.x", "debian-openssl-1.1.x"] } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model Projects { id String @id @default(nanoid(12)) name String description String globalPrompt String @default("") questionPrompt String @default("") answerPrompt String @default("") labelPrompt String @default("") domainTreePrompt String @default("") cleanPrompt String @default("") defaultModelConfigId String? test String @default("") createAt DateTime @default(now()) updateAt DateTime @updatedAt Questions Questions[] Datasets Datasets[] DatasetConversations DatasetConversations[] Chunks Chunks[] ModelConfig ModelConfig[] UploadFiles UploadFiles[] Tags Tags[] Task Task[] GaPairs GaPairs[] CustomPrompts CustomPrompts[] Images Images[] ImageDatasets ImageDatasets[] QuestionTemplates QuestionTemplates[] EvalDatasets EvalDatasets[] } model UploadFiles { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String fileName String fileExt String path String size Int md5 String createAt DateTime @default(now()) updateAt DateTime @updatedAt GaPairs GaPairs[] } model Chunks { id String @id @default(nanoid()) name String project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String fileId String fileName String content String summary String size Int createAt DateTime @default(now()) updateAt DateTime @updatedAt Questions Questions[] EvalDatasets EvalDatasets[] @@index([projectId]) } model Tags { id String @id @default(nanoid()) label String project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String parentId String? parent Tags? @relation("Tags", fields: [parentId], references: [id]) children Tags[] @relation("Tags") @@index([projectId, label]) @@index([projectId, parentId]) } model Questions { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String chunk Chunks @relation(fields: [chunkId], references: [id]) chunkId String gaPair GaPairs? @relation(fields: [gaPairId], references: [id]) gaPairId String? // Optional: links question to the GA pair that generated it question String label String answered Boolean @default(false) imageId String? // Optional: for image-based questions imageName String? // Optional: for image-based questions templateId String? // Optional: links to ImageQuestionTemplates createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) @@index([imageId]) @@index([templateId]) @@index([projectId, label]) } model Datasets { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String questionId String question String answer String answerType String? @default("text") // 'text' | 'label' | 'custom_format' chunkName String chunkContent String model String questionLabel String cot String confirmed Boolean @default(false) score Float @default(0) aiEvaluation String @default("") // AI评估结论 tags String @default("") note String @default("") other String @default("") // 存储其他字段的JSON字符串 createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) @@index([projectId, confirmed, createAt, id], name: "idx_export_confirmed") @@index([projectId, createAt], name: "idx_project_createAt") } model DatasetConversations { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String questionId String // 第一个问题 Id(初始问题) question String // 第一个问题(初始问题) chunkId String // 基于哪个文本块生成 model String questionLabel String score Float @default(0) aiEvaluation String @default("") // AI评估结论 tags String @default("") note String @default("") scenario String // 对话场景(教学/咨询/讨论等) roleA String // 角色A设定 roleB String // 角色B设定 turnCount Int // 实际轮数 maxTurns Int // 设置的最大轮数 rawMessages String // JSON存储完整对话(和 ShareGPT 格式保持完全一致) confirmed Boolean @default(false) createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) } model LlmProviders { id String @id name String apiUrl String createAt DateTime @default(now()) updateAt DateTime @updatedAt LlmModels LlmModels[] } model LlmModels { id String @id @default(nanoid()) modelId String modelName String provider LlmProviders @relation(fields: [providerId], references: [id]) providerId String createAt DateTime @default(now()) updateAt DateTime @updatedAt } model ModelConfig { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String providerId String providerName String endpoint String apiKey String modelId String modelName String type String temperature Float maxTokens Int topP Float topK Float status Int createAt DateTime @default(now()) updateAt DateTime @updatedAt } model Task { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String taskType String // 任务类型: text-processing, question-generation, answer-generation, data-distillation status Int // 任务状态: 0-处理中, 1-已完成, 2-失败, 3-已中断 startTime DateTime @default(now()) endTime DateTime? completedCount Int @default(0) totalCount Int @default(0) modelInfo String // JSON格式存储,包含使用的模型信息 language String @default("zh-CN") detail String @default("") // 任务详情 note String @default("") // 任务备注 createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) } model CustomPrompts { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String promptType String // 提示词类型,对应 lib/llm/prompts 下的文件名 promptKey String // 提示词在模块中的键名,如 QUESTION_PROMPT, QUESTION_PROMPT_EN language String // 语言: zh-CN, en content String // 自定义的提示词内容 isActive Boolean @default(true) // 是否启用 createAt DateTime @default(now()) updateAt DateTime @updatedAt @@unique([projectId, promptType, promptKey, language]) @@index([projectId, promptType]) @@index([projectId, language]) } model GaPairs { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String uploadFile UploadFiles @relation(fields: [fileId], references: [id], onDelete: Cascade) fileId String pairNumber Int // 1-5, representing the 5 generated pairs genreTitle String // Genre name/title genreDesc String // Genre description audienceTitle String // Audience name/title audienceDesc String // Audience description isActive Boolean @default(true) // Whether this pair is active for use questions Questions[] // Questions generated by this GA pair createAt DateTime @default(now()) updateAt DateTime @updatedAt @@unique([fileId, pairNumber]) @@index([projectId]) @@index([fileId]) } model Images { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String imageName String path String // 图片存储路径 size Int // 文件大小(字节) width Int? // 图片宽度 height Int? // 图片高度 createAt DateTime @default(now()) updateAt DateTime @updatedAt ImageDatasets ImageDatasets[] @@unique([projectId, imageName]) @@index([projectId]) } model ImageDatasets { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String image Images @relation(fields: [imageId], references: [id], onDelete: Cascade) imageId String imageName String questionId String? // Optional: links to Questions table question String answer String // Stores all answer types: text, JSON array for labels, or custom format JSON answerType String @default("text") // 'text' | 'label' | 'custom_format' model String confirmed Boolean @default(false) score Float @default(0) tags String @default("") note String @default("") createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) @@index([imageId]) @@index([questionId]) } model QuestionTemplates { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String question String // Question content sourceType String // 'image' | 'text' - data source type answerType String // 'text' | 'label' | 'custom_format' description String @default("") // Question description labels String @default("") // JSON array of label options (for answerType='label') customFormat String @default("") // Custom format definition (for answerType='custom_format') order Int @default(0) // Display order createAt DateTime @default(now()) updateAt DateTime @updatedAt @@index([projectId]) @@index([projectId, sourceType]) } model LlmUsageLogs { id String @id @default(nanoid()) projectId String provider String // 提供商: openai, anthropic, google 等 model String // 模型名称 // 核心指标 inputTokens Int @default(0) outputTokens Int @default(0) totalTokens Int @default(0) latency Int @default(0) // 响应耗时(毫秒) // 状态与追踪 status String @default("SUCCESS") // 状态: "SUCCESS", "FAILED" errorMessage String? // 失败原因,status="FAILED" 时填写 // 时间维度 createAt DateTime @default(now()) dateString String // 格式 "YYYY-MM-DD",用于快速按天聚合 @@index([projectId, dateString]) @@index([dateString]) @@index([provider]) @@index([model]) } model EvalDatasets { id String @id @default(nanoid()) project Projects @relation(fields: [projectId], references: [id], onDelete: Cascade) projectId String // 题目内容 question String // 题目内容 questionType String // 题型: true_false, single_choice, multiple_choice, short_answer, open_ended // 上下文信息(关联到文本块) chunkId String? // 关联到 Chunks 表 chunks Chunks? @relation(fields: [chunkId], references: [id]) // 选项(仅选择题使用) options String @default("") // JSON数组: ["选项A", "选项B", "选项C", "选项D"] // 标准答案 correctAnswer String // 标准答案 tags String @default("") // 标签,逗号分隔 note String @default("") // 备注 // 时间戳 createAt DateTime @default(now()) updateAt DateTime @updatedAt // 关联评估结果 EvalResults EvalResults[] @@index([projectId]) @@index([projectId, questionType]) @@index([chunkId]) } model EvalResults { id String @id @default(nanoid()) projectId String taskId String // 关联到 Task 表 // 关联评估题目 evalDataset EvalDatasets @relation(fields: [evalDatasetId], references: [id], onDelete: Cascade) evalDatasetId String // 评估结果 modelAnswer String // 模型的回答 score Float @default(0) // 得分 (0-1 之间) isCorrect Boolean @default(false) // 是否正确(用于客观题) judgeResponse String @default("") // LLM 评分的响应(用于主观题) // 答题详情 duration Int @default(0) // 答题耗时(毫秒) status Int @default(0) // 答题状态:0-成功, 1-输出不符合规范, 2-LLM调用报错 errorMessage String @default("") // 答题报错信息 // 时间戳 createAt DateTime @default(now()) updateAt DateTime @updatedAt @@unique([taskId, evalDatasetId]) // 每个任务对每道题只能有一个结果 @@index([projectId]) @@index([taskId]) @@index([evalDatasetId]) }