001project_wildgrowth/backend/prisma/schema_fixed.prisma

159 lines
5.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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")
}
model User {
id String @id @default(uuid())
phone String? @unique
appleId String? @unique @map("apple_id")
nickname String?
avatar String?
agreementAccepted Boolean @default(false) @map("agreement_accepted")
isPro Boolean @default(false) @map("is_pro") // 是否为付费会员
proExpireDate DateTime? @map("pro_expire_date") // 会员过期时间(可选,预留给订阅制)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
settings UserSettings?
learningProgress UserLearningProgress[]
achievements UserAchievement[]
courses UserCourse[]
@@map("users")
}
model UserSettings {
userId String @id @map("user_id")
pushNotification Boolean @default(true) @map("push_notification")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("user_settings")
}
model Course {
id String @id @default(uuid())
title String
subtitle String? // 课程副标题
description String?
coverImage String? @map("cover_image")
type String @default("system") // ✅ 新增system | single
status String @default("published") // ✅ 新增published | draft
deletedAt DateTime? @map("deleted_at") // ✅ 新增:软删除时间戳
totalNodes Int @default(0) @map("total_nodes")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
chapters CourseChapter[]
nodes CourseNode[]
userCourses UserCourse[]
@@map("courses")
}
model CourseChapter {
id String @id @default(uuid())
courseId String @map("course_id")
title String
orderIndex Int @map("order_index")
createdAt DateTime @default(now()) @map("created_at")
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
nodes CourseNode[]
@@unique([courseId, orderIndex])
@@map("course_chapters")
}
model CourseNode {
id String @id @default(uuid())
courseId String @map("course_id")
chapterId String? @map("chapter_id") // 可选,支持无章节的节点
title String
subtitle String?
orderIndex Int @map("order_index")
duration Int? // 预估时长(分钟)
unlockCondition String? @map("unlock_condition") // 解锁条件
createdAt DateTime @default(now()) @map("created_at")
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
chapter CourseChapter? @relation(fields: [chapterId], references: [id], onDelete: SetNull)
slides NodeSlide[]
learningProgress UserLearningProgress[]
@@unique([courseId, orderIndex])
@@map("course_nodes")
}
model NodeSlide {
id String @id @default(uuid())
nodeId String @map("node_id")
slideType String @map("slide_type") // text | image | quiz | interactive
orderIndex Int @map("order_index")
content Json // 存储卡片内容(灵活结构)
effect String? // fade_in | typewriter | slide_up
interaction String? // tap_to_reveal | zoom | parallax
createdAt DateTime @default(now()) @map("created_at")
node CourseNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
@@map("node_slides")
}
model UserLearningProgress {
id String @id @default(uuid())
userId String @map("user_id")
nodeId String @map("node_id")
status String @default("not_started") // not_started | in_progress | completed
startedAt DateTime? @map("started_at")
completedAt DateTime? @map("completed_at")
totalStudyTime Int @default(0) @map("total_study_time") // 总学习时长(秒)
currentSlide Int @default(0) @map("current_slide") // 当前学习到的幻灯片位置
completionRate Int @default(0) @map("completion_rate") // 完成度(%
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
node CourseNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
@@unique([userId, nodeId])
@@map("user_learning_progress")
}
model UserAchievement {
id String @id @default(uuid())
userId String @map("user_id")
achievementType String @map("achievement_type") // lesson_completed | course_completed
achievementData Json @map("achievement_data") // 存储成就详情
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("user_achievements")
}
model UserCourse {
id String @id @default(uuid())
userId String @map("user_id")
courseId String @map("course_id")
lastOpenedAt DateTime? @map("last_opened_at") // ✅ 新增:最近打开时间,用于排序
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
@@unique([userId, courseId])
@@map("user_courses")
}