Initial commit

This commit is contained in:
twotalesanimation
2026-06-11 10:46:09 +02:00
commit 81ad7e4ea9
223 changed files with 39530 additions and 0 deletions
+266
View File
@@ -0,0 +1,266 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
image String?
createdAt DateTime @default(now())
emailVerified DateTime?
role String @default("user")
accounts Account[]
comments Comment[]
replies CommentReply[]
enrollments Enrollment[]
sessions Session[]
likes VideoLike[]
progress VideoProgress[]
unlocks VideoUnlock[]
watchSegments VideoWatchSegment[]
uploadedVideos Video[] @relation("VideoUploader")
createdCourses Course[] @relation("CourseCreator")
createdPlaylists Playlist[] @relation("PlaylistCreator")
}
model Course {
id String @id @default(cuid())
code String @unique
title String
description String?
userId String?
createdAt DateTime @default(now())
creator User? @relation("CourseCreator", fields: [userId], references: [id], onDelete: SetNull)
enrollments Enrollment[]
playlists Playlist[]
playlistMappings CoursePlaylist[]
courseVideos VideoCourse[]
}
model Enrollment {
id String @id @default(cuid())
userId String
courseId String
createdAt DateTime @default(now())
course Course @relation(fields: [courseId], references: [id])
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, courseId])
@@index([courseId])
}
model Playlist {
id String @id @default(cuid())
title String
description String?
courseId String // Primary course (backwards compatibility)
userId String?
sortOrder Int @default(0)
createdAt DateTime @default(now())
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
creator User? @relation("PlaylistCreator", fields: [userId], references: [id], onDelete: SetNull)
videos Video[]
courses CoursePlaylist[] // Additional courses this playlist is assigned to
@@index([courseId])
}
model CoursePlaylist {
id String @id @default(cuid())
courseId String
playlistId String
createdAt DateTime @default(now())
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
playlist Playlist @relation(fields: [playlistId], references: [id], onDelete: Cascade)
@@unique([courseId, playlistId])
@@index([courseId])
@@index([playlistId])
}
model Video {
id String @id @default(cuid())
title String
playlistId String
userId String?
durationSec Int?
url String
thumbnail String?
index Int @default(0)
locked Boolean @default(false)
createdAt DateTime @default(now())
description String?
instantAccess Boolean @default(false)
transcodingStatus String @default("uploaded")
comments Comment[]
playlist Playlist @relation(fields: [playlistId], references: [id])
uploader User? @relation("VideoUploader", fields: [userId], references: [id], onDelete: SetNull)
likes VideoLike[]
progress VideoProgress[]
unlocks VideoUnlock[]
watchSegments VideoWatchSegment[]
videoCourses VideoCourse[]
@@unique([playlistId, index])
@@index([playlistId])
@@index([userId])
@@index([transcodingStatus])
}
model VideoCourse {
id String @id @default(cuid())
videoId String
courseId String
exclusive Boolean @default(true)
createdAt DateTime @default(now())
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
@@unique([videoId, courseId])
@@index([courseId])
@@index([videoId])
}
model VideoProgress {
id String @id @default(cuid())
userId String
videoId String
updatedAt DateTime @updatedAt
completed Boolean @default(false)
createdAt DateTime @default(now())
lastPos Int?
percent Int @default(0)
watchedSec Int @default(0)
durationSec Int?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
watchSegments VideoWatchSegment[]
@@unique([userId, videoId])
}
model VideoWatchSegment {
id String @id @default(cuid())
userId String
videoId String
startSec Int
endSec Int
watchedAt DateTime @default(now())
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
progress VideoProgress @relation(fields: [userId, videoId], references: [userId, videoId], onDelete: Cascade)
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
@@index([userId, videoId])
@@index([watchedAt])
@@index([userId])
@@index([videoId])
}
model VideoUnlock {
id String @id @default(cuid())
userId String
videoId String
unlockedAt DateTime @default(now())
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
@@unique([userId, videoId])
@@index([userId])
@@index([videoId])
@@index([userId, videoId])
}
model VideoLike {
id String @id @default(cuid())
userId String
videoId String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
@@unique([userId, videoId])
@@index([userId])
@@index([videoId])
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@index([userId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model Comment {
id String @id @default(cuid())
userId String
videoId String
content String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
video Video @relation(fields: [videoId], references: [id], onDelete: Cascade)
replies CommentReply[]
@@index([videoId])
@@index([userId])
}
model CommentReply {
id String @id @default(cuid())
userId String
commentId String
content String
createdAt DateTime @default(now())
comment Comment @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([commentId])
@@index([userId])
}
model AllowedStudent {
id String @id @default(cuid())
email String @unique
levels String // comma-separated course codes: "3D100,3D200,3D300"
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}