kreativortex/prisma/schema.prisma
Jessica Rekcah 4253483f44 jalan
2025-12-02 00:22:34 +07:00

346 lines
9.5 KiB
Plaintext

// 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
}