generator client { provider = "prisma-client-js" engineType = "client" output = "../lib/generated/prisma" } 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 phone String? @unique password String role Role @default(USER) createdAt DateTime @default(now()) team Team? sessions Session[] payments Payment[] quizSubmissions QuizSubmission[] goldenCards GoldenCard[] refreshTokens RefreshToken[] } model LoginOtp { id String @id @default(cuid()) phone String codeHash String attempts Int @default(0) expiresAt DateTime consumedAt DateTime? createdAt DateTime @default(now()) @@index([phone, createdAt]) } model FantasyNews { id String @id @default(cuid()) icon String title String description String @db.Text newsTime DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([newsTime]) } 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 RefreshToken { id String @id @default(cuid()) tokenHash String @unique userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) familyId String expiresAt DateTime revokedAt DateTime? replacedByTokenId String? createdAt DateTime @default(now()) @@index([userId]) @@index([familyId]) @@index([expiresAt]) } 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 }