200 lines
5.6 KiB
Text
200 lines
5.6 KiB
Text
// This is your Prisma schema file,
|
||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||
|
||
generator client {
|
||
provider = "prisma-client-js"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
}
|
||
|
||
model User {
|
||
id String @id @default(uuid())
|
||
email String? @unique
|
||
name String?
|
||
password String? // For optional email/password admin auth
|
||
role UserRole @default(USER)
|
||
telegramId String? @unique
|
||
createdAt DateTime @default(now())
|
||
|
||
// Связи
|
||
hostedRooms Room[] @relation("HostedRooms")
|
||
participants Participant[]
|
||
questionPacks QuestionPack[]
|
||
themes Theme[]
|
||
|
||
// Статистика
|
||
gamesPlayed Int @default(0)
|
||
gamesWon Int @default(0)
|
||
totalPoints Int @default(0)
|
||
}
|
||
|
||
model Room {
|
||
id String @id @default(uuid())
|
||
code String @unique // 6-символьный код
|
||
status RoomStatus @default(WAITING)
|
||
hostId String
|
||
createdAt DateTime @default(now())
|
||
expiresAt DateTime?
|
||
|
||
// Настройки
|
||
maxPlayers Int @default(10)
|
||
allowSpectators Boolean @default(true)
|
||
timerEnabled Boolean @default(false)
|
||
timerDuration Int @default(30)
|
||
questionPackId String?
|
||
autoAdvance Boolean @default(false)
|
||
voiceMode Boolean @default(false) // Голосовой режим
|
||
|
||
// Админские комнаты
|
||
isAdminRoom Boolean @default(false)
|
||
customCode String? // Кастомный код вместо random
|
||
activeFrom DateTime? // Комната доступна с этого времени
|
||
activeTo DateTime? // Комната доступна до этого времени
|
||
themeId String? // FK на Theme
|
||
uiControls Json? // { allowThemeChange, allowPackChange, allowNameChange, allowScoreEdit }
|
||
|
||
// Состояние игры
|
||
currentQuestionIndex Int @default(0)
|
||
currentQuestionId String? // UUID текущего вопроса
|
||
revealedAnswers Json @default("{}") // {"questionUuid": ["answerUuid1", "answerUuid2"]}
|
||
currentPlayerId String?
|
||
isGameOver Boolean @default(false)
|
||
|
||
// Метрики
|
||
totalQuestions Int @default(0)
|
||
answeredQuestions Int @default(0)
|
||
startedAt DateTime?
|
||
finishedAt DateTime?
|
||
|
||
// Связи
|
||
host User @relation("HostedRooms", fields: [hostId], references: [id])
|
||
participants Participant[]
|
||
questionPack QuestionPack? @relation(fields: [questionPackId], references: [id])
|
||
roomPack RoomPack?
|
||
gameHistory GameHistory?
|
||
theme Theme? @relation(fields: [themeId], references: [id])
|
||
}
|
||
|
||
enum RoomStatus {
|
||
WAITING
|
||
PLAYING
|
||
FINISHED
|
||
}
|
||
|
||
model Participant {
|
||
id String @id @default(uuid())
|
||
userId String
|
||
roomId String
|
||
name String
|
||
role ParticipantRole
|
||
score Int @default(0)
|
||
joinedAt DateTime @default(now())
|
||
isActive Boolean @default(true)
|
||
|
||
user User @relation(fields: [userId], references: [id])
|
||
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([userId, roomId])
|
||
}
|
||
|
||
enum ParticipantRole {
|
||
HOST
|
||
PLAYER
|
||
SPECTATOR
|
||
}
|
||
|
||
enum UserRole {
|
||
USER
|
||
ADMIN
|
||
}
|
||
|
||
model QuestionPack {
|
||
id String @id @default(uuid())
|
||
name String
|
||
description String
|
||
category String
|
||
isPublic Boolean @default(false)
|
||
createdBy String
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
questions Json // Массив вопросов с ответами
|
||
questionCount Int @default(0)
|
||
timesUsed Int @default(0)
|
||
rating Float @default(0)
|
||
|
||
creator User @relation(fields: [createdBy], references: [id])
|
||
rooms Room[]
|
||
roomPacks RoomPack[] @relation("RoomPackSource")
|
||
}
|
||
|
||
model RoomPack {
|
||
id String @id @default(uuid())
|
||
roomId String @unique
|
||
name String
|
||
description String @default("")
|
||
sourcePackId String?
|
||
questions Json @default("[]")
|
||
questionCount Int @default(0)
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||
sourcePack QuestionPack? @relation("RoomPackSource", fields: [sourcePackId], references: [id])
|
||
|
||
@@index([roomId])
|
||
@@index([sourcePackId])
|
||
}
|
||
|
||
model GameHistory {
|
||
id String @id @default(uuid())
|
||
roomId String @unique
|
||
roomCode String
|
||
questionPackId String
|
||
startedAt DateTime
|
||
finishedAt DateTime
|
||
|
||
players Json // { userId: { name, score, rank } }
|
||
statistics Json // Детальная статистика игры
|
||
timeline Json // История событий игры
|
||
|
||
room Room @relation(fields: [roomId], references: [id], onDelete: Cascade)
|
||
}
|
||
|
||
model AdminAuthCode {
|
||
id String @id @default(uuid())
|
||
code String @unique
|
||
telegramId String?
|
||
status CodeStatus @default(PENDING)
|
||
createdAt DateTime @default(now())
|
||
expiresAt DateTime
|
||
usedAt DateTime?
|
||
|
||
@@index([code])
|
||
@@index([telegramId])
|
||
}
|
||
|
||
enum CodeStatus {
|
||
PENDING
|
||
CLAIMED
|
||
USED
|
||
EXPIRED
|
||
}
|
||
|
||
model Theme {
|
||
id String @id @default(uuid())
|
||
name String
|
||
isPublic Boolean @default(false)
|
||
createdBy String
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
colors Json // { bgPrimary, bgOverlay, bgCard, textPrimary, textSecondary, accentPrimary, etc. }
|
||
settings Json // { shadowSm, shadowMd, blurAmount, borderRadius, animationSpeed, etc. }
|
||
|
||
creator User @relation(fields: [createdBy], references: [id])
|
||
rooms Room[]
|
||
}
|