generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum Role { ADMIN MEMBER } enum MediaType { PHOTO VIDEO } enum MediaVisibility { PUBLIC MEMBERS_ONLY MUAY_THAI_ONLY YOGA_ONLY } enum CertificateStatus { PENDING VALIDATED REJECTED } model User { id String @id @default(cuid()) email String @unique name String password String role Role @default(MEMBER) avatar String? phone String? isMuayThai Boolean @default(false) isYoga Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt muayThai MuayThaiProfile? yoga YogaProfile? media Media[] messagesRead MessageRead[] certificates Certificate[] absences Absence[] homework Homework[] } model MuayThaiProfile { id String @id @default(cuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) jumpRopeBestTime Int? // en secondes burpee100BestTime Int? // en secondes createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sessions TrainingSession[] } model TrainingSession { id String @id @default(cuid()) profileId String profile MuayThaiProfile @relation(fields: [profileId], references: [id], onDelete: Cascade) date DateTime @default(now()) jumpRopeTime Int? // en secondes burpee100Time Int? // en secondes notes String? } model YogaProfile { id String @id @default(cuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) sessionsRemaining Int @default(1) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt attendances YogaAttendance[] } model YogaAttendance { id String @id @default(cuid()) profileId String profile YogaProfile @relation(fields: [profileId], references: [id], onDelete: Cascade) date DateTime @default(now()) pricePaid Float? notes String? } model YogaTier { id String @id @default(cuid()) name String // ex: "Séance unique", "Pack 5", "Pack 10" numberOfSessions Int priceTotal Float isActive Boolean @default(true) } model Media { id String @id @default(cuid()) title String description String? type MediaType @default(PHOTO) url String thumbnail String? visibility MediaVisibility @default(MEMBERS_ONLY) uploadedById String? uploadedBy User? @relation(fields: [uploadedById], references: [id], onDelete: SetNull) createdAt DateTime @default(now()) } model Message { id String @id @default(cuid()) title String content String category String? // muay-thai | yoga | general createdAt DateTime @default(now()) readBy MessageRead[] } model MessageRead { id String @id @default(cuid()) messageId String message Message @relation(fields: [messageId], references: [id], onDelete: Cascade) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) readAt DateTime @default(now()) @@unique([messageId, userId]) } model Homework { id String @id @default(cuid()) title String description String videoUrl String? createdAt DateTime @default(now()) userId String? user User? @relation(fields: [userId], references: [id], onDelete: SetNull) } model Certificate { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) fileUrl String status CertificateStatus @default(PENDING) createdAt DateTime @default(now()) reviewedAt DateTime? } model Absence { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) date DateTime reason String? } model ClassSlot { id String @id @default(cuid()) slug String @unique label String sport String time String capacity Int @default(20) booked Int @default(0) isFull Boolean @default(false) updatedAt DateTime @updatedAt }