File size: 3,647 Bytes
811126d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// 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-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id            Int           @id @default(autoincrement())
  name          String
  voiceId       String? // ID ElevenLabs pour la voix clonée
  voiceLanguage String?
  audioUrl      String? // URL de l'enregistrement original
  createdAt     DateTime      @default(now())
  updatedAt     DateTime      @updatedAt
  groups        GroupMember[]
  invitations   Invitation[]  @relation("InvitedUser")
  createdGroups Group[]       @relation("GroupCreator")
}

model Group {
  id          Int           @id @default(autoincrement())
  name        String
  inviteCode  String        @unique // Code d'invitation unique
  status      String        @default("WAITING") // WAITING, PLAYING, FINISHED
  createdAt   DateTime      @default(now())
  updatedAt   DateTime      @updatedAt
  creator     User          @relation("GroupCreator", fields: [creatorId], references: [id])
  creatorId   Int
  members     GroupMember[]
  invitations Invitation[]
  gameState   GameState?
}

model GroupMember {
  id       Int      @id @default(autoincrement())
  group    Group    @relation(fields: [groupId], references: [id])
  groupId  Int
  user     User     @relation(fields: [userId], references: [id])
  userId   Int
  joinedAt DateTime @default(now())
  isReady  Boolean  @default(false) // Indique si le joueur a soumis sa voix

  @@unique([groupId, userId])
}

model Invitation {
  id        Int              @id @default(autoincrement())
  group     Group            @relation(fields: [groupId], references: [id])
  groupId   Int
  user      User?            @relation("InvitedUser", fields: [userId], references: [id])
  userId    Int?
  email     String? // Pour inviter des utilisateurs non inscrits
  status    InvitationStatus @default(PENDING)
  createdAt DateTime         @default(now())
  expiresAt DateTime?
}

model GameState {
  id                  Int         @id @default(autoincrement())
  group               Group       @relation(fields: [groupId], references: [id])
  groupId             Int         @unique
  status              GameStatus  @default(WAITING)
  stolenVoicePlayerId Int? // ID du joueur dont la voix est volée
  currentRound        Int         @default(0)
  startedAt           DateTime?
  endedAt             DateTime?
  rounds              GameRound[]
}

model GameRound {
  id          Int       @id @default(autoincrement())
  gameState   GameState @relation(fields: [gameStateId], references: [id])
  gameStateId Int
  roundNumber Int
  speakerId   Int // ID du joueur qui parle
  guesses     Guess[]
  startedAt   DateTime  @default(now())
  endedAt     DateTime?
}

model Guess {
  id          Int       @id @default(autoincrement())
  gameRound   GameRound @relation(fields: [gameRoundId], references: [id])
  gameRoundId Int
  guesserId   Int // ID du joueur qui devine
  guessedId   Int // ID du joueur deviné
  isCorrect   Boolean
  createdAt   DateTime  @default(now())
}

enum InvitationStatus {
  PENDING
  ACCEPTED
  DECLINED
  EXPIRED
}

enum GameStatus {
  WAITING // En attente que tous les joueurs soumettent leur voix
  ANSWERS // Les joueurs répondent à la question
  DEBATE // Phase de débat
  VOTE // Phase de vote
  FINISHED // Partie terminée
  CANCELLED // Partie annulée
}