first-update

This commit is contained in:
2026-03-17 14:36:31 +08:00
parent 72f08aee7c
commit 4eddf05e79
516 changed files with 115270 additions and 1 deletions

View File

@@ -0,0 +1,48 @@
/**
* 此脚本用于生成空的模板数据库文件template.sqlite
* 该文件将在应用打包时被包含,并在用户首次启动应用时作为初始数据库
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const templatePath = path.join(__dirname, 'template.sqlite');
const sqlitePath = path.join(__dirname, 'empty.db.sqlite');
// 如果存在旧的模板文件,先删除
if (fs.existsSync(templatePath)) {
console.log('删除旧的模板数据库...');
fs.unlinkSync(templatePath);
}
// 如果存在临时数据库文件,先删除
if (fs.existsSync(sqlitePath)) {
console.log('删除临时数据库文件...');
fs.unlinkSync(sqlitePath);
}
try {
console.log('设置临时数据库路径...');
// 设置 DATABASE_URL 环境变量
process.env.DATABASE_URL = `file:${sqlitePath}`;
console.log('执行 prisma db push 创建新的数据库架构...');
// 执行 prisma db push 创建数据库架构
execSync('npx prisma db push', { stdio: 'inherit' });
console.log('将生成的数据库文件复制为模板...');
// 复制生成的数据库文件为模板
fs.copyFileSync(sqlitePath, templatePath);
console.log(`✅ 模板数据库已成功生成: ${templatePath}`);
} catch (error) {
console.error('❌ 生成模板数据库失败:', error);
process.exit(1);
} finally {
// 清理: 删除临时数据库文件
if (fs.existsSync(sqlitePath)) {
console.log('清理临时数据库文件...');
fs.unlinkSync(sqlitePath);
}
}

View File

@@ -0,0 +1,406 @@
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])
}

View File

@@ -0,0 +1,88 @@
[
{
"version": "1.2.5",
"sql": "ALTER TABLE Projects ADD COLUMN test VARCHAR(255) DEFAULT '';"
},
{
"version": "1.3.3",
"sql": "CREATE TABLE IF NOT EXISTS Task (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n taskType VARCHAR(255) NOT NULL,\n status INT NOT NULL,\n startTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n endTime TIMESTAMP NULL,\n completedCount INT DEFAULT 0,\n totalCount INT DEFAULT 0,\n modelInfo TEXT NOT NULL,\n language VARCHAR(20) DEFAULT 'zh-CN',\n detail TEXT DEFAULT '',\n note TEXT DEFAULT '',\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE\n);\n\nCREATE INDEX idx_task_projectId ON Task(projectId);"
},
{
"version": "1.3.6",
"sql": "CREATE TABLE IF NOT EXISTS GaPairs (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n fileId VARCHAR(255) NOT NULL,\n pairNumber INT NOT NULL,\n genreTitle VARCHAR(255) NOT NULL,\n genreDesc TEXT NOT NULL,\n audienceTitle VARCHAR(255) NOT NULL,\n audienceDesc TEXT NOT NULL,\n isActive BOOLEAN DEFAULT 1 NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n FOREIGN KEY (fileId) REFERENCES UploadFiles(id) ON DELETE CASCADE,\n UNIQUE (fileId, pairNumber)\n);\n\nCREATE INDEX idx_gapairs_projectId ON GaPairs(projectId);\nCREATE INDEX idx_gapairs_fileId ON GaPairs(fileId);"
},
{
"version": "1.3.6",
"sql": "ALTER TABLE Questions ADD COLUMN gaPairId VARCHAR(255) NULL;"
},
{
"version": "1.3.6",
"sql": "ALTER TABLE Questions ADD FOREIGN KEY (gaPairId) REFERENCES GaPairs(id) ON DELETE SET NULL;\n\nCREATE INDEX idx_questions_gaPairId ON Questions(gaPairId);"
},
{
"version": "1.4.0",
"sql": "ALTER TABLE Datasets ADD COLUMN score REAL DEFAULT 0 NOT NULL;\nALTER TABLE Datasets ADD COLUMN tags TEXT DEFAULT '[]' NOT NULL;\nALTER TABLE Datasets ADD COLUMN note TEXT DEFAULT '' NOT NULL;\nALTER TABLE Datasets ADD COLUMN other TEXT DEFAULT '' NOT NULL;\nALTER TABLE Projects ADD COLUMN cleanPrompt TEXT DEFAULT '' NOT NULL;"
},
{
"version": "1.5.0",
"sql": "CREATE TABLE IF NOT EXISTS CustomPrompts (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n promptType VARCHAR(255) NOT NULL,\n promptKey VARCHAR(255) NOT NULL,\n language VARCHAR(10) NOT NULL,\n content TEXT NOT NULL,\n isActive BOOLEAN DEFAULT 1 NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n UNIQUE (projectId, promptType, promptKey, language)\n);\n\nCREATE INDEX idx_customprompts_projectId ON CustomPrompts(projectId);\nCREATE INDEX idx_customprompts_project_type ON CustomPrompts(projectId, promptType);\nCREATE INDEX idx_customprompts_project_language ON CustomPrompts(projectId, language);"
},
{
"version": "1.5.0",
"sql": "ALTER TABLE Datasets ADD COLUMN aiEvaluation TEXT DEFAULT '' NOT NULL;"
},
{
"version": "1.5.0",
"sql": "CREATE TABLE IF NOT EXISTS DatasetConversations (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n questionId VARCHAR(255) NOT NULL,\n question TEXT NOT NULL,\n chunkId VARCHAR(255) NOT NULL,\n model VARCHAR(255) NOT NULL,\n questionLabel VARCHAR(255) NOT NULL,\n score REAL DEFAULT 0 NOT NULL,\n aiEvaluation TEXT DEFAULT '' NOT NULL,\n tags TEXT DEFAULT '' NOT NULL,\n note TEXT DEFAULT '' NOT NULL,\n scenario TEXT NOT NULL,\n roleA TEXT NOT NULL,\n roleB TEXT NOT NULL,\n turnCount INT NOT NULL,\n maxTurns INT NOT NULL,\n rawMessages TEXT NOT NULL,\n confirmed BOOLEAN DEFAULT 0 NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE\n);\n\nCREATE INDEX idx_datasetconversations_projectId ON DatasetConversations(projectId);"
},
{
"version": "1.6.0",
"description": "为 Questions 表添加图片相关字段",
"sql": "ALTER TABLE Questions ADD COLUMN imageId VARCHAR(255) NULL;\nALTER TABLE Questions ADD COLUMN imageName VARCHAR(255) NULL;\nALTER TABLE Questions ADD COLUMN templateId VARCHAR(255) NULL;"
},
{
"version": "1.6.0",
"description": "为 Questions 表添加图片相关索引",
"sql": "CREATE INDEX idx_questions_imageId ON Questions(imageId);\nCREATE INDEX idx_questions_templateId ON Questions(templateId);"
},
{
"version": "1.6.0",
"description": "为 Datasets 表添加 answerType 字段",
"sql": "ALTER TABLE Datasets ADD COLUMN answerType VARCHAR(50) DEFAULT 'text';"
},
{
"version": "1.6.0",
"description": "创建 Images 表",
"sql": "CREATE TABLE IF NOT EXISTS Images (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n imageName VARCHAR(255) NOT NULL,\n path TEXT NOT NULL,\n size INT NOT NULL,\n width INT NULL,\n height INT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n UNIQUE (projectId, imageName)\n);\n\nCREATE INDEX idx_images_projectId ON Images(projectId);"
},
{
"version": "1.6.0",
"description": "创建 ImageDatasets 表",
"sql": "CREATE TABLE IF NOT EXISTS ImageDatasets (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n imageId VARCHAR(255) NOT NULL,\n imageName VARCHAR(255) NOT NULL,\n questionId VARCHAR(255) NULL,\n question TEXT NOT NULL,\n answer TEXT NOT NULL,\n answerType VARCHAR(50) DEFAULT 'text',\n model VARCHAR(255) NOT NULL,\n confirmed BOOLEAN DEFAULT 0 NOT NULL,\n score REAL DEFAULT 0 NOT NULL,\n tags TEXT DEFAULT '' NOT NULL,\n note TEXT DEFAULT '' NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n FOREIGN KEY (imageId) REFERENCES Images(id) ON DELETE CASCADE\n);\n\nCREATE INDEX idx_imagedatasets_projectId ON ImageDatasets(projectId);\nCREATE INDEX idx_imagedatasets_imageId ON ImageDatasets(imageId);\nCREATE INDEX idx_imagedatasets_questionId ON ImageDatasets(questionId);"
},
{
"version": "1.6.0",
"description": "创建 QuestionTemplates 表",
"sql": "CREATE TABLE IF NOT EXISTS QuestionTemplates (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n question TEXT NOT NULL,\n sourceType VARCHAR(50) NOT NULL,\n answerType VARCHAR(50) NOT NULL,\n description TEXT DEFAULT '' NOT NULL,\n labels TEXT DEFAULT '' NOT NULL,\n customFormat TEXT DEFAULT '' NOT NULL,\n \"order\" INT DEFAULT 0 NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE\n);\n\nCREATE INDEX idx_questiontemplates_projectId ON QuestionTemplates(projectId);\nCREATE INDEX idx_questiontemplates_project_source ON QuestionTemplates(projectId, sourceType);"
},
{
"version": "1.6.2",
"description": "创建 LlmUsageLogs 表 - LLM 调用统计日志",
"sql": "CREATE TABLE IF NOT EXISTS LlmUsageLogs (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n provider VARCHAR(255) NOT NULL,\n model VARCHAR(255) NOT NULL,\n inputTokens INT DEFAULT 0 NOT NULL,\n outputTokens INT DEFAULT 0 NOT NULL,\n totalTokens INT DEFAULT 0 NOT NULL,\n latency INT DEFAULT 0 NOT NULL,\n status VARCHAR(50) DEFAULT 'SUCCESS' NOT NULL,\n errorMessage TEXT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n dateString VARCHAR(10) NOT NULL,\n PRIMARY KEY (id)\n);\n\nCREATE INDEX idx_llmusagelogs_project_date ON LlmUsageLogs(projectId, dateString);\nCREATE INDEX idx_llmusagelogs_dateString ON LlmUsageLogs(dateString);\nCREATE INDEX idx_llmusagelogs_provider ON LlmUsageLogs(provider);\nCREATE INDEX idx_llmusagelogs_model ON LlmUsageLogs(model);"
},
{
"version": "1.6.2",
"description": "为 Tags 和 Questions 表添加索引",
"sql": "CREATE INDEX idx_tags_project_label ON Tags(projectId, label);\nCREATE INDEX idx_tags_project_parentId ON Tags(projectId, parentId);\nCREATE INDEX idx_questions_project_label ON Questions(projectId, label);"
},
{
"version": "1.7.0",
"description": "创建 EvalDatasets 表",
"sql": "CREATE TABLE IF NOT EXISTS EvalDatasets (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n question TEXT NOT NULL,\n questionType VARCHAR(50) NOT NULL,\n chunkId VARCHAR(255) NULL,\n options TEXT DEFAULT '' NOT NULL,\n correctAnswer TEXT NOT NULL,\n tags TEXT DEFAULT '' NOT NULL,\n note TEXT DEFAULT '' NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n FOREIGN KEY (chunkId) REFERENCES Chunks(id) ON DELETE SET NULL\n);\n\nCREATE INDEX idx_evaldatasets_projectId ON EvalDatasets(projectId);\nCREATE INDEX idx_evaldatasets_project_type ON EvalDatasets(projectId, questionType);\nCREATE INDEX idx_evaldatasets_chunkId ON EvalDatasets(chunkId);"
},
{
"version": "1.7.0",
"description": "创建 EvalResults 表",
"sql": "CREATE TABLE IF NOT EXISTS EvalResults (\n id VARCHAR(255) NOT NULL,\n projectId VARCHAR(255) NOT NULL,\n taskId VARCHAR(255) NOT NULL,\n evalDatasetId VARCHAR(255) NOT NULL,\n modelAnswer TEXT NOT NULL,\n score REAL DEFAULT 0 NOT NULL,\n isCorrect BOOLEAN DEFAULT 0 NOT NULL,\n judgeResponse TEXT DEFAULT '' NOT NULL,\n duration INT DEFAULT 0 NOT NULL,\n status INT DEFAULT 0 NOT NULL,\n errorMessage TEXT DEFAULT '' NOT NULL,\n createAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updateAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n FOREIGN KEY (projectId) REFERENCES Projects(id) ON DELETE CASCADE,\n FOREIGN KEY (evalDatasetId) REFERENCES EvalDatasets(id) ON DELETE CASCADE,\n UNIQUE (taskId, evalDatasetId)\n);\n\nCREATE INDEX idx_evalresults_projectId ON EvalResults(projectId);\nCREATE INDEX idx_evalresults_taskId ON EvalResults(taskId);\nCREATE INDEX idx_evalresults_evalDatasetId ON EvalResults(evalDatasetId);"
}
]