feat: add recalculateAllElo function for idempotent ELO recalculation
This commit is contained in:
+49
-61
@@ -1,67 +1,55 @@
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// Note: For PostgreSQL, create a separate schema file or use environment variable
|
||||
// See scripts/switch-database.js for provider switching logic
|
||||
|
||||
model Player {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
rating Int @default(0) // Historical rating (used for rankings)
|
||||
currentElo Int @default(1000) // Current Elo rating
|
||||
gamesPlayed Int @default(0) // Total games played
|
||||
wins Int @default(0) // Total wins
|
||||
losses Int @default(0) // Total losses
|
||||
rating Int @default(0)
|
||||
currentElo Int @default(1000)
|
||||
gamesPlayed Int @default(0)
|
||||
wins Int @default(0)
|
||||
losses Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
normalizedName String @unique
|
||||
eloSnapshots EloSnapshot[]
|
||||
eventParticipants EventParticipant[]
|
||||
matchesAsP4 Match[] @relation("MatchPlayer4")
|
||||
matchesAsP3 Match[] @relation("MatchPlayer3")
|
||||
matchesAsP2 Match[] @relation("MatchPlayer2")
|
||||
matchesAsP1 Match[] @relation("MatchPlayer1")
|
||||
partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2")
|
||||
matchesAsP2 Match[] @relation("MatchPlayer2")
|
||||
matchesAsP3 Match[] @relation("MatchPlayer3")
|
||||
matchesAsP4 Match[] @relation("MatchPlayer4")
|
||||
partnershipGames PartnershipGame[] @relation("PartnershipPlayer1")
|
||||
partnershipStats2 PartnershipStat[] @relation("StatPlayer2")
|
||||
partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2")
|
||||
partnershipStats PartnershipStat[] @relation("StatPlayer1")
|
||||
teamsAsPlayer2 Team[] @relation("TeamPlayer2")
|
||||
partnershipStats2 PartnershipStat[] @relation("StatPlayer2")
|
||||
teamsAsPlayer1 Team[] @relation("TeamPlayer1")
|
||||
teamsAsPlayer2 Team[] @relation("TeamPlayer2")
|
||||
user User?
|
||||
|
||||
@@map("players")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
emailVerified Boolean @default(false)
|
||||
name String?
|
||||
image String?
|
||||
role String @default("player") // player, tournament_admin, club_admin
|
||||
|
||||
// Session and account references for Better Auth
|
||||
sessions Session[]
|
||||
accounts Account[]
|
||||
|
||||
// Link to EuchreCamp player (optional)
|
||||
playerId Int? @unique
|
||||
player Player? @relation(fields: [playerId], references: [id])
|
||||
|
||||
// Tournaments owned by this user
|
||||
ownedTournaments Event[] @relation("TournamentOwner")
|
||||
|
||||
// Matches created by this user
|
||||
createdMatches Match[] @relation("MatchCreator")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
emailVerified Boolean @default(false)
|
||||
name String?
|
||||
image String?
|
||||
role String @default("player")
|
||||
playerId Int? @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
accounts Account[]
|
||||
ownedTournaments Event[] @relation("TournamentOwner")
|
||||
createdMatches Match[] @relation("MatchCreator")
|
||||
sessions Session[]
|
||||
player Player? @relation(fields: [playerId], references: [id])
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -76,15 +64,15 @@ model Event {
|
||||
format String @default("round_robin")
|
||||
status String @default("planned")
|
||||
maxParticipants Int?
|
||||
ownerId String? // User ID of the tournament owner (for tournament_admin)
|
||||
ownerId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
bracketMatchups BracketMatchup[]
|
||||
participants EventParticipant[]
|
||||
owner User? @relation("TournamentOwner", fields: [ownerId], references: [id])
|
||||
matches Match[]
|
||||
teams Team[]
|
||||
rounds TournamentRound[]
|
||||
owner User? @relation("TournamentOwner", fields: [ownerId], references: [id])
|
||||
|
||||
@@map("events")
|
||||
}
|
||||
@@ -99,9 +87,9 @@ model EventParticipant {
|
||||
registrationDate DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
event Event @relation(fields: [eventId], references: [id])
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
|
||||
@@unique([eventId, playerId])
|
||||
@@map("event_participants")
|
||||
@@ -115,12 +103,12 @@ model Team {
|
||||
player2Id Int
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
bracketMatchups2 BracketMatchup[] @relation("BracketTeam2")
|
||||
bracketMatchups1 BracketMatchup[] @relation("BracketTeam1")
|
||||
bracketMatchups2 BracketMatchup[] @relation("BracketTeam2")
|
||||
eventParticipants EventParticipant[]
|
||||
player2 Player @relation("TeamPlayer2", fields: [player2Id], references: [id])
|
||||
player1 Player @relation("TeamPlayer1", fields: [player1Id], references: [id])
|
||||
event Event @relation(fields: [eventId], references: [id])
|
||||
player1 Player @relation("TeamPlayer1", fields: [player1Id], references: [id])
|
||||
player2 Player @relation("TeamPlayer2", fields: [player2Id], references: [id])
|
||||
|
||||
@@map("teams")
|
||||
}
|
||||
@@ -155,11 +143,11 @@ model BracketMatchup {
|
||||
status String @default("pending")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
match Match? @relation(fields: [matchId], references: [id])
|
||||
team2 Team? @relation("BracketTeam2", fields: [team2Id], references: [id])
|
||||
team1 Team? @relation("BracketTeam1", fields: [team1Id], references: [id])
|
||||
event Event @relation(fields: [eventId], references: [id])
|
||||
match Match? @relation(fields: [matchId], references: [id])
|
||||
round TournamentRound @relation(fields: [roundId], references: [id])
|
||||
team1 Team? @relation("BracketTeam1", fields: [team1Id], references: [id])
|
||||
team2 Team? @relation("BracketTeam2", fields: [team2Id], references: [id])
|
||||
|
||||
@@map("bracket_matchups")
|
||||
}
|
||||
@@ -175,18 +163,18 @@ model Match {
|
||||
team1Score Int
|
||||
team2Score Int
|
||||
status String @default("completed")
|
||||
createdById String? // User ID of the match creator (for tournament_admin)
|
||||
createdById String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
bracketMatchups BracketMatchup[]
|
||||
eloSnapshots EloSnapshot[]
|
||||
team2P2 Player @relation("MatchPlayer4", fields: [team2P2Id], references: [id])
|
||||
team2P1 Player @relation("MatchPlayer3", fields: [team2P1Id], references: [id])
|
||||
team1P2 Player @relation("MatchPlayer2", fields: [team1P2Id], references: [id])
|
||||
team1P1 Player @relation("MatchPlayer1", fields: [team1P1Id], references: [id])
|
||||
event Event? @relation(fields: [eventId], references: [id])
|
||||
partnershipGames PartnershipGame[]
|
||||
createdBy User? @relation("MatchCreator", fields: [createdById], references: [id])
|
||||
event Event? @relation(fields: [eventId], references: [id])
|
||||
team1P1 Player @relation("MatchPlayer1", fields: [team1P1Id], references: [id])
|
||||
team1P2 Player @relation("MatchPlayer2", fields: [team1P2Id], references: [id])
|
||||
team2P1 Player @relation("MatchPlayer3", fields: [team2P1Id], references: [id])
|
||||
team2P2 Player @relation("MatchPlayer4", fields: [team2P2Id], references: [id])
|
||||
partnershipGames PartnershipGame[]
|
||||
|
||||
@@map("matches")
|
||||
}
|
||||
@@ -216,8 +204,8 @@ model PartnershipGame {
|
||||
player2EloChange Int?
|
||||
createdAt DateTime @default(now())
|
||||
match Match @relation(fields: [matchId], references: [id])
|
||||
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
|
||||
player1 Player @relation("PartnershipPlayer1", fields: [player1Id], references: [id])
|
||||
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
|
||||
|
||||
@@map("partnership_games")
|
||||
}
|
||||
@@ -233,16 +221,17 @@ model PartnershipStat {
|
||||
lastPlayed DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
player2 Player @relation("StatPlayer2", fields: [player2Id], references: [id])
|
||||
player1 Player @relation("StatPlayer1", fields: [player1Id], references: [id])
|
||||
player2 Player @relation("StatPlayer2", fields: [player2Id], references: [id])
|
||||
|
||||
@@unique([player1Id, player2Id], name: "partnership_stats_player1Id_player2Id_key")
|
||||
@@map("partnership_stats")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id
|
||||
expiresAt DateTime
|
||||
token String
|
||||
token String @unique
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
ipAddress String?
|
||||
@@ -250,7 +239,6 @@ model Session {
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([token])
|
||||
@@index([userId])
|
||||
@@map("session")
|
||||
}
|
||||
@@ -260,7 +248,6 @@ model Account {
|
||||
accountId String
|
||||
providerId String
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
accessToken String?
|
||||
refreshToken String?
|
||||
idToken String?
|
||||
@@ -270,6 +257,7 @@ model Account {
|
||||
password String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId])
|
||||
@@map("account")
|
||||
|
||||
Reference in New Issue
Block a user