Base de Données
Schéma Prisma
Modèles Principaux
model User {
id String @id @default(cuid())
email String @unique
name String?
password String @default("")
image String?
emailVerified Boolean @default(false)
// Relations
ownedProjects Project[] @relation("owner")
projectMemberships ProjectMember[]
tickets Ticket[]
reviews Review[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Project {
id String @id @default(cuid())
name String
description String?
slug String @unique
customDomain String? @unique
// Owner
ownerId String
owner User @relation("owner", fields: [ownerId], references: [id], onDelete: Cascade)
// Relations
members ProjectMember[]
articles Article[]
reviews Review[]
festival Festival?
tickets Ticket[]
// Settings
isPublic Boolean @default(true)
status ProjectStatus @default(ACTIVE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([ownerId])
@@index([slug])
}
enum ProjectStatus {
ACTIVE
INACTIVE
ARCHIVED
}
model ProjectMember {
id String @id @default(cuid())
projectId String
userId String
role MemberRole @default(MEMBER)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
@@unique([projectId, userId])
@@index([projectId])
@@index([userId])
}
enum MemberRole {
OWNER
MEMBER
}
model Article {
id String @id @default(cuid())
projectId String
title String
slug String
content String @db.Text
excerpt String?
status ArticleStatus @default(DRAFT)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
publishedAt DateTime?
@@unique([projectId, slug])
@@index([projectId])
}
enum ArticleStatus {
DRAFT
PUBLISHED
ARCHIVED
}
model Review {
id String @id @default(cuid())
projectId String
authorId String
rating Int // 1-5
title String
content String @db.Text
isPublished Boolean @default(false)
status ReviewStatus @default(PENDING)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([projectId])
@@index([authorId])
}
enum ReviewStatus {
PENDING
APPROVED
REJECTED
}
model Festival {
id String @id @default(cuid())
projectId String @unique
name String
description String? @db.Text
location String?
startDate DateTime
endDate DateTime
isActive Boolean @default(true)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
periods FestivalPeriod[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([projectId])
}
model FestivalPeriod {
id String @id @default(cuid())
festivalId String
name String // "Week 1", "Phase A", etc.
description String?
startDate DateTime
endDate DateTime
festival Festival @relation(fields: [festivalId], references: [id], onDelete: Cascade)
artists FestivalArtist[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([festivalId])
}
model FestivalArtist {
id String @id @default(cuid())
periodId String
name String
description String?
imageUrl String?
period FestivalPeriod @relation(fields: [periodId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([periodId])
}
model Ticket {
id String @id @default(cuid())
projectId String? // Optionnel
title String
description String @db.Text
priority TicketPriority @default(MEDIUM)
status TicketStatus @default(OPEN)
authorId String
assignedToId String?
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
assignedTo User? @relation("TicketAssignee", fields: [assignedToId], references: [id])
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
messages TicketMessage[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
closedAt DateTime?
@@index([projectId])
@@index([authorId])
@@index([assignedToId])
}
enum TicketStatus {
OPEN
IN_PROGRESS
CLOSED
}
enum TicketPriority {
LOW
MEDIUM
HIGH
URGENT
}
model TicketMessage {
id String @id @default(cuid())
ticketId String
content String @db.Text
isPublic Boolean @default(true)
authorId String
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
author User @relation("TicketMessages", fields: [authorId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([ticketId])
@@index([authorId])
}
model StripeCustomer {
id String @id @default(cuid())
userId String @unique
stripeCustomerId String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model StripeSubscription {
id String @id @default(cuid())
projectId String
stripeSubscriptionId String @unique
status String
currentPeriodStart DateTime
currentPeriodEnd DateTime
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([projectId])
}Relations Principales
User (1) ──── (N) ProjectMember ──── (1) Project
│
├── (1) ──── (N) Article
│
├── (1) ──── (N) Review
│
├── (1) ──── (N) Ticket
│
└── (1) ──── (N) TicketMessage
Project (1) ──── (N) Article
Project (1) ──── (N) Review
Project (1) ──── (N) Ticket
Project (1) ──── (1) Festival (optionnel)
Project (1) ──── (N) StripeSubscriptionÉnumérations
ProjectStatus
ACTIVE: Projet actifINACTIVE: Projet inactifARCHIVED: Projet archivé
MemberRole
OWNER: Propriétaire (permissions complètes)MEMBER: Membre (permissions restreintes)
ArticleStatus
DRAFT: Brouillon (non-public)PUBLISHED: PubliéARCHIVED: Archivé
ReviewStatus
PENDING: En attente de modérationAPPROVED: ApprouvéREJECTED: Rejeté
TicketStatus
OPEN: NouveauIN_PROGRESS: En cours de traitementCLOSED: Fermé
TicketPriority
LOW: Basse prioritéMEDIUM: Priorité normaleHIGH: Haute prioritéURGENT: Très urgent
Migration
Pour appliquer ce schéma :
# Créer les migrations
pnpm prisma migrate dev --name init
# Mettre Ă jour Prisma Client
pnpm prisma generate
# Visualiser les données
pnpm prisma studioIndexation
Les index amélioren la performance des requêtes :
@@index([ownerId]) # RequĂŞtes sur les projets d'un user
@@index([projectId]) # RequĂŞtes sur les articles d'un projet
@@unique([email]) # Éviter les doublons de mailDiagramme ER
[User] ──one-to-many── [ProjectMember] ──many-to-one── [Project]
│
├─ one-to-many ── [Article]
├─ one-to-many ── [Review]
├─ one-to-many ── [Ticket]
└─ one-to-many ── [TicketMessage]
[Project]
├─ one-to-many ── [Article]
├─ one-to-many ── [Review]
├─ one-to-many ── [Ticket]
├─ one-to-one ── [Festival]
└─ one-to-many ── [StripeSubscription]
[Festival] ──one-to-many── [FestivalPeriod] ──one-to-many── [FestivalArtist]Voir Système d’authentification pour les tables better-auth.
Last updated on