369 lines
10 KiB
Plaintext
369 lines
10 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum Role {
|
|
USER
|
|
ADMIN
|
|
}
|
|
|
|
enum Position {
|
|
GK
|
|
DEF
|
|
MID
|
|
FWD
|
|
}
|
|
|
|
enum MatchStage {
|
|
GROUP
|
|
ROUND_OF_16
|
|
QUARTER_FINAL
|
|
SEMI_FINAL
|
|
THIRD_PLACE
|
|
FINAL
|
|
}
|
|
|
|
enum MatchStatus {
|
|
SCHEDULED
|
|
LIVE
|
|
FINISHED
|
|
}
|
|
|
|
enum TeamStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
ACTIVE
|
|
INACTIVE
|
|
}
|
|
|
|
enum PaymentStatus {
|
|
PENDING
|
|
SUCCESS
|
|
FAILED
|
|
}
|
|
|
|
enum CardTier {
|
|
BRONZE
|
|
SILVER
|
|
GOLD
|
|
}
|
|
|
|
enum EventType {
|
|
GOAL
|
|
ASSIST
|
|
YELLOW_CARD
|
|
RED_CARD
|
|
SECOND_YELLOW
|
|
SUBSTITUTION_IN
|
|
SUBSTITUTION_OUT
|
|
INJURY_NO_SUB
|
|
CLEAN_SHEET
|
|
PENALTY_SAVED
|
|
PENALTY_MISSED
|
|
OWN_GOAL
|
|
EXTRA_TIME_BONUS
|
|
MOTM
|
|
}
|
|
|
|
model Country {
|
|
id String @id @default(cuid())
|
|
name String @unique
|
|
code String @unique
|
|
flagUrl String?
|
|
flagImage String? // نام فایل پرچم مثل Flag_of_Australia.webp
|
|
confederation String? // کنفدراسیون (UEFA, AFC, CAF, ...)
|
|
qualificationMethod String? // شیوه راهیابی
|
|
qualificationDate String? // تاریخ راهیابی
|
|
participationHistory String? // سابقه شرکت
|
|
bestResult String? // بهترین نتیجه
|
|
description String? @db.Text // توضیحات کامل
|
|
defaultFormation String @default("4-3-3")
|
|
defaultLineupPlayerIds String[] @default([])
|
|
defaultCaptainId String? // شناسه کاپیتان پیشفرض
|
|
group Group? @relation(fields: [groupId], references: [id])
|
|
groupId String?
|
|
isEliminated Boolean @default(false)
|
|
players Player[]
|
|
homeMatches Match[] @relation("HomeTeam")
|
|
awayMatches Match[] @relation("AwayTeam")
|
|
}
|
|
|
|
model Group {
|
|
id String @id @default(cuid())
|
|
name String @unique
|
|
countries Country[]
|
|
}
|
|
|
|
model Player {
|
|
id String @id @default(cuid())
|
|
name String
|
|
image String? // نام فایل تصویر در public/uploads/players/
|
|
position Position
|
|
countryId String
|
|
country Country @relation(fields: [countryId], references: [id])
|
|
price Float @default(5.0)
|
|
totalPoints Int @default(0)
|
|
isActive Boolean @default(true)
|
|
isGoldenCardEligible Boolean @default(false)
|
|
cardTier CardTier @default(BRONZE)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
matchStats PlayerMatchStat[]
|
|
teamPlayers TeamPlayer[]
|
|
events MatchEvent[]
|
|
goldenCards GoldenCard[]
|
|
}
|
|
|
|
model Match {
|
|
id String @id @default(cuid())
|
|
homeTeamId String
|
|
awayTeamId String
|
|
homeTeam Country @relation("HomeTeam", fields: [homeTeamId], references: [id])
|
|
awayTeam Country @relation("AwayTeam", fields: [awayTeamId], references: [id])
|
|
homeScore Int?
|
|
awayScore Int?
|
|
stage MatchStage @default(GROUP)
|
|
status MatchStatus @default(SCHEDULED)
|
|
matchDate DateTime
|
|
matchDatePersian String? // تاریخ شمسی
|
|
stadium String? // نام ورزشگاه
|
|
city String? // شهر
|
|
referee String? // داور اصلی
|
|
assistant1 String? // کمک داور 1
|
|
assistant2 String? // کمک داور 2
|
|
fourthOfficial String? // داور چهارم
|
|
attendance Int? // تعداد تماشاگر
|
|
weather String? // وضعیت آب و هوا
|
|
description String? @db.Text // توضیحات بازی
|
|
roundId String?
|
|
round Round? @relation(fields: [roundId], references: [id])
|
|
playerStats PlayerMatchStat[]
|
|
events MatchEvent[]
|
|
lineups MatchLineup[]
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Round {
|
|
id String @id @default(cuid())
|
|
number Int @unique
|
|
name String
|
|
isActive Boolean @default(false)
|
|
deadline DateTime
|
|
matches Match[]
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Gameweek {
|
|
id String @id @default(cuid())
|
|
number Int @unique
|
|
name String
|
|
isActive Boolean @default(false)
|
|
deadline DateTime
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model MatchEvent {
|
|
id String @id @default(cuid())
|
|
matchId String
|
|
playerId String
|
|
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
|
player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
|
|
type EventType
|
|
minute Int?
|
|
extraInfo String?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model MatchLineup {
|
|
id String @id @default(cuid())
|
|
matchId String
|
|
countryId String
|
|
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
|
formation String
|
|
playerIds String[]
|
|
}
|
|
|
|
model PlayerMatchStat {
|
|
id String @id @default(cuid())
|
|
playerId String
|
|
matchId String
|
|
player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
|
|
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
|
goals Int @default(0)
|
|
assists Int @default(0)
|
|
yellowCards Int @default(0)
|
|
redCards Int @default(0)
|
|
minutesPlayed Int @default(0)
|
|
cleanSheet Boolean @default(false)
|
|
penaltySaved Int @default(0)
|
|
penaltyMissed Int @default(0)
|
|
ownGoals Int @default(0)
|
|
isMotm Boolean @default(false)
|
|
extraTimeBonus Int @default(0)
|
|
points Int @default(0)
|
|
|
|
@@unique([playerId, matchId])
|
|
}
|
|
|
|
model ScoringRule {
|
|
id String @id @default(cuid())
|
|
position Position
|
|
eventType EventType
|
|
points Int
|
|
updatedAt DateTime @updatedAt
|
|
updatedBy String?
|
|
|
|
@@unique([position, eventType])
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
name String?
|
|
email String @unique
|
|
password String
|
|
role Role @default(USER)
|
|
createdAt DateTime @default(now())
|
|
team Team?
|
|
sessions Session[]
|
|
payments Payment[]
|
|
quizSubmissions QuizSubmission[]
|
|
goldenCards GoldenCard[]
|
|
}
|
|
|
|
enum GoldenCardStatus {
|
|
SEALED
|
|
OPENED
|
|
}
|
|
|
|
enum SpecialCardState {
|
|
IN_INVENTORY
|
|
IN_TEAM
|
|
SOLD
|
|
}
|
|
|
|
model DailyQuiz {
|
|
id String @id @default(cuid())
|
|
date DateTime @db.Date
|
|
windowStart DateTime
|
|
windowEnd DateTime
|
|
goldWinnersCount Int @default(1)
|
|
silverWinnersCount Int @default(0)
|
|
bronzeWinnersCount Int @default(0)
|
|
goldMinCorrect Int?
|
|
silverMinCorrect Int?
|
|
bronzeMinCorrect Int?
|
|
isProcessed Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
questions QuizQuestion[]
|
|
submissions QuizSubmission[]
|
|
awardedCards GoldenCard[]
|
|
|
|
@@unique([date])
|
|
}
|
|
|
|
model QuizQuestion {
|
|
id String @id @default(cuid())
|
|
quizId String
|
|
quiz DailyQuiz @relation(fields: [quizId], references: [id], onDelete: Cascade)
|
|
questionText String
|
|
options String[]
|
|
correctAnswer Int // index of correct option (0-based)
|
|
order Int @default(0)
|
|
}
|
|
|
|
model QuizSubmission {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
quizId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
quiz DailyQuiz @relation(fields: [quizId], references: [id], onDelete: Cascade)
|
|
answers Int[] // user's selected option indexes
|
|
correctAnswers Int @default(0)
|
|
score Int @default(0) // percentage 0-100
|
|
submittedAt DateTime @default(now())
|
|
|
|
@@unique([userId, quizId])
|
|
}
|
|
|
|
model GoldenCard {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
quizId String?
|
|
playerId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
quiz DailyQuiz? @relation(fields: [quizId], references: [id], onDelete: SetNull)
|
|
player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
|
|
cardTier CardTier @default(GOLD)
|
|
status GoldenCardStatus @default(SEALED)
|
|
state SpecialCardState @default(IN_INVENTORY)
|
|
acquiredDate DateTime @default(now())
|
|
openedAt DateTime?
|
|
teamPlayer TeamPlayer?
|
|
}
|
|
|
|
model Session {
|
|
id String @id @default(cuid())
|
|
sessionToken String @unique
|
|
userId String
|
|
expires DateTime
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model Team {
|
|
id String @id @default(cuid())
|
|
name String
|
|
userId String @unique
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
budget Float @default(100.0)
|
|
totalPoints Int @default(0)
|
|
formation String @default("4-3-3")
|
|
status TeamStatus @default(INACTIVE)
|
|
createdAt DateTime @default(now())
|
|
players TeamPlayer[]
|
|
}
|
|
|
|
model TeamPlayer {
|
|
teamId String
|
|
playerId String
|
|
goldenCardId String? @unique
|
|
isCaptain Boolean @default(false)
|
|
isViceCaptain Boolean @default(false)
|
|
isBench Boolean @default(false)
|
|
positionIndex Int @default(0)
|
|
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
|
player Player @relation(fields: [playerId], references: [id], onDelete: Cascade)
|
|
goldenCard GoldenCard? @relation(fields: [goldenCardId], references: [id], onDelete: SetNull)
|
|
|
|
@@id([teamId, playerId])
|
|
}
|
|
|
|
model Package {
|
|
id String @id @default(cuid())
|
|
name String
|
|
budgetBonus Float
|
|
price Int
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
payments Payment[]
|
|
}
|
|
|
|
model Payment {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
packageId String
|
|
user User @relation(fields: [userId], references: [id])
|
|
package Package @relation(fields: [packageId], references: [id])
|
|
amount Int
|
|
authority String? @unique
|
|
refId String?
|
|
status PaymentStatus @default(PENDING)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|