2026-05-09 18:25:04 +08:00
|
|
|
generator client {
|
2026-05-09 19:37:15 +08:00
|
|
|
provider = "prisma-client-js"
|
|
|
|
|
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
2026-05-09 18:25:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
datasource db {
|
|
|
|
|
provider = "mysql"
|
|
|
|
|
url = env("DATABASE_URL")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model User {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
2026-05-09 18:25:04 +08:00
|
|
|
email String? @db.VarChar(255)
|
|
|
|
|
nickname String? @db.VarChar(100)
|
|
|
|
|
avatarUrl String? @db.VarChar(500)
|
2026-05-13 17:31:50 +08:00
|
|
|
role String @default("USER") @db.VarChar(32)
|
2026-05-09 18:25:04 +08:00
|
|
|
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[]
|
2026-05-17 00:39:46 +08:00
|
|
|
aiUsageLogs AiUsageLog[]
|
2026-05-09 18:25:04 +08:00
|
|
|
|
|
|
|
|
@@index([email])
|
|
|
|
|
@@index([status])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model AuthAccount {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String @unique
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String @unique
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeBaseId String
|
|
|
|
|
parentId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
sourceItemId String
|
|
|
|
|
targetItemId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
knowledgeItemId String
|
|
|
|
|
tagId String
|
2026-05-09 18:25:04 +08:00
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
knowledgeItem KnowledgeItem @relation(fields: [knowledgeItemId], references: [id])
|
|
|
|
|
tag Tag @relation(fields: [tagId], references: [id])
|
|
|
|
|
|
|
|
|
|
@@unique([knowledgeItemId, tagId])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model UploadedFile {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeBaseId String?
|
|
|
|
|
fileId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeBaseId String?
|
|
|
|
|
knowledgeItemId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
sessionId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeItemId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
questionId String?
|
|
|
|
|
sessionId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
answerType String @default("text") @db.VarChar(32)
|
|
|
|
|
answerText String? @db.LongText
|
2026-05-17 00:39:46 +08:00
|
|
|
audioFileId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
sessionId String?
|
|
|
|
|
answerId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
jobId String
|
|
|
|
|
sessionId String?
|
|
|
|
|
answerId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeBaseId String?
|
|
|
|
|
knowledgeItemId String?
|
|
|
|
|
analysisResultId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
knowledgeItemId String?
|
|
|
|
|
focusItemId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
reviewCardId String
|
|
|
|
|
sessionId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
2026-05-09 18:25:04 +08:00
|
|
|
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 {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String?
|
2026-05-09 18:25:04 +08:00
|
|
|
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])
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 00:39:46 +08:00
|
|
|
model AiUsageLog {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
userId String
|
|
|
|
|
feature String @db.VarChar(64)
|
|
|
|
|
provider String @db.VarChar(32)
|
|
|
|
|
model String @db.VarChar(100)
|
|
|
|
|
tier String @db.VarChar(32)
|
|
|
|
|
promptKey String @db.VarChar(128)
|
|
|
|
|
promptVersion String @db.VarChar(32)
|
|
|
|
|
inputTokens Int @default(0)
|
|
|
|
|
outputTokens Int @default(0)
|
|
|
|
|
estimatedCost Float @default(0)
|
|
|
|
|
latencyMs Int @default(0)
|
|
|
|
|
success Boolean @default(true)
|
|
|
|
|
errorMessage String? @db.VarChar(500)
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
user User @relation(fields: [userId], references: [id])
|
|
|
|
|
|
|
|
|
|
@@index([userId])
|
|
|
|
|
@@index([feature])
|
|
|
|
|
@@index([createdAt])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
model WaitlistEntry {
|
|
|
|
|
id String @id @default(cuid())
|
|
|
|
|
nickname String @db.VarChar(100)
|
|
|
|
|
email String @db.VarChar(255)
|
|
|
|
|
devices Json?
|
|
|
|
|
interests Json?
|
|
|
|
|
painpoint String? @db.Text
|
|
|
|
|
willingBeta Boolean @default(false)
|
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
|
|
|
|
|
|
@@index([email])
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-09 18:25:04 +08:00
|
|
|
model AppChangelog {
|
2026-05-17 00:39:46 +08:00
|
|
|
id String @id @default(cuid())
|
2026-05-09 18:25:04 +08:00
|
|
|
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
|
|
|
|
|
}
|