nextjs-rewrite #5

Merged
david merged 56 commits from nextjs-rewrite into main 2026-03-30 02:30:16 +00:00
4 changed files with 503 additions and 173 deletions
Showing only changes of commit 8f1f2bf196 - Show all commits
@@ -0,0 +1,232 @@
-- CreateTable
CREATE TABLE "players" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"rating" INTEGER NOT NULL DEFAULT 0,
"currentElo" INTEGER NOT NULL DEFAULT 1000,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "users" (
"id" TEXT NOT NULL PRIMARY KEY,
"email" TEXT NOT NULL,
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
"name" TEXT,
"image" TEXT,
"role" TEXT NOT NULL DEFAULT 'player',
"playerId" INTEGER,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "users_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "players" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "events" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"event_id" INTEGER,
"name" TEXT NOT NULL,
"description" TEXT,
"eventDate" DATETIME,
"eventType" TEXT NOT NULL DEFAULT 'tournament',
"format" TEXT NOT NULL DEFAULT 'round_robin',
"status" TEXT NOT NULL DEFAULT 'planned',
"maxParticipants" INTEGER,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "event_participants" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"eventId" INTEGER NOT NULL,
"playerId" INTEGER NOT NULL,
"teamId" INTEGER,
"seed" INTEGER,
"status" TEXT NOT NULL DEFAULT 'registered',
"registrationDate" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "event_participants_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "teams" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "event_participants_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "event_participants_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "teams" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"eventId" INTEGER NOT NULL,
"teamName" TEXT,
"player1Id" INTEGER NOT NULL,
"player2Id" INTEGER NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "teams_player2Id_fkey" FOREIGN KEY ("player2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "teams_player1Id_fkey" FOREIGN KEY ("player1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "teams_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "tournament_rounds" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"eventId" INTEGER NOT NULL,
"roundNumber" INTEGER NOT NULL,
"status" TEXT NOT NULL DEFAULT 'pending',
"scheduledStart" DATETIME,
"actualStart" DATETIME,
"completedAt" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "tournament_rounds_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "bracket_matchups" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"roundId" INTEGER NOT NULL,
"eventId" INTEGER NOT NULL,
"team1Id" INTEGER,
"team2Id" INTEGER,
"matchId" INTEGER,
"tableNumber" INTEGER,
"bracketPosition" INTEGER,
"winnerTeamId" INTEGER,
"loserTeamId" INTEGER,
"status" TEXT NOT NULL DEFAULT 'pending',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "bracket_matchups_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "matches" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "bracket_matchups_team2Id_fkey" FOREIGN KEY ("team2Id") REFERENCES "teams" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "bracket_matchups_team1Id_fkey" FOREIGN KEY ("team1Id") REFERENCES "teams" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "bracket_matchups_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "bracket_matchups_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "tournament_rounds" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "matches" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"eventId" INTEGER,
"playedAt" DATETIME,
"team1P1Id" INTEGER NOT NULL,
"team1P2Id" INTEGER NOT NULL,
"team2P1Id" INTEGER NOT NULL,
"team2P2Id" INTEGER NOT NULL,
"team1Score" INTEGER NOT NULL,
"team2Score" INTEGER NOT NULL,
"status" TEXT NOT NULL DEFAULT 'completed',
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "matches_team2P2Id_fkey" FOREIGN KEY ("team2P2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team2P1Id_fkey" FOREIGN KEY ("team2P1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team1P2Id_fkey" FOREIGN KEY ("team1P2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team1P1Id_fkey" FOREIGN KEY ("team1P1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "elo_snapshots" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"playerId" INTEGER NOT NULL,
"matchId" INTEGER NOT NULL,
"ratingBefore" INTEGER NOT NULL,
"ratingAfter" INTEGER NOT NULL,
"ratingChange" INTEGER NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "elo_snapshots_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "matches" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "elo_snapshots_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "partnership_games" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"player1Id" INTEGER NOT NULL,
"player2Id" INTEGER NOT NULL,
"matchId" INTEGER NOT NULL,
"teamNumber" INTEGER,
"wonMatch" INTEGER,
"player1EloChange" INTEGER,
"player2EloChange" INTEGER,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "partnership_games_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "matches" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "partnership_games_player2Id_fkey" FOREIGN KEY ("player2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "partnership_games_player1Id_fkey" FOREIGN KEY ("player1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "partnership_stats" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"player1Id" INTEGER NOT NULL,
"player2Id" INTEGER NOT NULL,
"gamesPlayed" INTEGER NOT NULL DEFAULT 0,
"wins" INTEGER NOT NULL DEFAULT 0,
"losses" INTEGER NOT NULL DEFAULT 0,
"totalEloChange" INTEGER NOT NULL DEFAULT 0,
"lastPlayed" DATETIME,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "partnership_stats_player2Id_fkey" FOREIGN KEY ("player2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "partnership_stats_player1Id_fkey" FOREIGN KEY ("player1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "session" (
"id" TEXT NOT NULL PRIMARY KEY,
"expiresAt" DATETIME NOT NULL,
"token" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"ipAddress" TEXT,
"userAgent" TEXT,
"userId" TEXT NOT NULL,
CONSTRAINT "session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "account" (
"id" TEXT NOT NULL PRIMARY KEY,
"accountId" TEXT NOT NULL,
"providerId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"accessToken" TEXT,
"refreshToken" TEXT,
"idToken" TEXT,
"accessTokenExpiresAt" DATETIME,
"refreshTokenExpiresAt" DATETIME,
"scope" TEXT,
"password" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "verification" (
"id" TEXT NOT NULL PRIMARY KEY,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresAt" DATETIME NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "players_name_key" ON "players"("name");
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
-- CreateIndex
CREATE UNIQUE INDEX "users_playerId_key" ON "users"("playerId");
-- CreateIndex
CREATE INDEX "session_userId_idx" ON "session"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
-- CreateIndex
CREATE INDEX "account_userId_idx" ON "account"("userId");
-- CreateIndex
CREATE INDEX "verification_identifier_idx" ON "verification"("identifier");
@@ -0,0 +1,61 @@
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_events" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"event_id" INTEGER,
"name" TEXT NOT NULL,
"description" TEXT,
"eventDate" DATETIME,
"eventType" TEXT NOT NULL DEFAULT 'tournament',
"format" TEXT NOT NULL DEFAULT 'round_robin',
"status" TEXT NOT NULL DEFAULT 'planned',
"maxParticipants" INTEGER,
"ownerId" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "events_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_events" ("createdAt", "description", "eventDate", "eventType", "event_id", "format", "id", "maxParticipants", "name", "status", "updatedAt") SELECT "createdAt", "description", "eventDate", "eventType", "event_id", "format", "id", "maxParticipants", "name", "status", "updatedAt" FROM "events";
DROP TABLE "events";
ALTER TABLE "new_events" RENAME TO "events";
CREATE TABLE "new_matches" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"eventId" INTEGER,
"playedAt" DATETIME,
"team1P1Id" INTEGER NOT NULL,
"team1P2Id" INTEGER NOT NULL,
"team2P1Id" INTEGER NOT NULL,
"team2P2Id" INTEGER NOT NULL,
"team1Score" INTEGER NOT NULL,
"team2Score" INTEGER NOT NULL,
"status" TEXT NOT NULL DEFAULT 'completed',
"createdById" TEXT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
CONSTRAINT "matches_team2P2Id_fkey" FOREIGN KEY ("team2P2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team2P1Id_fkey" FOREIGN KEY ("team2P1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team1P2Id_fkey" FOREIGN KEY ("team1P2Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_team1P1Id_fkey" FOREIGN KEY ("team1P1Id") REFERENCES "players" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT "matches_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "events" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT "matches_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
INSERT INTO "new_matches" ("createdAt", "eventId", "id", "playedAt", "status", "team1P1Id", "team1P2Id", "team1Score", "team2P1Id", "team2P2Id", "team2Score", "updatedAt") SELECT "createdAt", "eventId", "id", "playedAt", "status", "team1P1Id", "team1P2Id", "team1Score", "team2P1Id", "team2P2Id", "team2Score", "updatedAt" FROM "matches";
DROP TABLE "matches";
ALTER TABLE "new_matches" RENAME TO "matches";
CREATE TABLE "new_players" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT NOT NULL,
"rating" INTEGER NOT NULL DEFAULT 0,
"currentElo" INTEGER NOT NULL DEFAULT 1000,
"gamesPlayed" INTEGER NOT NULL DEFAULT 0,
"wins" INTEGER NOT NULL DEFAULT 0,
"losses" INTEGER NOT NULL DEFAULT 0,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
INSERT INTO "new_players" ("createdAt", "currentElo", "id", "name", "rating", "updatedAt") SELECT "createdAt", "currentElo", "id", "name", "rating", "updatedAt" FROM "players";
DROP TABLE "players";
ALTER TABLE "new_players" RENAME TO "players";
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;
+3
View File
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"
+113 -79
View File
@@ -1,5 +1,3 @@
// EuchreCamp Database Schema
// Generated from existing Ruby/ROM implementation
generator client { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
@@ -10,58 +8,61 @@ datasource db {
url = env("DATABASE_URL") url = env("DATABASE_URL")
} }
// Player Model - Tracks individual player information
model Player { model Player {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
name String @unique name String
rating Int @default(0) rating Int @default(0) // Historical rating (used for rankings)
currentElo Int @default(1000) 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
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
// Relationships
users User[]
eventParticipants EventParticipant[]
teamsAsPlayer1 Team[] @relation("TeamPlayer1")
teamsAsPlayer2 Team[] @relation("TeamPlayer2")
matchesAsP1 Match[] @relation("MatchPlayer1")
matchesAsP2 Match[] @relation("MatchPlayer2")
matchesAsP3 Match[] @relation("MatchPlayer3")
matchesAsP4 Match[] @relation("MatchPlayer4")
eloSnapshots EloSnapshot[] eloSnapshots EloSnapshot[]
partnershipGames PartnershipGame[] @relation("PartnershipPlayer1") eventParticipants EventParticipant[]
matchesAsP4 Match[] @relation("MatchPlayer4")
matchesAsP3 Match[] @relation("MatchPlayer3")
matchesAsP2 Match[] @relation("MatchPlayer2")
matchesAsP1 Match[] @relation("MatchPlayer1")
partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2") partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2")
partnershipStats PartnershipStat[] @relation("StatPlayer1") partnershipGames PartnershipGame[] @relation("PartnershipPlayer1")
partnershipStats2 PartnershipStat[] @relation("StatPlayer2") partnershipStats2 PartnershipStat[] @relation("StatPlayer2")
partnershipStats PartnershipStat[] @relation("StatPlayer1")
teamsAsPlayer2 Team[] @relation("TeamPlayer2")
teamsAsPlayer1 Team[] @relation("TeamPlayer1")
user User?
@@map("players") @@map("players")
} }
// User Model - Authentication and authorization
model User { model User {
id Int @id @default(autoincrement()) id String @id @default(cuid())
playerId Int @unique
email String @unique email String @unique
passwordDigest String emailVerified Boolean @default(false)
role String @default("player") name String?
confirmed Boolean @default(false) image String?
confirmationToken String? role String @default("player") // player, tournament_admin, club_admin
confirmationSentAt DateTime?
resetPasswordToken String? // Session and account references for Better Auth
resetPasswordSentAt DateTime? sessions Session[]
failedLoginAttempts Int @default(0) accounts Account[]
lockedUntil DateTime?
lastLoginAt DateTime? // Link to EuchreCamp player (optional)
lastLoginIp String? 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()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
player Player @relation(fields: [playerId], references: [id])
@@map("users") @@map("users")
} }
// Event (Tournament) Model
model Event { model Event {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
event_id Int? event_id Int?
@@ -72,20 +73,19 @@ model Event {
format String @default("round_robin") format String @default("round_robin")
status String @default("planned") status String @default("planned")
maxParticipants Int? maxParticipants Int?
ownerId String? // User ID of the tournament owner (for tournament_admin)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
bracketMatchups BracketMatchup[]
// Relationships
participants EventParticipant[] participants EventParticipant[]
matches Match[]
teams Team[] teams Team[]
rounds TournamentRound[] rounds TournamentRound[]
bracketMatchups BracketMatchup[] owner User? @relation("TournamentOwner", fields: [ownerId], references: [id])
matches Match[]
@@map("events") @@map("events")
} }
// EventParticipant Model
model EventParticipant { model EventParticipant {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
eventId Int eventId Int
@@ -96,15 +96,13 @@ model EventParticipant {
registrationDate DateTime? registrationDate DateTime?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
event Event @relation(fields: [eventId], references: [id])
player Player @relation(fields: [playerId], references: [id])
team Team? @relation(fields: [teamId], references: [id]) team Team? @relation(fields: [teamId], references: [id])
player Player @relation(fields: [playerId], references: [id])
event Event @relation(fields: [eventId], references: [id])
@@map("event_participants") @@map("event_participants")
} }
// Team Model
model Team { model Team {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
eventId Int eventId Int
@@ -113,19 +111,16 @@ model Team {
player2Id Int player2Id Int
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
// Relationships
event Event @relation(fields: [eventId], references: [id])
player1 Player @relation("TeamPlayer1", fields: [player1Id], references: [id])
player2 Player @relation("TeamPlayer2", fields: [player2Id], references: [id])
eventParticipants EventParticipant[]
bracketMatchups1 BracketMatchup[] @relation("BracketTeam1")
bracketMatchups2 BracketMatchup[] @relation("BracketTeam2") bracketMatchups2 BracketMatchup[] @relation("BracketTeam2")
bracketMatchups1 BracketMatchup[] @relation("BracketTeam1")
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])
@@map("teams") @@map("teams")
} }
// TournamentRound Model
model TournamentRound { model TournamentRound {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
eventId Int eventId Int
@@ -136,14 +131,12 @@ model TournamentRound {
completedAt DateTime? completedAt DateTime?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
event Event @relation(fields: [eventId], references: [id])
bracketMatchups BracketMatchup[] bracketMatchups BracketMatchup[]
event Event @relation(fields: [eventId], references: [id])
@@map("tournament_rounds") @@map("tournament_rounds")
} }
// BracketMatchup Model
model BracketMatchup { model BracketMatchup {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
roundId Int roundId Int
@@ -158,17 +151,15 @@ model BracketMatchup {
status String @default("pending") status String @default("pending")
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
round TournamentRound @relation(fields: [roundId], references: [id])
event Event @relation(fields: [eventId], references: [id])
team1 Team? @relation("BracketTeam1", fields: [team1Id], references: [id])
team2 Team? @relation("BracketTeam2", fields: [team2Id], references: [id])
match Match? @relation(fields: [matchId], references: [id]) 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])
round TournamentRound @relation(fields: [roundId], references: [id])
@@map("bracket_matchups") @@map("bracket_matchups")
} }
// Match Model
model Match { model Match {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
eventId Int? eventId Int?
@@ -180,22 +171,22 @@ model Match {
team1Score Int team1Score Int
team2Score Int team2Score Int
status String @default("completed") status String @default("completed")
createdById String? // User ID of the match creator (for tournament_admin)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
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])
eloSnapshots EloSnapshot[]
partnershipGames PartnershipGame[]
bracketMatchups BracketMatchup[] 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])
@@map("matches") @@map("matches")
} }
// EloSnapshot Model
model EloSnapshot { model EloSnapshot {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
playerId Int playerId Int
@@ -204,14 +195,12 @@ model EloSnapshot {
ratingAfter Int ratingAfter Int
ratingChange Int ratingChange Int
createdAt DateTime @default(now()) createdAt DateTime @default(now())
player Player @relation(fields: [playerId], references: [id])
match Match @relation(fields: [matchId], references: [id]) match Match @relation(fields: [matchId], references: [id])
player Player @relation(fields: [playerId], references: [id])
@@map("elo_snapshots") @@map("elo_snapshots")
} }
// PartnershipGame Model - Tracks each game played by a partnership
model PartnershipGame { model PartnershipGame {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
player1Id Int player1Id Int
@@ -222,15 +211,13 @@ model PartnershipGame {
player1EloChange Int? player1EloChange Int?
player2EloChange Int? player2EloChange Int?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
player1 Player @relation("PartnershipPlayer1", fields: [player1Id], references: [id])
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
match Match @relation(fields: [matchId], references: [id]) match Match @relation(fields: [matchId], references: [id])
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
player1 Player @relation("PartnershipPlayer1", fields: [player1Id], references: [id])
@@map("partnership_games") @@map("partnership_games")
} }
// PartnershipStat Model - Aggregated partnership statistics
model PartnershipStat { model PartnershipStat {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
player1Id Int player1Id Int
@@ -242,9 +229,56 @@ model PartnershipStat {
lastPlayed DateTime? lastPlayed DateTime?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
player1 Player @relation("StatPlayer1", fields: [player1Id], references: [id])
player2 Player @relation("StatPlayer2", fields: [player2Id], references: [id]) player2 Player @relation("StatPlayer2", fields: [player2Id], references: [id])
player1 Player @relation("StatPlayer1", fields: [player1Id], references: [id])
@@map("partnership_stats") @@map("partnership_stats")
} }
model Session {
id String @id
expiresAt DateTime
token String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ipAddress String?
userAgent String?
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([token])
@@index([userId])
@@map("session")
}
model Account {
id String @id
accountId String
providerId String
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
accessToken String?
refreshToken String?
idToken String?
accessTokenExpiresAt DateTime?
refreshTokenExpiresAt DateTime?
scope String?
password String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@map("account")
}
model Verification {
id String @id
identifier String
value String
expiresAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([identifier])
@@map("verification")
}