feat(db): add tournament_admin role and ownership fields to schema
This commit is contained in:
@@ -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;
|
||||||
@@ -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"
|
||||||
+207
-173
@@ -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,192 +8,185 @@ 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
|
||||||
createdAt DateTime @default(now())
|
gamesPlayed Int @default(0) // Total games played
|
||||||
updatedAt DateTime @updatedAt
|
wins Int @default(0) // Total wins
|
||||||
|
losses Int @default(0) // Total losses
|
||||||
// Relationships
|
createdAt DateTime @default(now())
|
||||||
users User[]
|
updatedAt DateTime @updatedAt
|
||||||
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[]
|
||||||
partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2")
|
matchesAsP4 Match[] @relation("MatchPlayer4")
|
||||||
partnershipStats PartnershipStat[] @relation("StatPlayer1")
|
matchesAsP3 Match[] @relation("MatchPlayer3")
|
||||||
partnershipStats2 PartnershipStat[] @relation("StatPlayer2")
|
matchesAsP2 Match[] @relation("MatchPlayer2")
|
||||||
|
matchesAsP1 Match[] @relation("MatchPlayer1")
|
||||||
|
partnershipGames2 PartnershipGame[] @relation("PartnershipPlayer2")
|
||||||
|
partnershipGames PartnershipGame[] @relation("PartnershipPlayer1")
|
||||||
|
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
|
emailVerified Boolean @default(false)
|
||||||
passwordDigest String
|
name String?
|
||||||
role String @default("player")
|
image String?
|
||||||
confirmed Boolean @default(false)
|
role String @default("player") // player, tournament_admin, club_admin
|
||||||
confirmationToken String?
|
|
||||||
confirmationSentAt DateTime?
|
// Session and account references for Better Auth
|
||||||
resetPasswordToken String?
|
sessions Session[]
|
||||||
resetPasswordSentAt DateTime?
|
accounts Account[]
|
||||||
failedLoginAttempts Int @default(0)
|
|
||||||
lockedUntil DateTime?
|
// Link to EuchreCamp player (optional)
|
||||||
lastLoginAt DateTime?
|
playerId Int? @unique
|
||||||
lastLoginIp String?
|
player Player? @relation(fields: [playerId], references: [id])
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
// Tournaments owned by this user
|
||||||
|
ownedTournaments Event[] @relation("TournamentOwner")
|
||||||
player Player @relation(fields: [playerId], references: [id])
|
|
||||||
|
// Matches created by this user
|
||||||
|
createdMatches Match[] @relation("MatchCreator")
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
@@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?
|
||||||
name String
|
name String
|
||||||
description String?
|
description String?
|
||||||
eventDate DateTime?
|
eventDate DateTime?
|
||||||
eventType String @default("tournament")
|
eventType String @default("tournament")
|
||||||
format String @default("round_robin")
|
format String @default("round_robin")
|
||||||
status String @default("planned")
|
status String @default("planned")
|
||||||
maxParticipants Int?
|
maxParticipants Int?
|
||||||
createdAt DateTime @default(now())
|
ownerId String? // User ID of the tournament owner (for tournament_admin)
|
||||||
updatedAt DateTime @updatedAt
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
// Relationships
|
bracketMatchups BracketMatchup[]
|
||||||
participants EventParticipant[]
|
participants EventParticipant[]
|
||||||
teams Team[]
|
matches Match[]
|
||||||
rounds TournamentRound[]
|
teams Team[]
|
||||||
bracketMatchups BracketMatchup[]
|
rounds TournamentRound[]
|
||||||
matches Match[]
|
owner User? @relation("TournamentOwner", fields: [ownerId], references: [id])
|
||||||
|
|
||||||
@@map("events")
|
@@map("events")
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventParticipant Model
|
|
||||||
model EventParticipant {
|
model EventParticipant {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
eventId Int
|
eventId Int
|
||||||
playerId Int
|
playerId Int
|
||||||
teamId Int?
|
teamId Int?
|
||||||
seed Int?
|
seed Int?
|
||||||
status String @default("registered")
|
status String @default("registered")
|
||||||
registrationDate DateTime?
|
registrationDate DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
team Team? @relation(fields: [teamId], references: [id])
|
||||||
event Event @relation(fields: [eventId], references: [id])
|
player Player @relation(fields: [playerId], references: [id])
|
||||||
player Player @relation(fields: [playerId], references: [id])
|
event Event @relation(fields: [eventId], references: [id])
|
||||||
team Team? @relation(fields: [teamId], 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
|
||||||
teamName String?
|
teamName String?
|
||||||
player1Id Int
|
player1Id Int
|
||||||
player2Id Int
|
player2Id Int
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
bracketMatchups2 BracketMatchup[] @relation("BracketTeam2")
|
||||||
// Relationships
|
bracketMatchups1 BracketMatchup[] @relation("BracketTeam1")
|
||||||
event Event @relation(fields: [eventId], references: [id])
|
eventParticipants EventParticipant[]
|
||||||
player1 Player @relation("TeamPlayer1", fields: [player1Id], references: [id])
|
player2 Player @relation("TeamPlayer2", fields: [player2Id], references: [id])
|
||||||
player2 Player @relation("TeamPlayer2", fields: [player2Id], references: [id])
|
player1 Player @relation("TeamPlayer1", fields: [player1Id], references: [id])
|
||||||
eventParticipants EventParticipant[]
|
event Event @relation(fields: [eventId], references: [id])
|
||||||
bracketMatchups1 BracketMatchup[] @relation("BracketTeam1")
|
|
||||||
bracketMatchups2 BracketMatchup[] @relation("BracketTeam2")
|
|
||||||
|
|
||||||
@@map("teams")
|
@@map("teams")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TournamentRound Model
|
|
||||||
model TournamentRound {
|
model TournamentRound {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
eventId Int
|
eventId Int
|
||||||
roundNumber Int
|
roundNumber Int
|
||||||
status String @default("pending")
|
status String @default("pending")
|
||||||
scheduledStart DateTime?
|
scheduledStart DateTime?
|
||||||
actualStart DateTime?
|
actualStart DateTime?
|
||||||
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
|
||||||
eventId Int
|
eventId Int
|
||||||
team1Id Int?
|
team1Id Int?
|
||||||
team2Id Int?
|
team2Id Int?
|
||||||
matchId Int?
|
matchId Int?
|
||||||
tableNumber Int?
|
tableNumber Int?
|
||||||
bracketPosition Int?
|
bracketPosition Int?
|
||||||
winnerTeamId Int?
|
winnerTeamId Int?
|
||||||
loserTeamId Int?
|
loserTeamId Int?
|
||||||
status String @default("pending")
|
status String @default("pending")
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
match Match? @relation(fields: [matchId], references: [id])
|
||||||
round TournamentRound @relation(fields: [roundId], references: [id])
|
team2 Team? @relation("BracketTeam2", fields: [team2Id], references: [id])
|
||||||
event Event @relation(fields: [eventId], references: [id])
|
team1 Team? @relation("BracketTeam1", fields: [team1Id], references: [id])
|
||||||
team1 Team? @relation("BracketTeam1", fields: [team1Id], references: [id])
|
event Event @relation(fields: [eventId], references: [id])
|
||||||
team2 Team? @relation("BracketTeam2", fields: [team2Id], references: [id])
|
round TournamentRound @relation(fields: [roundId], references: [id])
|
||||||
match Match? @relation(fields: [matchId], 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?
|
||||||
playedAt DateTime?
|
playedAt DateTime?
|
||||||
team1P1Id Int
|
team1P1Id Int
|
||||||
team1P2Id Int
|
team1P2Id Int
|
||||||
team2P1Id Int
|
team2P1Id Int
|
||||||
team2P2Id Int
|
team2P2Id Int
|
||||||
team1Score Int
|
team1Score Int
|
||||||
team2Score Int
|
team2Score Int
|
||||||
status String @default("completed")
|
status String @default("completed")
|
||||||
createdAt DateTime @default(now())
|
createdById String? // User ID of the match creator (for tournament_admin)
|
||||||
updatedAt DateTime @updatedAt
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
event Event? @relation(fields: [eventId], references: [id])
|
bracketMatchups BracketMatchup[]
|
||||||
team1P1 Player @relation("MatchPlayer1", fields: [team1P1Id], references: [id])
|
eloSnapshots EloSnapshot[]
|
||||||
team1P2 Player @relation("MatchPlayer2", fields: [team1P2Id], references: [id])
|
team2P2 Player @relation("MatchPlayer4", fields: [team2P2Id], references: [id])
|
||||||
team2P1 Player @relation("MatchPlayer3", fields: [team2P1Id], references: [id])
|
team2P1 Player @relation("MatchPlayer3", fields: [team2P1Id], references: [id])
|
||||||
team2P2 Player @relation("MatchPlayer4", fields: [team2P2Id], references: [id])
|
team1P2 Player @relation("MatchPlayer2", fields: [team1P2Id], references: [id])
|
||||||
eloSnapshots EloSnapshot[]
|
team1P1 Player @relation("MatchPlayer1", fields: [team1P1Id], references: [id])
|
||||||
|
event Event? @relation(fields: [eventId], references: [id])
|
||||||
partnershipGames PartnershipGame[]
|
partnershipGames PartnershipGame[]
|
||||||
bracketMatchups BracketMatchup[]
|
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,47 +195,90 @@ model EloSnapshot {
|
|||||||
ratingAfter Int
|
ratingAfter Int
|
||||||
ratingChange Int
|
ratingChange Int
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
match Match @relation(fields: [matchId], references: [id])
|
||||||
player Player @relation(fields: [playerId], references: [id])
|
player Player @relation(fields: [playerId], references: [id])
|
||||||
match Match @relation(fields: [matchId], 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
|
||||||
player2Id Int
|
player2Id Int
|
||||||
matchId Int
|
matchId Int
|
||||||
teamNumber Int?
|
teamNumber Int?
|
||||||
wonMatch Int?
|
wonMatch Int?
|
||||||
player1EloChange Int?
|
player1EloChange Int?
|
||||||
player2EloChange Int?
|
player2EloChange Int?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
|
match Match @relation(fields: [matchId], references: [id])
|
||||||
player1 Player @relation("PartnershipPlayer1", fields: [player1Id], references: [id])
|
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
|
||||||
player2 Player @relation("PartnershipPlayer2", fields: [player2Id], references: [id])
|
player1 Player @relation("PartnershipPlayer1", fields: [player1Id], references: [id])
|
||||||
match Match @relation(fields: [matchId], 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
|
||||||
player2Id Int
|
player2Id Int
|
||||||
gamesPlayed Int @default(0)
|
gamesPlayed Int @default(0)
|
||||||
wins Int @default(0)
|
wins Int @default(0)
|
||||||
losses Int @default(0)
|
losses Int @default(0)
|
||||||
totalEloChange Int @default(0)
|
totalEloChange Int @default(0)
|
||||||
lastPlayed DateTime?
|
lastPlayed DateTime?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
player2 Player @relation("StatPlayer2", fields: [player2Id], references: [id])
|
||||||
player1 Player @relation("StatPlayer1", fields: [player1Id], references: [id])
|
player1 Player @relation("StatPlayer1", fields: [player1Id], references: [id])
|
||||||
player2 Player @relation("StatPlayer2", fields: [player2Id], 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")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user