api-server/prisma/schema.prisma

535 lines
16 KiB
Plaintext
Raw Normal View History

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id BigInt @id @default(autoincrement())
email String? @db.VarChar(255)
nickname String? @db.VarChar(100)
avatarUrl String? @db.VarChar(500)
status String @default("active") @db.VarChar(32)
onboardingCompleted Boolean @default(false)
lastLoginAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
authAccounts AuthAccount[]
refreshTokens RefreshToken[]
profile UserProfile?
preferences UserPreference?
consents UserConsent[]
knowledgeBases KnowledgeBase[]
knowledgeItems KnowledgeItem[]
knowledgeItemRelations KnowledgeItemRelation[]
tags Tag[]
uploadedFiles UploadedFile[]
documentImports DocumentImport[]
learningSessions LearningSession[]
learningRecords LearningRecord[]
activeRecallQuestions ActiveRecallQuestion[]
activeRecallAnswers ActiveRecallAnswer[]
aiAnalysisJobs AiAnalysisJob[]
aiAnalysisResults AiAnalysisResult[]
focusItems FocusItem[]
reviewCards ReviewCard[]
reviewLogs ReviewLog[]
reviewPlans ReviewPlan[]
dailyLearningActivities DailyLearningActivity[]
notifications Notification[]
feedbacks Feedback[]
@@index([email])
@@index([status])
}
model AuthAccount {
id BigInt @id @default(autoincrement())
userId BigInt
provider String @db.VarChar(32)
providerUserId String @db.VarChar(255)
email String? @db.VarChar(255)
rawProfileJson Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@unique([provider, providerUserId])
@@index([userId])
}
model RefreshToken {
id BigInt @id @default(autoincrement())
userId BigInt
tokenHash String @db.VarChar(255)
deviceId String? @db.VarChar(255)
deviceName String? @db.VarChar(255)
expiresAt DateTime
revokedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([tokenHash])
}
model UserProfile {
id BigInt @id @default(autoincrement())
userId BigInt @unique
learningIdentity String? @db.VarChar(100)
learningDirection String? @db.VarChar(255)
bio String? @db.Text
currentGoal String? @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
}
model UserPreference {
id BigInt @id @default(autoincrement())
userId BigInt @unique
preferredMethods Json?
defaultFocusMinutes Int @default(25)
aiSuggestionLevel String @default("normal") @db.VarChar(32)
language String @default("zh-CN") @db.VarChar(32)
appearance String @default("system") @db.VarChar(32)
notificationEnabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
}
model UserConsent {
id BigInt @id @default(autoincrement())
userId BigInt
consentType String @db.VarChar(32)
version String @db.VarChar(50)
acceptedAt DateTime
ipAddress String? @db.VarChar(100)
userAgent String? @db.VarChar(500)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([consentType])
}
model KnowledgeBase {
id BigInt @id @default(autoincrement())
userId BigInt
title String @db.VarChar(255)
description String? @db.Text
coverKey String? @db.VarChar(100)
status String @default("active") @db.VarChar(32)
itemCount Int @default(0)
lastStudiedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
user User @relation(fields: [userId], references: [id])
items KnowledgeItem[]
focusItems FocusItem[]
@@index([userId])
@@index([status])
}
model KnowledgeItem {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeBaseId BigInt
parentId BigInt?
itemType String @db.VarChar(32)
title String @db.VarChar(255)
content String? @db.LongText
summary String? @db.Text
sourceType String? @db.VarChar(32)
sourceRef String? @db.VarChar(500)
orderIndex Int @default(0)
status String @default("active") @db.VarChar(32)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
user User @relation(fields: [userId], references: [id])
knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id])
parent KnowledgeItem? @relation("KnowledgeItemRelations", fields: [parentId], references: [id])
children KnowledgeItem[] @relation("KnowledgeItemRelations")
tags KnowledgeItemTag[]
@@index([userId])
@@index([knowledgeBaseId])
@@index([parentId])
@@index([itemType])
}
model KnowledgeItemRelation {
id BigInt @id @default(autoincrement())
userId BigInt
sourceItemId BigInt
targetItemId BigInt
relationType String @db.VarChar(32)
confidence Decimal? @db.Decimal(5, 2)
reason String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([sourceItemId])
@@index([targetItemId])
}
model Tag {
id BigInt @id @default(autoincrement())
userId BigInt
name String @db.VarChar(100)
color String? @db.VarChar(32)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
items KnowledgeItemTag[]
@@unique([userId, name])
}
model KnowledgeItemTag {
id BigInt @id @default(autoincrement())
knowledgeItemId BigInt
tagId BigInt
createdAt DateTime @default(now())
knowledgeItem KnowledgeItem @relation(fields: [knowledgeItemId], references: [id])
tag Tag @relation(fields: [tagId], references: [id])
@@unique([knowledgeItemId, tagId])
}
model UploadedFile {
id BigInt @id @default(autoincrement())
userId BigInt
filename String @db.VarChar(255)
mimeType String? @db.VarChar(100)
storagePath String @db.VarChar(500)
sizeBytes BigInt @default(0)
checksum String? @db.VarChar(255)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
@@index([userId])
}
model DocumentImport {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeBaseId BigInt?
fileId BigInt?
sourceType String @db.VarChar(32)
sourceName String? @db.VarChar(255)
sourceUrl String? @db.VarChar(500)
rawText String? @db.LongText
status String @default("pending") @db.VarChar(32)
progress Int @default(0)
errorMessage String? @db.Text
resultJson Json?
startedAt DateTime?
completedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([status])
}
model LearningSession {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeBaseId BigInt?
knowledgeItemId BigInt?
mode String @db.VarChar(32)
status String @default("active") @db.VarChar(32)
startedAt DateTime
endedAt DateTime?
durationSeconds Int @default(0)
focusMinutes Int?
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([knowledgeItemId])
@@index([startedAt])
}
model LearningRecord {
id BigInt @id @default(autoincrement())
userId BigInt
sessionId BigInt?
recordType String @db.VarChar(32)
title String @db.VarChar(255)
description String? @db.Text
durationSeconds Int @default(0)
occurredAt DateTime
metadata Json?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([occurredAt])
}
model ActiveRecallQuestion {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeItemId BigInt?
questionText String @db.Text
difficulty String? @db.VarChar(32)
createdBy String @default("ai") @db.VarChar(32)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
answers ActiveRecallAnswer[]
@@index([userId])
@@index([knowledgeItemId])
}
model ActiveRecallAnswer {
id BigInt @id @default(autoincrement())
userId BigInt
questionId BigInt?
sessionId BigInt?
answerType String @default("text") @db.VarChar(32)
answerText String? @db.LongText
audioFileId BigInt?
submittedAt DateTime
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
question ActiveRecallQuestion? @relation(fields: [questionId], references: [id])
@@index([userId])
@@index([questionId])
@@index([sessionId])
}
model AiAnalysisJob {
id BigInt @id @default(autoincrement())
userId BigInt
sessionId BigInt?
answerId BigInt?
jobType String @db.VarChar(32)
status String @default("pending") @db.VarChar(32)
progress Int @default(0)
errorMessage String? @db.Text
queuedAt DateTime?
startedAt DateTime?
completedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
results AiAnalysisResult[]
@@index([userId])
@@index([status])
@@index([sessionId])
}
model AiAnalysisResult {
id BigInt @id @default(autoincrement())
userId BigInt
jobId BigInt
sessionId BigInt?
answerId BigInt?
summary String? @db.Text
masteryScore Int?
strengths Json?
weaknesses Json?
suggestions Json?
nextActions Json?
rawResult Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
job AiAnalysisJob @relation(fields: [jobId], references: [id])
@@index([userId])
@@index([jobId])
@@index([sessionId])
}
model FocusItem {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeBaseId BigInt?
knowledgeItemId BigInt?
analysisResultId BigInt?
title String @db.VarChar(255)
reason String? @db.Text
suggestion String? @db.Text
priority String @default("normal") @db.VarChar(32)
status String @default("open") @db.VarChar(32)
masteryScore Int?
dueAt DateTime?
completedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
user User @relation(fields: [userId], references: [id])
knowledgeBase KnowledgeBase? @relation(fields: [knowledgeBaseId], references: [id])
@@index([userId])
@@index([status])
@@index([dueAt])
}
model ReviewCard {
id BigInt @id @default(autoincrement())
userId BigInt
knowledgeItemId BigInt?
focusItemId BigInt?
frontText String @db.Text
backText String? @db.Text
difficulty String? @db.VarChar(32)
status String @default("active") @db.VarChar(32)
nextReviewAt DateTime?
intervalDays Int @default(1)
easeFactor Decimal @default(2.50) @db.Decimal(4, 2)
repetitionCount Int @default(0)
lapseCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
user User @relation(fields: [userId], references: [id])
logs ReviewLog[]
@@index([userId])
@@index([nextReviewAt])
@@index([focusItemId])
}
model ReviewLog {
id BigInt @id @default(autoincrement())
userId BigInt
reviewCardId BigInt
sessionId BigInt?
rating String @db.VarChar(32)
responseText String? @db.Text
reviewedAt DateTime
nextReviewAt DateTime?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
reviewCard ReviewCard @relation(fields: [reviewCardId], references: [id])
@@index([userId])
@@index([reviewCardId])
@@index([reviewedAt])
}
model ReviewPlan {
id BigInt @id @default(autoincrement())
userId BigInt
title String @db.VarChar(255)
status String @default("active") @db.VarChar(32)
scheduledAt DateTime?
completedAt DateTime?
cardCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([scheduledAt])
}
model DailyLearningActivity {
id BigInt @id @default(autoincrement())
userId BigInt
activityDate DateTime @db.Date
durationSeconds Int @default(0)
sessionsCount Int @default(0)
activeRecallCount Int @default(0)
reviewCount Int @default(0)
aiAnalysisCount Int @default(0)
completedLoopCount Int @default(0)
activityLevel Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@unique([userId, activityDate])
@@index([userId])
}
model Notification {
id BigInt @id @default(autoincrement())
userId BigInt
type String @db.VarChar(32)
title String @db.VarChar(255)
content String? @db.Text
data Json?
readAt DateTime?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@index([readAt])
@@index([type])
}
model Feedback {
id BigInt @id @default(autoincrement())
userId BigInt?
email String? @db.VarChar(255)
category String @db.VarChar(64)
content String @db.Text
deviceInfo Json?
status String @default("open") @db.VarChar(32)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id])
@@index([userId])
@@index([status])
}
model AppChangelog {
id BigInt @id @default(autoincrement())
version String @db.VarChar(50)
title String @db.VarChar(255)
content String @db.Text
platform String @default("ios") @db.VarChar(32)
publishedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}