chore: initial import to Nexus_Edu
This commit is contained in:
526
backend/prisma/schema.prisma
Normal file
526
backend/prisma/schema.prisma
Normal file
@@ -0,0 +1,526 @@
|
||||
// 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"
|
||||
previewFeatures = ["fullTextIndex"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 基础审计字段模型
|
||||
// =============================================
|
||||
|
||||
model ApplicationUser {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
realName String @map("real_name") @db.VarChar(50)
|
||||
studentId String? @map("student_id") @db.VarChar(20)
|
||||
avatarUrl String? @map("avatar_url") @db.VarChar(500)
|
||||
gender Gender @default(Male)
|
||||
currentSchoolId String? @map("current_school_id") @db.VarChar(36)
|
||||
accountStatus AccountStatus @map("account_status") @default(Active)
|
||||
email String? @db.VarChar(100)
|
||||
phone String? @db.VarChar(20)
|
||||
bio String? @db.Text
|
||||
passwordHash String @map("password_hash") @db.VarChar(255)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
// Relations
|
||||
classMemberships ClassMember[]
|
||||
createdQuestions Question[] @relation("CreatedQuestions")
|
||||
createdExams Exam[] @relation("CreatedExams")
|
||||
submissions StudentSubmission[]
|
||||
messages Message[]
|
||||
|
||||
@@index([studentId])
|
||||
@@index([email])
|
||||
@@index([phone])
|
||||
@@index([currentSchoolId])
|
||||
@@map("application_users")
|
||||
}
|
||||
|
||||
enum Gender {
|
||||
Male
|
||||
Female
|
||||
}
|
||||
|
||||
enum AccountStatus {
|
||||
Active
|
||||
Suspended
|
||||
Graduated
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 组织架构模块
|
||||
// =============================================
|
||||
|
||||
model School {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
name String @db.VarChar(100)
|
||||
regionCode String @map("region_code") @db.VarChar(20)
|
||||
address String? @db.VarChar(200)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
grades Grade[]
|
||||
|
||||
@@index([regionCode])
|
||||
@@map("schools")
|
||||
}
|
||||
|
||||
model Grade {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
schoolId String @map("school_id") @db.VarChar(36)
|
||||
name String @db.VarChar(50)
|
||||
sortOrder Int @map("sort_order")
|
||||
enrollmentYear Int @map("enrollment_year")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
school School @relation(fields: [schoolId], references: [id])
|
||||
classes Class[]
|
||||
|
||||
@@index([schoolId])
|
||||
@@index([enrollmentYear])
|
||||
@@map("grades")
|
||||
}
|
||||
|
||||
model Class {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
gradeId String @map("grade_id") @db.VarChar(36)
|
||||
name String @db.VarChar(50)
|
||||
inviteCode String @unique @map("invite_code") @db.VarChar(10)
|
||||
headTeacherId String? @map("head_teacher_id") @db.VarChar(36)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
grade Grade @relation(fields: [gradeId], references: [id])
|
||||
members ClassMember[]
|
||||
assignments Assignment[]
|
||||
schedules Schedule[]
|
||||
|
||||
@@index([gradeId])
|
||||
@@map("classes")
|
||||
}
|
||||
|
||||
model ClassMember {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
classId String @map("class_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
roleInClass ClassRole @map("role_in_class") @default(Student)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||||
user ApplicationUser @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([classId, userId])
|
||||
@@index([userId])
|
||||
@@map("class_members")
|
||||
}
|
||||
|
||||
enum ClassRole {
|
||||
Student
|
||||
Monitor
|
||||
Committee
|
||||
Teacher
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 教材与知识图谱模块
|
||||
// =============================================
|
||||
|
||||
model Subject {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
name String @db.VarChar(50)
|
||||
code String @unique @db.VarChar(20)
|
||||
icon String? @db.VarChar(50)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
textbooks Textbook[]
|
||||
questions Question[]
|
||||
exams Exam[]
|
||||
|
||||
@@map("subjects")
|
||||
}
|
||||
|
||||
model Textbook {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
subjectId String @map("subject_id") @db.VarChar(36)
|
||||
name String @db.VarChar(100)
|
||||
publisher String @db.VarChar(100)
|
||||
versionYear String @map("version_year") @db.VarChar(20)
|
||||
coverUrl String? @map("cover_url") @db.VarChar(500)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
subject Subject @relation(fields: [subjectId], references: [id])
|
||||
units TextbookUnit[]
|
||||
|
||||
@@index([subjectId])
|
||||
@@map("textbooks")
|
||||
}
|
||||
|
||||
model TextbookUnit {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
textbookId String @map("textbook_id") @db.VarChar(36)
|
||||
name String @db.VarChar(100)
|
||||
sortOrder Int @map("sort_order")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
textbook Textbook @relation(fields: [textbookId], references: [id], onDelete: Cascade)
|
||||
lessons TextbookLesson[]
|
||||
|
||||
@@index([textbookId])
|
||||
@@index([sortOrder])
|
||||
@@map("textbook_units")
|
||||
}
|
||||
|
||||
model TextbookLesson {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
unitId String @map("unit_id") @db.VarChar(36)
|
||||
name String @db.VarChar(100)
|
||||
sortOrder Int @map("sort_order")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
unit TextbookUnit @relation(fields: [unitId], references: [id], onDelete: Cascade)
|
||||
knowledgePoints KnowledgePoint[]
|
||||
|
||||
@@index([unitId])
|
||||
@@index([sortOrder])
|
||||
@@map("textbook_lessons")
|
||||
}
|
||||
|
||||
model KnowledgePoint {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
lessonId String @map("lesson_id") @db.VarChar(36)
|
||||
parentKnowledgePointId String? @map("parent_knowledge_point_id") @db.VarChar(36)
|
||||
name String @db.VarChar(200)
|
||||
difficulty Int
|
||||
description String? @db.Text
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
lesson TextbookLesson @relation(fields: [lessonId], references: [id], onDelete: Cascade)
|
||||
parentKnowledgePoint KnowledgePoint? @relation("KnowledgePointHierarchy", fields: [parentKnowledgePointId], references: [id], onDelete: Cascade)
|
||||
childKnowledgePoints KnowledgePoint[] @relation("KnowledgePointHierarchy")
|
||||
questionAssociations QuestionKnowledge[]
|
||||
|
||||
@@index([lessonId])
|
||||
@@index([parentKnowledgePointId])
|
||||
@@index([difficulty])
|
||||
@@map("knowledge_points")
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 题库资源模块
|
||||
// =============================================
|
||||
|
||||
model Question {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
subjectId String @map("subject_id") @db.VarChar(36)
|
||||
content String @db.Text
|
||||
optionsConfig Json? @map("options_config")
|
||||
questionType QuestionType @map("question_type")
|
||||
answer String @db.Text
|
||||
explanation String? @db.Text
|
||||
difficulty Int @default(3)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
subject Subject @relation(fields: [subjectId], references: [id])
|
||||
creator ApplicationUser @relation("CreatedQuestions", fields: [createdBy], references: [id])
|
||||
knowledgePoints QuestionKnowledge[]
|
||||
examNodes ExamNode[]
|
||||
|
||||
@@index([subjectId])
|
||||
@@index([questionType])
|
||||
@@index([difficulty])
|
||||
@@fulltext([content])
|
||||
@@map("questions")
|
||||
}
|
||||
|
||||
model QuestionKnowledge {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
questionId String @map("question_id") @db.VarChar(36)
|
||||
knowledgePointId String @map("knowledge_point_id") @db.VarChar(36)
|
||||
weight Int @default(100)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
||||
knowledgePoint KnowledgePoint @relation(fields: [knowledgePointId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([questionId, knowledgePointId])
|
||||
@@index([knowledgePointId])
|
||||
@@map("question_knowledge")
|
||||
}
|
||||
|
||||
enum QuestionType {
|
||||
SingleChoice
|
||||
MultipleChoice
|
||||
TrueFalse
|
||||
FillBlank
|
||||
Subjective
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 试卷工程模块
|
||||
// =============================================
|
||||
|
||||
model Exam {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
subjectId String @map("subject_id") @db.VarChar(36)
|
||||
title String @db.VarChar(200)
|
||||
totalScore Decimal @map("total_score") @default(0) @db.Decimal(5, 1)
|
||||
suggestedDuration Int @map("suggested_duration")
|
||||
status ExamStatus @default(Draft)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
subject Subject @relation(fields: [subjectId], references: [id])
|
||||
creator ApplicationUser @relation("CreatedExams", fields: [createdBy], references: [id])
|
||||
nodes ExamNode[]
|
||||
assignments Assignment[]
|
||||
|
||||
@@index([subjectId])
|
||||
@@index([status])
|
||||
@@index([createdBy])
|
||||
@@map("exams")
|
||||
}
|
||||
|
||||
model ExamNode {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
examId String @map("exam_id") @db.VarChar(36)
|
||||
parentNodeId String? @map("parent_node_id") @db.VarChar(36)
|
||||
nodeType NodeType @map("node_type")
|
||||
questionId String? @map("question_id") @db.VarChar(36)
|
||||
title String? @db.VarChar(200)
|
||||
description String? @db.Text
|
||||
score Decimal @db.Decimal(5, 1)
|
||||
sortOrder Int @map("sort_order")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
exam Exam @relation(fields: [examId], references: [id], onDelete: Cascade)
|
||||
parentNode ExamNode? @relation("ExamNodeHierarchy", fields: [parentNodeId], references: [id], onDelete: Cascade)
|
||||
childNodes ExamNode[] @relation("ExamNodeHierarchy")
|
||||
question Question? @relation(fields: [questionId], references: [id])
|
||||
submissionDetails SubmissionDetail[]
|
||||
|
||||
@@index([examId])
|
||||
@@index([parentNodeId])
|
||||
@@index([sortOrder])
|
||||
@@index([questionId])
|
||||
@@map("exam_nodes")
|
||||
}
|
||||
|
||||
enum ExamStatus {
|
||||
Draft
|
||||
Published
|
||||
}
|
||||
|
||||
enum NodeType {
|
||||
Group
|
||||
Question
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 教学执行模块
|
||||
// =============================================
|
||||
|
||||
model Assignment {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
examId String @map("exam_id") @db.VarChar(36)
|
||||
classId String @map("class_id") @db.VarChar(36)
|
||||
title String @db.VarChar(200)
|
||||
startTime DateTime @map("start_time")
|
||||
endTime DateTime @map("end_time")
|
||||
allowLateSubmission Boolean @map("allow_late_submission") @default(false)
|
||||
autoScoreEnabled Boolean @map("auto_score_enabled") @default(true)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
exam Exam @relation(fields: [examId], references: [id])
|
||||
class Class @relation(fields: [classId], references: [id])
|
||||
submissions StudentSubmission[]
|
||||
|
||||
@@index([examId])
|
||||
@@index([classId])
|
||||
@@index([startTime])
|
||||
@@index([endTime])
|
||||
@@map("assignments")
|
||||
}
|
||||
|
||||
model StudentSubmission {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
assignmentId String @map("assignment_id") @db.VarChar(36)
|
||||
studentId String @map("student_id") @db.VarChar(36)
|
||||
submissionStatus SubmissionStatus @map("submission_status") @default(Pending)
|
||||
submitTime DateTime? @map("submit_time")
|
||||
timeSpentSeconds Int? @map("time_spent_seconds")
|
||||
totalScore Decimal? @map("total_score") @db.Decimal(5, 1)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
||||
student ApplicationUser @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
||||
details SubmissionDetail[]
|
||||
|
||||
@@unique([assignmentId, studentId])
|
||||
@@index([studentId])
|
||||
@@index([submitTime])
|
||||
@@index([submissionStatus])
|
||||
@@map("student_submissions")
|
||||
}
|
||||
|
||||
model SubmissionDetail {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
submissionId String @map("submission_id") @db.VarChar(36)
|
||||
examNodeId String @map("exam_node_id") @db.VarChar(36)
|
||||
studentAnswer String? @map("student_answer") @db.Text
|
||||
gradingData Json? @map("grading_data")
|
||||
score Decimal? @db.Decimal(5, 1)
|
||||
judgement JudgementResult?
|
||||
teacherComment String? @map("teacher_comment") @db.Text
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
createdBy String @map("created_by") @db.VarChar(36)
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
updatedBy String @map("updated_by") @db.VarChar(36)
|
||||
isDeleted Boolean @default(false) @map("is_deleted")
|
||||
|
||||
submission StudentSubmission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
|
||||
examNode ExamNode @relation(fields: [examNodeId], references: [id])
|
||||
|
||||
@@unique([submissionId, examNodeId])
|
||||
@@index([examNodeId])
|
||||
@@index([judgement])
|
||||
@@map("submission_details")
|
||||
}
|
||||
|
||||
enum SubmissionStatus {
|
||||
Pending
|
||||
Submitted
|
||||
Grading
|
||||
Graded
|
||||
}
|
||||
|
||||
enum JudgementResult {
|
||||
Correct
|
||||
Incorrect
|
||||
Partial
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 辅助功能模块
|
||||
// =============================================
|
||||
|
||||
model Message {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
title String @db.VarChar(200)
|
||||
content String @db.Text
|
||||
type String @db.VarChar(20) // Announcement, Notification, Alert
|
||||
senderName String @map("sender_name") @db.VarChar(50)
|
||||
isRead Boolean @default(false) @map("is_read")
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
user ApplicationUser @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId])
|
||||
@@map("messages")
|
||||
}
|
||||
|
||||
model Schedule {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
classId String @map("class_id") @db.VarChar(36)
|
||||
subject String @db.VarChar(50)
|
||||
room String? @db.VarChar(50)
|
||||
dayOfWeek Int @map("day_of_week") // 1-7
|
||||
period Int // 1-8
|
||||
startTime String @map("start_time") @db.VarChar(10) // HH:mm
|
||||
endTime String @map("end_time") @db.VarChar(10) // HH:mm
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([classId])
|
||||
@@map("schedules")
|
||||
}
|
||||
Reference in New Issue
Block a user