// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init generator client { provider = "prisma-client" engineType = "client" output = "./generated/prisma" } datasource db { provider = "postgresql" } // ======================================== // AUTH MODELS (imported from auth.prisma) // ======================================== // Note: User, Session, Account, and Verification models are imported from auth.prisma // We need to extend the User model here to add the profile relation model User { id String @id name String email String emailVerified Boolean @default(false) image String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sessions Session[] accounts Account[] profile UserProfile? @@unique([email]) @@map("user") } model Session { id String @id expiresAt DateTime token String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt ipAddress String? userAgent String? userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([token]) @@index([userId]) @@map("session") } model Account { id String @id accountId String providerId String userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) accessToken String? refreshToken String? idToken String? accessTokenExpiresAt DateTime? refreshTokenExpiresAt DateTime? scope String? password String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@map("account") } model Verification { id String @id identifier String value String expiresAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([identifier]) @@map("verification") } // ======================================== // KREATIVORTEX PLATFORM MODELS // ======================================== model UserRole { id String @id @default(cuid()) name String @unique description String permissions String[] // JSON array of permissions createdAt DateTime @default(now()) updatedAt DateTime @updatedAt users UserProfile[] @@map("user_roles") } model UserProfile { id String @id @default(cuid()) userId String @unique roleId String nim String? // Nomor Induk Mahasiswa phone String? address String? bio String? avatar String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) role UserRole @relation(fields: [roleId], references: [id]) // Relations as educator classesTeaching Class[] videos Video[] forums Forum[] assignments Assignment[] // Relations as student classesEnrolled ClassMember[] forumPosts ForumPost[] @relation("ForumPosts") assignmentSubmissions AssignmentSubmission[] comments Comment[] @relation("CommentAuthor") // Additional relations reviewedSubmissions AssignmentSubmission[] @relation("SubmissionReviewer") @@map("user_profiles") } model Class { id String @id @default(cuid()) name String description String code String @unique educatorId String isActive Boolean @default(true) maxStudents Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String updatedBy String educator UserProfile @relation(fields: [educatorId], references: [id], onDelete: Cascade) members ClassMember[] videos Video[] forums Forum[] assignments Assignment[] @@map("classes") } model ClassMember { id String @id @default(cuid()) classId String studentId String joinedAt DateTime @default(now()) isActive Boolean @default(true) class Class @relation(fields: [classId], references: [id], onDelete: Cascade) student UserProfile @relation(fields: [studentId], references: [id], onDelete: Cascade) @@unique([classId, studentId]) @@map("class_members") } model Video { id String @id @default(cuid()) title String description String? videoUrl String videoType VideoType @default(YOUTUBE) thumbnailUrl String? duration Int? // in seconds uploaderId String classId String? isPublic Boolean @default(true) viewCount Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String updatedBy String menuId String? uploader UserProfile @relation(fields: [uploaderId], references: [id], onDelete: Cascade) class Class? @relation(fields: [classId], references: [id], onDelete: SetNull) menu Menu? @relation(fields: [menuId], references: [id], onDelete: SetNull) comments Comment[] @@map("videos") } model Forum { id String @id @default(cuid()) title String description String? type ForumType @default(GENERAL) classId String? createdBy String isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt updatedBy String creator UserProfile @relation(fields: [createdBy], references: [id], onDelete: Cascade) class Class? @relation(fields: [classId], references: [id], onDelete: SetNull) posts ForumPost[] @@map("forums") } model ForumPost { id String @id @default(cuid()) title String content String forumId String authorId String parentId String? // for replies isPinned Boolean @default(false) isActive Boolean @default(true) attachments Json @default("[]") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt updatedBy String forum Forum @relation(fields: [forumId], references: [id], onDelete: Cascade) author UserProfile @relation("ForumPosts", fields: [authorId], references: [id], onDelete: Cascade) parent ForumPost? @relation("PostReplies", fields: [parentId], references: [id], onDelete: Cascade) replies ForumPost[] @relation("PostReplies") comments Comment[] @@map("forum_posts") } model Assignment { id String @id @default(cuid()) title String description String dueDate DateTime classId String educatorId String maxScore Int isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String updatedBy String class Class @relation(fields: [classId], references: [id], onDelete: Cascade) educator UserProfile @relation(fields: [educatorId], references: [id], onDelete: Cascade) submissions AssignmentSubmission[] @@map("assignments") } model AssignmentSubmission { id String @id @default(cuid()) assignmentId String studentId String documentUrl String documentType String // MIME type score Int? feedback String? status SubmissionStatus @default(SUBMITTED) submittedAt DateTime @default(now()) reviewedAt DateTime? reviewedBy String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt updatedBy String assignment Assignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade) student UserProfile @relation(fields: [studentId], references: [id], onDelete: Cascade) reviewer UserProfile? @relation("SubmissionReviewer", fields: [reviewedBy], references: [id], onDelete: SetNull) @@map("assignment_submissions") } model Comment { id String @id @default(cuid()) content String authorId String videoId String? forumPostId String? parentId String? // for replies attachments Json @default("[]") isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt updatedBy String author UserProfile @relation("CommentAuthor", fields: [authorId], references: [id], onDelete: Cascade) video Video? @relation(fields: [videoId], references: [id], onDelete: Cascade) forumPost ForumPost? @relation(fields: [forumPostId], references: [id], onDelete: Cascade) parent Comment? @relation("CommentReplies", fields: [parentId], references: [id], onDelete: Cascade) replies Comment[] @relation("CommentReplies") @@map("comments") } model Menu { id String @id @default(cuid()) name Json slug String @unique description Json parentId String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt updatedBy String parent Menu? @relation("MenuHierarchy", fields: [parentId], references: [id], onDelete: Cascade) children Menu[] @relation("MenuHierarchy") videos Video[] @@map("menus") } // ======================================== // ENUMS // ======================================== enum VideoType { YOUTUBE LOCAL } enum ForumType { GENERAL CLASS } enum SubmissionStatus { SUBMITTED REVIEWED REVISED APPROVED }