From f40144e1e2656b9f6cbaa6d203304ae3c1849fa2 Mon Sep 17 00:00:00 2001
From: chrisp
Date: Fri, 12 Jun 2026 22:35:35 +0000
Subject: [PATCH] claude/great-lovelace-r3bznh (#88)
Co-authored-by: Claude
Reviewed-on: https://forge.brackt.com/chrisp/brackt/pulls/88
---
.../scoring/Cs2TournamentBracket.tsx | 199 +
app/components/scoring/MatchSchedule.tsx | 136 +
app/models/__tests__/season-match.test.ts | 234 +
app/models/index.ts | 1 +
app/models/scoring-calculator.ts | 22 +-
app/models/season-match.ts | 232 +
app/routes.ts | 9 +
...sons.$id.events.$eventId.bracket.server.ts | 34 +-
...-seasons.$id.events.$eventId.cs2-setup.tsx | 126 +-
...sons.$id.events.$eventId.swiss-matches.tsx | 382 +
app/routes/admin.sports-seasons.$id.tsx | 19 +
app/routes/admin.sports-seasons.new.tsx | 18 +
app/routes/admin/jobs.sync-matches.ts | 41 +
...rts-seasons.$sportsSeasonId.tournament.tsx | 135 +
.../__tests__/espn-schedule.test.ts | 236 +
.../match-sync/__tests__/pandascore.test.ts | 163 +
app/services/match-sync/espn-schedule.ts | 96 +
app/services/match-sync/index.ts | 271 +
app/services/match-sync/pandascore.ts | 137 +
app/services/match-sync/types.ts | 44 +
database/schema.ts | 117 +
docs/plans/match-sync-display.md | 255 +
drizzle/0120_tidy_invaders.sql | 87 +
drizzle/0121_even_gambit.sql | 1 +
drizzle/meta/0120_snapshot.json | 6712 ++++++++++++++++
drizzle/meta/0121_snapshot.json | 6718 +++++++++++++++++
drizzle/meta/_journal.json | 14 +
27 files changed, 16400 insertions(+), 39 deletions(-)
create mode 100644 app/components/scoring/Cs2TournamentBracket.tsx
create mode 100644 app/components/scoring/MatchSchedule.tsx
create mode 100644 app/models/__tests__/season-match.test.ts
create mode 100644 app/models/season-match.ts
create mode 100644 app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx
create mode 100644 app/routes/admin/jobs.sync-matches.ts
create mode 100644 app/routes/sports-seasons.$sportsSeasonId.tournament.tsx
create mode 100644 app/services/match-sync/__tests__/espn-schedule.test.ts
create mode 100644 app/services/match-sync/__tests__/pandascore.test.ts
create mode 100644 app/services/match-sync/espn-schedule.ts
create mode 100644 app/services/match-sync/index.ts
create mode 100644 app/services/match-sync/pandascore.ts
create mode 100644 app/services/match-sync/types.ts
create mode 100644 docs/plans/match-sync-display.md
create mode 100644 drizzle/0120_tidy_invaders.sql
create mode 100644 drizzle/0121_even_gambit.sql
create mode 100644 drizzle/meta/0120_snapshot.json
create mode 100644 drizzle/meta/0121_snapshot.json
diff --git a/app/components/scoring/Cs2TournamentBracket.tsx b/app/components/scoring/Cs2TournamentBracket.tsx
new file mode 100644
index 0000000..6843064
--- /dev/null
+++ b/app/components/scoring/Cs2TournamentBracket.tsx
@@ -0,0 +1,199 @@
+import { useState } from "react";
+import type { SeasonMatch, MatchSubGame } from "~/models/season-match";
+import { PlayoffBracket, type Match as PlayoffMatch, type TeamOwnership } from "./PlayoffBracket";
+
+type MatchWithRelations = SeasonMatch & {
+ participant1: { id: string; name: string } | null;
+ participant2: { id: string; name: string } | null;
+ winner: { id: string; name: string } | null;
+ subGames: MatchSubGame[];
+};
+
+interface Cs2TournamentBracketProps {
+ swissMatches: MatchWithRelations[];
+ playoffMatches: PlayoffMatch[];
+ playoffRounds: string[];
+ bracketTemplateId?: string | null;
+ teamOwnerships?: TeamOwnership[];
+ userParticipantIds?: string[];
+}
+
+const STATUS_BADGE: Record = {
+ scheduled: "bg-muted text-muted-foreground text-xs px-2 py-0.5 rounded",
+ in_progress: "bg-amber-500/15 text-amber-400 border border-amber-500/30 text-xs px-2 py-0.5 rounded",
+ complete: "bg-emerald-500/15 text-emerald-400 border border-emerald-500/30 text-xs px-2 py-0.5 rounded",
+ canceled: "bg-destructive/15 text-destructive text-xs px-2 py-0.5 rounded",
+ postponed: "bg-muted text-muted-foreground text-xs px-2 py-0.5 rounded italic",
+};
+
+function MapScores({ subGames, p1Id, p2Id }: { subGames: MatchSubGame[]; p1Id: string | null; p2Id: string | null }) {
+ if (subGames.length === 0) return null;
+ return (
+
+ {subGames.map((g) => (
+
+ {g.gameLabel && {g.gameLabel} }
+ {g.participant1Score ?? "-"}
+ {" – "}
+ {g.participant2Score ?? "-"}
+
+ ))}
+
+ );
+}
+
+function MatchCard({ match }: { match: MatchWithRelations }) {
+ const p1 = match.participant1;
+ const p2 = match.participant2;
+ const winnerId = match.winnerId;
+ const isComplete = match.status === "complete";
+
+ return (
+
+
+
+
+ {p1?.name ?? "TBD"}
+ {isComplete && (
+ {match.participant1Score ?? ""}
+ )}
+
+
+ {p2?.name ?? "TBD"}
+ {isComplete && (
+ {match.participant2Score ?? ""}
+ )}
+
+
+
+
+
+ {match.status === "in_progress" && (
+
+ )}
+ {match.status === "complete" ? "Final" : match.status === "in_progress" ? "Live" : match.status === "scheduled" ? "Upcoming" : match.status}
+
+
+
+
+ );
+}
+
+function SwissStageTab({ stage: _stage, matches }: { stage: number; matches: MatchWithRelations[] }) {
+ if (matches.length === 0) {
+ return No matches for this stage yet.
;
+ }
+
+ // Group matches by round
+ const rounds = new Map();
+ for (const m of matches) {
+ const r = m.matchRound ?? 0;
+ let roundGroup = rounds.get(r);
+ if (!roundGroup) {
+ roundGroup = [];
+ rounds.set(r, roundGroup);
+ }
+ roundGroup.push(m);
+ }
+
+ const sortedRounds = [...rounds.entries()].toSorted(([a], [b]) => a - b);
+
+ return (
+
+ {sortedRounds.map(([round, roundMatches]) => (
+
+ {round > 0 && (
+
+ Round {round}
+
+ )}
+
+ {roundMatches.map((m) => (
+
+ ))}
+
+
+ ))}
+
+ );
+}
+
+export function Cs2TournamentBracket({
+ swissMatches,
+ playoffMatches,
+ playoffRounds,
+ bracketTemplateId,
+ teamOwnerships,
+ userParticipantIds,
+}: Cs2TournamentBracketProps) {
+ const stages = [1, 2, 3].filter((s) => swissMatches.some((m) => m.matchStage === s));
+ const hasBracket = playoffMatches.length > 0;
+
+ type Tab = "swiss-1" | "swiss-2" | "swiss-3" | "bracket";
+ const availableTabs: Tab[] = [
+ ...(stages.includes(1) ? (["swiss-1"] as Tab[]) : []),
+ ...(stages.includes(2) ? (["swiss-2"] as Tab[]) : []),
+ ...(stages.includes(3) ? (["swiss-3"] as Tab[]) : []),
+ ...(hasBracket ? (["bracket"] as Tab[]) : []),
+ ];
+
+ const [activeTab, setActiveTab] = useState(availableTabs[0] ?? "swiss-1");
+
+ const tabLabel: Record = {
+ "swiss-1": "Opening Stage",
+ "swiss-2": "Challengers Stage",
+ "swiss-3": "Legends Stage",
+ bracket: "Champions Stage",
+ };
+
+ if (availableTabs.length === 0) {
+ return (
+
+ No match data available yet.
+
+ );
+ }
+
+ return (
+
+ {/* Tab bar */}
+
+ {availableTabs.map((tab) => (
+ setActiveTab(tab)}
+ className={`px-4 py-2 text-sm font-medium whitespace-nowrap border-b-2 transition-colors ${
+ activeTab === tab
+ ? "border-primary text-foreground"
+ : "border-transparent text-muted-foreground hover:text-foreground"
+ }`}
+ >
+ {tabLabel[tab]}
+
+ ))}
+
+
+ {/* Tab content */}
+
+ {activeTab === "swiss-1" && (
+
m.matchStage === 1)} />
+ )}
+ {activeTab === "swiss-2" && (
+ m.matchStage === 2)} />
+ )}
+ {activeTab === "swiss-3" && (
+ m.matchStage === 3)} />
+ )}
+ {activeTab === "bracket" && hasBracket && (
+
+ )}
+
+
+ );
+}
diff --git a/app/components/scoring/MatchSchedule.tsx b/app/components/scoring/MatchSchedule.tsx
new file mode 100644
index 0000000..3da0cae
--- /dev/null
+++ b/app/components/scoring/MatchSchedule.tsx
@@ -0,0 +1,136 @@
+import type { SeasonMatch, MatchSubGame } from "~/models/season-match";
+
+type MatchWithRelations = SeasonMatch & {
+ participant1: { name: string } | null;
+ participant2: { name: string } | null;
+ winner: { name: string } | null;
+ subGames: MatchSubGame[];
+};
+
+interface MatchScheduleProps {
+ matches: MatchWithRelations[];
+ title?: string;
+}
+
+const STATUS_BADGE: Record = {
+ scheduled: "bg-muted text-muted-foreground",
+ in_progress: "bg-amber-500/15 text-amber-400 border border-amber-500/30",
+ complete: "bg-emerald-500/15 text-emerald-400 border border-emerald-500/30",
+ canceled: "bg-destructive/15 text-destructive border border-destructive/30",
+ postponed: "bg-muted text-muted-foreground",
+};
+
+const STATUS_LABEL: Record = {
+ scheduled: "Scheduled",
+ in_progress: "Live",
+ complete: "Final",
+ canceled: "Canceled",
+ postponed: "Postponed",
+};
+
+function formatDate(d: Date | null) {
+ if (!d) return "TBD";
+ return new Intl.DateTimeFormat("en-US", {
+ month: "short",
+ day: "numeric",
+ hour: "numeric",
+ minute: "2-digit",
+ timeZoneName: "short",
+ }).format(new Date(d));
+}
+
+function MatchRow({ match }: { match: MatchWithRelations }) {
+ const p1 = match.participant1?.name ?? "TBD";
+ const p2 = match.participant2?.name ?? "TBD";
+ const isComplete = match.status === "complete";
+ const winnerId = match.winnerId;
+
+ return (
+
+
+
+
+ {isComplete && (
+
+
+ {match.participant1Score ?? "-"}
+
+
+ {match.participant2Score ?? "-"}
+
+
+ )}
+ {match.status === "in_progress" && (
+
+
{match.participant1Score ?? "-"}
+
{match.participant2Score ?? "-"}
+
+ )}
+
+ {match.matchday !== null && (
+
Matchday {match.matchday}
+ )}
+
+
+
+ {match.status === "in_progress" && }
+ {STATUS_LABEL[match.status] ?? match.status}
+
+ {formatDate(match.scheduledAt)}
+
+
+ );
+}
+
+// Groups by matchday number when available, or by UTC calendar date (YYYY-MM-DD) for date-based sports.
+// UTC date keys ensure consistent grouping regardless of the viewer's timezone.
+function groupByMatchday(matches: MatchWithRelations[]) {
+ const groups = new Map();
+ for (const m of matches) {
+ const key = m.matchday !== null
+ ? `Matchday ${m.matchday}`
+ : m.scheduledAt?.toISOString().slice(0, 10) ?? "TBD";
+ let group = groups.get(key);
+ if (!group) {
+ group = [];
+ groups.set(key, group);
+ }
+ group.push(m);
+ }
+ return groups;
+}
+
+export function MatchSchedule({ matches, title = "Schedule" }: MatchScheduleProps) {
+ if (matches.length === 0) {
+ return (
+
+ No matches scheduled yet.
+
+ );
+ }
+
+ const grouped = groupByMatchday(matches);
+
+ return (
+
+ {title &&
{title} }
+ {[...grouped.entries()].map(([label, group]) => (
+
+
+ {label}
+
+ {group.map((m) => (
+
+ ))}
+
+ ))}
+
+ );
+}
diff --git a/app/models/__tests__/season-match.test.ts b/app/models/__tests__/season-match.test.ts
new file mode 100644
index 0000000..adab14a
--- /dev/null
+++ b/app/models/__tests__/season-match.test.ts
@@ -0,0 +1,234 @@
+import { describe, it, expect, vi, beforeEach } from "vitest";
+
+vi.mock("~/database/context", () => ({
+ database: vi.fn(),
+}));
+
+import {
+ upsertSeasonMatch,
+ upsertSeasonMatchBulk,
+ upsertMatchSubGame,
+} from "../season-match";
+import { database } from "~/database/context";
+
+const SPORTS_SEASON_ID = "ss-1";
+const SCORING_EVENT_ID = "evt-1";
+const P1_ID = "p1";
+const P2_ID = "p2";
+const WINNER_ID = "p1";
+const EXTERNAL_ID = "panda_123";
+
+function makeUpsertDb(returnValue: object) {
+ const returningFn = vi.fn().mockResolvedValue([returnValue]);
+ const onConflictFn = vi.fn().mockReturnValue({ returning: returningFn });
+ const valuesFn = vi.fn().mockReturnValue({ onConflictDoUpdate: onConflictFn });
+ return {
+ insert: vi.fn().mockReturnValue({ values: valuesFn }),
+ _returning: returningFn,
+ _onConflict: onConflictFn,
+ _values: valuesFn,
+ };
+}
+
+function makeBulkUpsertDb(returnValues: object[]) {
+ const returningFn = vi.fn().mockResolvedValue(returnValues);
+ const onConflictFn = vi.fn().mockReturnValue({ returning: returningFn });
+ const valuesFn = vi.fn().mockReturnValue({ onConflictDoUpdate: onConflictFn });
+ return {
+ insert: vi.fn().mockReturnValue({ values: valuesFn }),
+ _returning: returningFn,
+ };
+}
+
+const SAMPLE_MATCH = {
+ id: "match-1",
+ sportsSeasonId: SPORTS_SEASON_ID,
+ scoringEventId: SCORING_EVENT_ID,
+ participant1Id: P1_ID,
+ participant2Id: P2_ID,
+ winnerId: WINNER_ID,
+ participant1Score: 2,
+ participant2Score: 1,
+ matchStage: 1,
+ matchRound: 3,
+ matchday: null,
+ isSeries: true,
+ status: "complete" as const,
+ scheduledAt: null,
+ startedAt: null,
+ completedAt: new Date("2025-01-15T14:00:00Z"),
+ externalMatchId: EXTERNAL_ID,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+};
+
+describe("upsertSeasonMatch", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("inserts a match and returns it", async () => {
+ const mockDb = makeUpsertDb(SAMPLE_MATCH);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertSeasonMatch({
+ sportsSeasonId: SPORTS_SEASON_ID,
+ scoringEventId: SCORING_EVENT_ID,
+ participant1Id: P1_ID,
+ participant2Id: P2_ID,
+ winnerId: WINNER_ID,
+ participant1Score: 2,
+ participant2Score: 1,
+ matchStage: 1,
+ matchRound: 3,
+ isSeries: true,
+ status: "complete",
+ completedAt: new Date("2025-01-15T14:00:00Z"),
+ externalMatchId: EXTERNAL_ID,
+ });
+
+ expect(result.id).toBe("match-1");
+ expect(result.matchStage).toBe(1);
+ expect(result.matchRound).toBe(3);
+ expect(result.status).toBe("complete");
+ expect(mockDb.insert).toHaveBeenCalledOnce();
+ expect(mockDb._values).toHaveBeenCalledOnce();
+ expect(mockDb._onConflict).toHaveBeenCalledOnce();
+ });
+
+ it("defaults isSeries to false when not provided", async () => {
+ const expectedMatch = { ...SAMPLE_MATCH, isSeries: false };
+ const mockDb = makeUpsertDb(expectedMatch);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertSeasonMatch({
+ sportsSeasonId: SPORTS_SEASON_ID,
+ externalMatchId: "ext_1",
+ status: "scheduled",
+ });
+
+ const valuesCall = mockDb._values.mock.calls[0][0];
+ expect(valuesCall.isSeries).toBe(false);
+ expect(result.isSeries).toBe(false);
+ });
+
+ it("allows null matchStage and matchRound for non-CS2 sports", async () => {
+ const mlbMatch = { ...SAMPLE_MATCH, matchStage: null, matchRound: null, matchday: null, isSeries: false };
+ const mockDb = makeUpsertDb(mlbMatch);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertSeasonMatch({
+ sportsSeasonId: SPORTS_SEASON_ID,
+ externalMatchId: "mlb_game_456",
+ status: "complete",
+ participant1Score: 5,
+ participant2Score: 3,
+ });
+
+ const valuesCall = mockDb._values.mock.calls[0][0];
+ expect(valuesCall.matchStage).toBeUndefined();
+ expect(valuesCall.matchRound).toBeUndefined();
+ expect(result.matchStage).toBeNull();
+ expect(result.matchRound).toBeNull();
+ });
+});
+
+describe("upsertSeasonMatchBulk", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("returns empty array for empty input", async () => {
+ vi.mocked(database).mockReturnValue({} as ReturnType);
+ const result = await upsertSeasonMatchBulk([]);
+ expect(result).toEqual([]);
+ });
+
+ it("bulk upserts multiple matches", async () => {
+ const match2 = { ...SAMPLE_MATCH, id: "match-2", matchRound: 4, externalMatchId: "panda_456" };
+ const mockDb = makeBulkUpsertDb([SAMPLE_MATCH, match2]);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertSeasonMatchBulk([
+ { sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: EXTERNAL_ID, status: "complete", matchStage: 1, matchRound: 3 },
+ { sportsSeasonId: SPORTS_SEASON_ID, externalMatchId: "panda_456", status: "complete", matchStage: 1, matchRound: 4 },
+ ]);
+
+ expect(result).toHaveLength(2);
+ expect(mockDb.insert).toHaveBeenCalledOnce();
+ });
+});
+
+describe("upsertMatchSubGame", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("upserts a map sub-game", async () => {
+ const subGame = {
+ id: "sg-1",
+ seasonMatchId: "match-1",
+ gameNumber: 1,
+ gameLabel: "Mirage",
+ participant1Score: 16,
+ participant2Score: 14,
+ winnerId: P1_ID,
+ status: "complete" as const,
+ startedAt: null,
+ completedAt: new Date(),
+ externalGameId: "map_1",
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+ const mockDb = makeUpsertDb(subGame);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertMatchSubGame({
+ seasonMatchId: "match-1",
+ gameNumber: 1,
+ gameLabel: "Mirage",
+ participant1Score: 16,
+ participant2Score: 14,
+ winnerId: P1_ID,
+ status: "complete",
+ externalGameId: "map_1",
+ });
+
+ expect(result.gameLabel).toBe("Mirage");
+ expect(result.participant1Score).toBe(16);
+ expect(result.gameNumber).toBe(1);
+ expect(mockDb.insert).toHaveBeenCalledOnce();
+ expect(mockDb._onConflict).toHaveBeenCalledOnce();
+ });
+
+ it("allows null gameLabel for non-named sub-games", async () => {
+ const subGame = {
+ id: "sg-2",
+ seasonMatchId: "match-1",
+ gameNumber: 2,
+ gameLabel: null,
+ participant1Score: 3,
+ participant2Score: 1,
+ winnerId: P1_ID,
+ status: "complete" as const,
+ startedAt: null,
+ completedAt: new Date(),
+ externalGameId: null,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ };
+ const mockDb = makeUpsertDb(subGame);
+ vi.mocked(database).mockReturnValue(mockDb as unknown as ReturnType);
+
+ const result = await upsertMatchSubGame({
+ seasonMatchId: "match-1",
+ gameNumber: 2,
+ participant1Score: 3,
+ participant2Score: 1,
+ status: "complete",
+ });
+
+ expect(result.gameLabel).toBeNull();
+ expect(result.gameNumber).toBe(2);
+ });
+});
diff --git a/app/models/index.ts b/app/models/index.ts
index 0598a45..4b3c38d 100644
--- a/app/models/index.ts
+++ b/app/models/index.ts
@@ -23,3 +23,4 @@ export * from "./participant";
export * from "./tournament-result";
export * from "./canonical-surface-elo";
export * from "./canonical-golf-skills";
+export * from "./season-match";
diff --git a/app/models/scoring-calculator.ts b/app/models/scoring-calculator.ts
index 8efff96..283b34b 100644
--- a/app/models/scoring-calculator.ts
+++ b/app/models/scoring-calculator.ts
@@ -11,7 +11,7 @@ import { getSeasonResults } from "./participant-season-result";
import { updateProbabilitiesAfterResult } from "~/services/probability-updater";
import { sendStandingsUpdateNotification, type ScoredMatch } from "~/services/discord";
import { BRACKET_TEMPLATES } from "~/lib/bracket-templates";
-import { doesLoserAdvance } from "~/models/playoff-match";
+import { doesLoserAdvance, findPlayoffMatchesByEventId } from "~/models/playoff-match";
import { getUserDisplayName } from "~/models/user";
import { findDiscordIdsByUserIds } from "~/models/account";
import { createDailySnapshot } from "~/models/standings";
@@ -1657,3 +1657,23 @@ export async function recalculateAffectedLeagues(
`[ScoringCalculator] Recalculated ${seasonIds.length} affected season(s) for sports season ${sportsSeasonId}`
);
}
+
+export async function autoCompleteRoundIfDone(
+ eventId: string,
+ round: string,
+ sportsSeasonId: string,
+ db: ReturnType
+): Promise {
+ const allMatches = await findPlayoffMatchesByEventId(eventId);
+ const roundMatches = allMatches.filter((m) => m.round === round);
+ if (roundMatches.length === 0) return;
+ if (!roundMatches.every((m) => m.isComplete)) return;
+
+ await db
+ .update(schema.scoringEvents)
+ .set({ playoffRound: round, updatedAt: new Date() })
+ .where(eq(schema.scoringEvents.id, eventId));
+
+ await processPlayoffEvent(eventId, db, { skipRecalculate: true, skipProbabilities: true });
+ logger.log(`[AutoComplete] Round "${round}" auto-completed for event ${eventId}`);
+}
diff --git a/app/models/season-match.ts b/app/models/season-match.ts
new file mode 100644
index 0000000..d114afc
--- /dev/null
+++ b/app/models/season-match.ts
@@ -0,0 +1,232 @@
+import { and, asc, eq, isNotNull, sql } from "drizzle-orm";
+import { database } from "~/database/context";
+import * as schema from "~/database/schema";
+
+export type SeasonMatch = typeof schema.seasonMatches.$inferSelect;
+export type MatchSubGame = typeof schema.matchSubGames.$inferSelect;
+export type MatchStatus = (typeof schema.matchStatusEnum.enumValues)[number];
+
+export interface UpsertSeasonMatchData {
+ sportsSeasonId: string;
+ scoringEventId?: string | null;
+ participant1Id?: string | null;
+ participant2Id?: string | null;
+ winnerId?: string | null;
+ participant1Score?: number | null;
+ participant2Score?: number | null;
+ matchStage?: number | null;
+ matchRound?: number | null;
+ matchday?: number | null;
+ isSeries?: boolean;
+ status: MatchStatus;
+ scheduledAt?: Date | null;
+ startedAt?: Date | null;
+ completedAt?: Date | null;
+ externalMatchId: string;
+}
+
+export interface UpsertMatchSubGameData {
+ seasonMatchId: string;
+ gameNumber: number;
+ gameLabel?: string | null;
+ participant1Score?: number | null;
+ participant2Score?: number | null;
+ winnerId?: string | null;
+ status: MatchStatus;
+ startedAt?: Date | null;
+ completedAt?: Date | null;
+ externalGameId?: string | null;
+}
+
+export async function upsertSeasonMatch(
+ data: UpsertSeasonMatchData
+): Promise {
+ const db = database();
+ const now = new Date();
+ const [result] = await db
+ .insert(schema.seasonMatches)
+ .values({
+ ...data,
+ isSeries: data.isSeries ?? false,
+ updatedAt: now,
+ })
+ .onConflictDoUpdate({
+ target: schema.seasonMatches.externalMatchId,
+ targetWhere: isNotNull(schema.seasonMatches.externalMatchId),
+ set: {
+ participant1Id: sql`excluded.participant1_id`,
+ participant2Id: sql`excluded.participant2_id`,
+ winnerId: sql`excluded.winner_id`,
+ participant1Score: sql`excluded.participant1_score`,
+ participant2Score: sql`excluded.participant2_score`,
+ matchStage: sql`excluded.match_stage`,
+ matchRound: sql`excluded.match_round`,
+ matchday: sql`excluded.matchday`,
+ isSeries: sql`excluded.is_series`,
+ status: sql`excluded.status`,
+ scheduledAt: sql`excluded.scheduled_at`,
+ startedAt: sql`excluded.started_at`,
+ completedAt: sql`excluded.completed_at`,
+ updatedAt: now,
+ },
+ })
+ .returning();
+ return result;
+}
+
+export async function upsertSeasonMatchBulk(
+ records: UpsertSeasonMatchData[]
+): Promise {
+ if (records.length === 0) return [];
+ const db = database();
+ const now = new Date();
+ return await db
+ .insert(schema.seasonMatches)
+ .values(records.map((r) => ({ ...r, isSeries: r.isSeries ?? false, updatedAt: now })))
+ .onConflictDoUpdate({
+ target: schema.seasonMatches.externalMatchId,
+ targetWhere: isNotNull(schema.seasonMatches.externalMatchId),
+ set: {
+ participant1Id: sql`excluded.participant1_id`,
+ participant2Id: sql`excluded.participant2_id`,
+ winnerId: sql`excluded.winner_id`,
+ participant1Score: sql`excluded.participant1_score`,
+ participant2Score: sql`excluded.participant2_score`,
+ matchStage: sql`excluded.match_stage`,
+ matchRound: sql`excluded.match_round`,
+ matchday: sql`excluded.matchday`,
+ isSeries: sql`excluded.is_series`,
+ status: sql`excluded.status`,
+ scheduledAt: sql`excluded.scheduled_at`,
+ startedAt: sql`excluded.started_at`,
+ completedAt: sql`excluded.completed_at`,
+ updatedAt: now,
+ },
+ })
+ .returning();
+}
+
+export async function findSeasonMatchesBySportsSeasonId(
+ sportsSeasonId: string,
+ filters?: { status?: MatchStatus; matchStage?: number }
+) {
+ const db = database();
+ return await db.query.seasonMatches.findMany({
+ where: and(
+ eq(schema.seasonMatches.sportsSeasonId, sportsSeasonId),
+ filters?.status ? eq(schema.seasonMatches.status, filters.status) : undefined,
+ filters?.matchStage !== undefined
+ ? eq(schema.seasonMatches.matchStage, filters.matchStage)
+ : undefined
+ ),
+ orderBy: [
+ asc(schema.seasonMatches.matchStage),
+ asc(schema.seasonMatches.matchRound),
+ asc(schema.seasonMatches.matchday),
+ asc(schema.seasonMatches.scheduledAt),
+ asc(schema.seasonMatches.createdAt),
+ ],
+ with: {
+ participant1: true,
+ participant2: true,
+ winner: true,
+ subGames: { orderBy: [asc(schema.matchSubGames.gameNumber)] },
+ },
+ });
+}
+
+export async function findSeasonMatchesByScoringEventId(scoringEventId: string) {
+ const db = database();
+ return await db.query.seasonMatches.findMany({
+ where: eq(schema.seasonMatches.scoringEventId, scoringEventId),
+ orderBy: [
+ asc(schema.seasonMatches.matchStage),
+ asc(schema.seasonMatches.matchRound),
+ asc(schema.seasonMatches.scheduledAt),
+ asc(schema.seasonMatches.createdAt),
+ ],
+ with: {
+ participant1: true,
+ participant2: true,
+ winner: true,
+ subGames: { orderBy: [asc(schema.matchSubGames.gameNumber)] },
+ },
+ });
+}
+
+export async function findSeasonMatchById(matchId: string) {
+ const db = database();
+ return await db.query.seasonMatches.findFirst({
+ where: eq(schema.seasonMatches.id, matchId),
+ with: {
+ participant1: true,
+ participant2: true,
+ winner: true,
+ subGames: { orderBy: [asc(schema.matchSubGames.gameNumber)] },
+ },
+ });
+}
+
+export async function updateSeasonMatch(
+ matchId: string,
+ data: Partial<{
+ participant1Id: string | null;
+ participant2Id: string | null;
+ winnerId: string | null;
+ participant1Score: number | null;
+ participant2Score: number | null;
+ status: MatchStatus;
+ scheduledAt: Date | null;
+ startedAt: Date | null;
+ completedAt: Date | null;
+ }>
+): Promise {
+ const db = database();
+ const [result] = await db
+ .update(schema.seasonMatches)
+ .set({ ...data, updatedAt: new Date() })
+ .where(eq(schema.seasonMatches.id, matchId))
+ .returning();
+ return result;
+}
+
+export async function deleteSeasonMatch(matchId: string): Promise {
+ const db = database();
+ await db
+ .delete(schema.seasonMatches)
+ .where(eq(schema.seasonMatches.id, matchId));
+}
+
+export async function upsertMatchSubGame(
+ data: UpsertMatchSubGameData
+): Promise {
+ const db = database();
+ const now = new Date();
+ const [result] = await db
+ .insert(schema.matchSubGames)
+ .values({ ...data, updatedAt: now })
+ .onConflictDoUpdate({
+ target: [schema.matchSubGames.seasonMatchId, schema.matchSubGames.gameNumber],
+ set: {
+ gameLabel: sql`excluded.game_label`,
+ participant1Score: sql`excluded.participant1_score`,
+ participant2Score: sql`excluded.participant2_score`,
+ winnerId: sql`excluded.winner_id`,
+ status: sql`excluded.status`,
+ startedAt: sql`excluded.started_at`,
+ completedAt: sql`excluded.completed_at`,
+ externalGameId: sql`excluded.external_game_id`,
+ updatedAt: now,
+ },
+ })
+ .returning();
+ return result;
+}
+
+export async function findMatchSubGamesByMatchId(matchId: string): Promise {
+ const db = database();
+ return await db.query.matchSubGames.findMany({
+ where: eq(schema.matchSubGames.seasonMatchId, matchId),
+ orderBy: [asc(schema.matchSubGames.gameNumber)],
+ });
+}
diff --git a/app/routes.ts b/app/routes.ts
index 2ffa9a4..ad85920 100644
--- a/app/routes.ts
+++ b/app/routes.ts
@@ -70,6 +70,10 @@ export default [
route("how-to-play", "routes/how-to-play.tsx"),
route("rules", "routes/rules.tsx"),
route("sports", "routes/sports.tsx"),
+ route(
+ "sports-seasons/:sportsSeasonId/tournament",
+ "routes/sports-seasons.$sportsSeasonId.tournament.tsx"
+ ),
route("support", "routes/support.tsx"),
route("upcoming-events", "routes/upcoming-events.tsx"),
route("privacy-policy", "routes/privacy-policy.tsx"),
@@ -79,6 +83,7 @@ export default [
// Cron job endpoints
route("admin/jobs/run-daily-snapshots", "routes/admin/jobs.run-daily-snapshots.ts"),
route("admin/jobs/sync-and-simulate", "routes/admin/jobs.sync-and-simulate.ts"),
+ route("admin/jobs/sync-matches", "routes/admin/jobs.sync-matches.ts"),
// Admin routes
route("admin", "routes/admin.tsx", [
@@ -110,6 +115,10 @@ export default [
"sports-seasons/:id/events/:eventId/cs2-setup",
"routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx"
),
+ route(
+ "sports-seasons/:id/events/:eventId/swiss-matches",
+ "routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx"
+ ),
route(
"sports-seasons/:id/expected-values",
"routes/admin.sports-seasons.$id.expected-values.tsx"
diff --git a/app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts b/app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts
index 7a10943..1dab669 100644
--- a/app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts
+++ b/app/routes/admin.sports-seasons.$id.events.$eventId.bracket.server.ts
@@ -27,6 +27,7 @@ import {
processMatchResult,
recalculateAffectedLeagues,
recalculateStandings,
+ autoCompleteRoundIfDone,
} from "~/models/scoring-calculator";
import { updateProbabilitiesAfterResult } from "~/services/probability-updater";
import { getBracketTemplate, ALL_16_SEEDS, type BracketRegion } from "~/lib/bracket-templates";
@@ -211,39 +212,6 @@ export async function action({ request, params }: Route.ActionArgs) {
}
}
- /**
- * Auto-complete a round when every match in it is marked complete.
- * Updates scoringEvents.playoffRound and calls processPlayoffEvent so that
- * round placements are recorded and probabilities are refreshed.
- * This replaces the manual "Complete Round" button.
- *
- * skipRecalculate=true because the caller already sent a Discord notification
- * scoped to the current batch of matches — we don't want a second one that
- * would show all previously-completed matches in the event.
- */
- async function autoCompleteRoundIfDone(
- eventId: string,
- round: string,
- sportsSeasonId: string,
- db: ReturnType
- ): Promise {
- const allMatches = await findPlayoffMatchesByEventId(eventId);
- const roundMatches = allMatches.filter((m) => m.round === round);
- if (roundMatches.length === 0) return;
- const allDone = roundMatches.every((m) => m.isComplete);
- if (!allDone) return;
-
- await db
- .update(schema.scoringEvents)
- .set({ playoffRound: round, updatedAt: new Date() })
- .where(eq(schema.scoringEvents.id, eventId));
-
- // skipProbabilities=true: callers (set-winner / set-round-winners) already ran
- // updateProbabilitiesAfterResult before reaching here, so re-running would be wasted.
- await processPlayoffEvent(eventId, db, { skipRecalculate: true, skipProbabilities: true });
- logger.log(`[AutoComplete] Round "${round}" auto-completed for event ${eventId}`);
- }
-
if (intent === "set-winner") {
const matchId = formData.get("matchId");
const winnerId = formData.get("winnerId");
diff --git a/app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx b/app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx
index 9dec8fd..db4e759 100644
--- a/app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx
+++ b/app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx
@@ -1,4 +1,4 @@
-import { Form, useLoaderData, useActionData, useNavigation, Link } from 'react-router';
+import { Form, useLoaderData, useActionData, useNavigation, useFetcher, Link } from 'react-router';
import type { Route } from './+types/admin.sports-seasons.$id.events.$eventId.cs2-setup';
import { findSportsSeasonById } from '~/models/sports-season';
@@ -10,6 +10,8 @@ import {
markCs2StageEliminations,
clearCs2StageAssignments,
} from '~/models/cs2-major-stage';
+import { findSeasonMatchesByScoringEventId } from '~/models/season-match';
+import { syncMatches } from '~/services/match-sync';
import { Button } from '~/components/ui/button';
import {
Card,
@@ -19,7 +21,7 @@ import {
CardTitle,
} from '~/components/ui/card';
import { Badge } from '~/components/ui/badge';
-import { ArrowLeft, Save, Trash2, CheckCircle2 } from 'lucide-react';
+import { ArrowLeft, Save, Trash2, CheckCircle2, RefreshCw } from 'lucide-react';
import { useState } from 'react';
export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
@@ -38,12 +40,13 @@ export async function loader({ params }: Route.LoaderArgs) {
if (!sportsSeason) throw new Response('Sports season not found', { status: 404 });
if (!event) throw new Response('Event not found', { status: 404 });
- const [participants, stageResults] = await Promise.all([
+ const [participants, stageResults, seasonMatches] = await Promise.all([
findParticipantsBySportsSeasonId(sportsSeasonId),
getCs2StageResultsForEvent(eventId),
+ findSeasonMatchesByScoringEventId(eventId),
]);
- return { sportsSeason, event, participants, stageResults };
+ return { sportsSeason, event, participants, stageResults, seasonMatches };
}
interface ActionData {
@@ -98,6 +101,17 @@ export async function action({ request, params }: Route.ActionArgs) {
return { success: true, message: `Marked ${eliminations.length} eliminations.` };
}
+ if (intent === 'sync-matches') {
+ try {
+ const result = await syncMatches(params.id);
+ const total = result.swissCreated + result.swissUpdated;
+ const summary = `Synced: ${total} Swiss match(es), ${result.playoffUpdated} playoff match(es).`;
+ return { success: true, message: summary };
+ } catch (err) {
+ return { success: false, message: err instanceof Error ? err.message : 'Sync failed.' };
+ }
+ }
+
return { success: false, message: 'Unknown action.' };
}
@@ -113,11 +127,27 @@ const RECORD_OPTIONS = [
{ value: '0', label: '0-3 (earliest exit)' },
];
+const MATCH_STATUS_STYLES: Record = {
+ scheduled: 'text-muted-foreground',
+ in_progress: 'text-amber-400 font-medium',
+ complete: 'text-emerald-400',
+ canceled: 'text-destructive line-through',
+ postponed: 'text-muted-foreground italic',
+};
+
+const STAGE_NAMES: Record = {
+ 1: 'Opening Stage',
+ 2: 'Challengers Stage',
+ 3: 'Legends Stage',
+};
+
export default function AdminCs2Setup() {
- const { sportsSeason, event, participants, stageResults } = useLoaderData();
+ const { sportsSeason, event, participants, stageResults, seasonMatches } = useLoaderData();
const actionData = useActionData();
const navigation = useNavigation();
const isSubmitting = navigation.state === 'submitting';
+ const syncFetcher = useFetcher();
+ const isSyncing = syncFetcher.state !== 'idle';
// Stage assignment state (local, submitted via form)
const [stageSelections, setStageSelections] = useState>(() => {
@@ -313,6 +343,92 @@ export default function AdminCs2Setup() {
)}
+ {/* Swiss Rounds */}
+
+
+
+ Swiss Rounds
+
+
+
+
+ {isSyncing ? 'Syncing...' : 'Sync from API'}
+
+
+
+
+ {sportsSeason.externalSeasonId
+ ? `Syncing from external ID: ${sportsSeason.externalSeasonId}`
+ : 'Set an External Season ID on the sports season to enable API sync.'}
+
+
+
+ {seasonMatches.length === 0 ? (
+ No match data yet. Sync from the API or use the manual match entry page.
+ ) : (
+
+ {[1, 2, 3].map(stage => {
+ const stageMatches = seasonMatches.filter(m => m.matchStage === stage);
+ if (stageMatches.length === 0) return null;
+
+ // Group by round
+ const rounds = new Map
();
+ for (const m of stageMatches) {
+ const r = m.matchRound ?? 0;
+ let roundGroup = rounds.get(r);
+ if (!roundGroup) {
+ roundGroup = [];
+ rounds.set(r, roundGroup);
+ }
+ roundGroup.push(m);
+ }
+
+ return (
+
+
+ Stage {stage} — {STAGE_NAMES[stage] ?? ''}
+
+
+ {[...rounds.entries()].toSorted(([a], [b]) => a - b).map(([round, matches]) => (
+
+
+ Round {round}
+
+
+ {matches.map(m => (
+
+ {m.participant1?.name ?? '?'}
+
+ {m.status === 'complete' || m.status === 'in_progress'
+ ? `${m.participant1Score ?? '–'} – ${m.participant2Score ?? '–'}`
+ : 'vs'}
+
+ {m.participant2?.name ?? '?'}
+ {m.subGames.length > 0 && (
+
+ [{m.subGames.map(g => `${g.participant1Score}-${g.participant2Score}`).join(', ')}]
+
+ )}
+
+ ))}
+
+
+ ))}
+
+
+ );
+ })}
+
+ )}
+
+
+
{/* Champions Stage link */}
{stageResults.length > 0 && (
diff --git a/app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx b/app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx
new file mode 100644
index 0000000..7b13e2b
--- /dev/null
+++ b/app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx
@@ -0,0 +1,382 @@
+import { Form, useLoaderData, useActionData, useNavigation, Link } from 'react-router';
+import type { Route } from './+types/admin.sports-seasons.$id.events.$eventId.swiss-matches';
+
+import { findSportsSeasonById } from '~/models/sports-season';
+import { getScoringEventById } from '~/models/scoring-event';
+import { findParticipantsBySportsSeasonId } from '~/models/season-participant';
+import {
+ findSeasonMatchesByScoringEventId,
+ upsertSeasonMatch,
+ updateSeasonMatch,
+ deleteSeasonMatch,
+ upsertMatchSubGame,
+} from '~/models/season-match';
+import type { MatchStatus } from '~/models/season-match';
+import { Button } from '~/components/ui/button';
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from '~/components/ui/card';
+import { Badge } from '~/components/ui/badge';
+import { ArrowLeft, Plus, Save, Trash2 } from 'lucide-react';
+
+export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
+ return [{ title: `Swiss Matches — ${data?.event?.name ?? "Event"} - Brackt Admin` }];
+}
+
+export async function loader({ params }: Route.LoaderArgs) {
+ const sportsSeasonId = params.id;
+ const eventId = params.eventId;
+
+ const [sportsSeason, event] = await Promise.all([
+ findSportsSeasonById(sportsSeasonId),
+ getScoringEventById(eventId),
+ ]);
+
+ if (!sportsSeason) throw new Response('Sports season not found', { status: 404 });
+ if (!event) throw new Response('Event not found', { status: 404 });
+
+ const [participants, matches] = await Promise.all([
+ findParticipantsBySportsSeasonId(sportsSeasonId),
+ findSeasonMatchesByScoringEventId(eventId),
+ ]);
+
+ return { sportsSeason, event, participants, matches };
+}
+
+interface ActionData {
+ success?: boolean;
+ message?: string;
+}
+
+export async function action({ request, params }: Route.ActionArgs) {
+ const eventId = params.eventId;
+ const sportsSeasonId = params.id;
+ const formData = await request.formData();
+ const intent = formData.get('intent') as string;
+
+ if (intent === 'create-match') {
+ const participant1Id = formData.get('participant1Id') as string;
+ const participant2Id = formData.get('participant2Id') as string;
+ const matchStage = parseInt(formData.get('matchStage') as string, 10);
+ const matchRound = parseInt(formData.get('matchRound') as string, 10);
+ const isSeries = formData.get('isSeries') === 'true';
+
+ if (!participant1Id || !participant2Id || isNaN(matchStage) || isNaN(matchRound)) {
+ return { success: false, message: 'Missing required fields.' };
+ }
+
+ const externalMatchId = `manual_${eventId}_s${matchStage}_r${matchRound}_${participant1Id}_${participant2Id}`;
+ await upsertSeasonMatch({
+ sportsSeasonId,
+ scoringEventId: eventId,
+ participant1Id,
+ participant2Id,
+ matchStage,
+ matchRound,
+ isSeries,
+ status: 'scheduled',
+ externalMatchId,
+ });
+ return { success: true, message: 'Match created.' };
+ }
+
+ if (intent === 'update-result') {
+ const matchId = formData.get('matchId') as string;
+ const participant1Score = formData.get('participant1Score');
+ const participant2Score = formData.get('participant2Score');
+ const winnerId = formData.get('winnerId') as string | null;
+ const status = formData.get('status') as MatchStatus;
+
+ const p1Score = participant1Score ? parseInt(participant1Score as string, 10) : null;
+ const p2Score = participant2Score ? parseInt(participant2Score as string, 10) : null;
+
+ await updateSeasonMatch(matchId, {
+ participant1Score: p1Score,
+ participant2Score: p2Score,
+ winnerId: winnerId || null,
+ status,
+ completedAt: status === 'complete' ? new Date() : null,
+ });
+
+ // Handle sub-games (maps) if provided
+ const mapCount = parseInt(formData.get('mapCount') as string ?? '0', 10);
+ for (let i = 1; i <= mapCount; i++) {
+ const mapLabel = formData.get(`map${i}_label`) as string | null;
+ const map1Score = formData.get(`map${i}_p1`) as string | null;
+ const map2Score = formData.get(`map${i}_p2`) as string | null;
+ if (map1Score !== null && map2Score !== null) {
+ await upsertMatchSubGame({
+ seasonMatchId: matchId,
+ gameNumber: i,
+ gameLabel: mapLabel || null,
+ participant1Score: parseInt(map1Score, 10),
+ participant2Score: parseInt(map2Score, 10),
+ status: 'complete',
+ });
+ }
+ }
+
+ return { success: true, message: 'Result saved.' };
+ }
+
+ if (intent === 'delete-match') {
+ const matchId = formData.get('matchId') as string;
+ await deleteSeasonMatch(matchId);
+ return { success: true, message: 'Match deleted.' };
+ }
+
+ return { success: false, message: 'Unknown action.' };
+}
+
+const STAGE_NAMES: Record = {
+ 1: 'Opening Stage',
+ 2: 'Challengers Stage',
+ 3: 'Legends Stage',
+};
+
+const STATUS_BADGE: Record = {
+ scheduled: { label: 'Scheduled', variant: 'outline' },
+ in_progress: { label: 'Live', variant: 'default' },
+ complete: { label: 'Complete', variant: 'secondary' },
+ canceled: { label: 'Canceled', variant: 'destructive' },
+ postponed: { label: 'Postponed', variant: 'outline' },
+};
+
+export default function AdminSwissMatches() {
+ const { sportsSeason, event, participants, matches } = useLoaderData();
+ const actionData = useActionData();
+ const navigation = useNavigation();
+ const isSubmitting = navigation.state === 'submitting';
+
+ // Group matches by stage → round
+ const byStage = new Map>();
+ for (const m of matches) {
+ const stage = m.matchStage ?? 0;
+ const round = m.matchRound ?? 0;
+ let stageMap = byStage.get(stage);
+ if (!stageMap) {
+ stageMap = new Map();
+ byStage.set(stage, stageMap);
+ }
+ let roundList = stageMap.get(round);
+ if (!roundList) {
+ roundList = [];
+ stageMap.set(round, roundList);
+ }
+ roundList.push(m);
+ }
+
+ return (
+
+
+
+
+ Back to CS2 Setup
+
+
Swiss Match Entry
+
{event.name} — {sportsSeason.name}
+
+
+ {actionData?.message && (
+
+ {actionData.message}
+
+ )}
+
+ {/* Create new match */}
+
+
+ Add Match
+ Manually add a Swiss round match.
+
+
+
+
+
+
+ {/* Existing matches grouped by stage/round */}
+ {matches.length === 0 ? (
+
No matches yet.
+ ) : (
+ [...byStage.entries()].toSorted(([a], [b]) => a - b).map(([stage, rounds]) => (
+
+
+ Stage {stage} — {STAGE_NAMES[stage] ?? ''}
+
+
+ {[...rounds.entries()].toSorted(([a], [b]) => a - b).map(([round, roundMatches]) => (
+
+
Round {round}
+
+ {roundMatches.map(match => (
+
+
+
+ {match.participant1?.name ?? '?'} vs {match.participant2?.name ?? '?'}
+
+
+
+ {STATUS_BADGE[match.status]?.label ?? match.status}
+
+
+
+
+
+
+ ))}
+
+
+ ))}
+
+
+ ))
+ )}
+
+ );
+}
diff --git a/app/routes/admin.sports-seasons.$id.tsx b/app/routes/admin.sports-seasons.$id.tsx
index 0eedb49..cf056e8 100644
--- a/app/routes/admin.sports-seasons.$id.tsx
+++ b/app/routes/admin.sports-seasons.$id.tsx
@@ -315,6 +315,7 @@ export async function action(args: Route.ActionArgs) {
const totalMajors = formData.get("totalMajors");
const draftOn = formData.get("draftOn");
const draftOff = formData.get("draftOff");
+ const externalSeasonId = formData.get("externalSeasonId");
// Validation
if (typeof name !== "string" || !name.trim()) {
@@ -378,6 +379,10 @@ export async function action(args: Route.ActionArgs) {
}
}
+ updateData.externalSeasonId = typeof externalSeasonId === "string" && externalSeasonId.trim()
+ ? externalSeasonId.trim()
+ : null;
+
await updateSportsSeason(params.id, updateData);
return { success: true, message: "Sports season updated successfully!" };
@@ -566,6 +571,20 @@ export default function EditSportsSeason({ loaderData, actionData }: Route.Compo
This season appears in league creation and pre-draft settings only between these two dates (inclusive).
+
+
External Season ID (Optional)
+
+
+ Used by the match sync cron job. For CS2: PandaScore serie_id. For MLB/NBA: year (e.g., 2025).
+
+
+
{actionData?.error && (
{actionData.error}
diff --git a/app/routes/admin.sports-seasons.new.tsx b/app/routes/admin.sports-seasons.new.tsx
index 15a7cce..854fca5 100644
--- a/app/routes/admin.sports-seasons.new.tsx
+++ b/app/routes/admin.sports-seasons.new.tsx
@@ -40,6 +40,7 @@ export async function action({ request }: Route.ActionArgs) {
const totalMajors = formData.get("totalMajors");
const draftOn = formData.get("draftOn");
const draftOff = formData.get("draftOff");
+ const externalSeasonId = formData.get("externalSeasonId");
// Validation
if (typeof sportId !== "string" || !sportId) {
@@ -108,6 +109,10 @@ export async function action({ request }: Route.ActionArgs) {
}
}
+ if (typeof externalSeasonId === "string" && externalSeasonId.trim()) {
+ seasonData.externalSeasonId = externalSeasonId.trim();
+ }
+
await createSportsSeason(seasonData as NewSportsSeason);
return redirect("/admin/sports-seasons");
@@ -261,6 +266,19 @@ export default function NewSportsSeason({ loaderData, actionData }: Route.Compon
)}
+
+
External Season ID (Optional)
+
+
+ Used by the match sync cron job. For CS2: PandaScore serie_id. For MLB/NBA: year (e.g., 2025).
+
+
+
Draft Open Date
diff --git a/app/routes/admin/jobs.sync-matches.ts b/app/routes/admin/jobs.sync-matches.ts
new file mode 100644
index 0000000..23c7870
--- /dev/null
+++ b/app/routes/admin/jobs.sync-matches.ts
@@ -0,0 +1,41 @@
+import { and, eq, isNotNull } from "drizzle-orm";
+import { database } from "~/database/context";
+import * as schema from "~/database/schema";
+import { requireCronSecret } from "~/lib/cron-auth";
+import { syncMatches } from "~/services/match-sync";
+
+export async function action({ request }: { request: Request }) {
+ requireCronSecret(request);
+
+ const db = database();
+ const seasons = await db.query.sportsSeasons.findMany({
+ where: and(
+ isNotNull(schema.sportsSeasons.externalSeasonId),
+ eq(schema.sportsSeasons.status, "active")
+ ),
+ with: { sport: true },
+ });
+
+ const synced: string[] = [];
+ const errors: { id: string; name: string; error: string }[] = [];
+
+ for (const season of seasons) {
+ try {
+ const result = await syncMatches(season.id);
+ synced.push(season.id);
+ if (result.errors.length > 0) {
+ for (const e of result.errors) {
+ errors.push({ id: season.id, name: season.name, error: e.error });
+ }
+ }
+ } catch (err) {
+ errors.push({
+ id: season.id,
+ name: season.name,
+ error: err instanceof Error ? err.message : String(err),
+ });
+ }
+ }
+
+ return Response.json({ synced, errors }, { status: errors.length > 0 && synced.length === 0 ? 500 : 200 });
+}
diff --git a/app/routes/sports-seasons.$sportsSeasonId.tournament.tsx b/app/routes/sports-seasons.$sportsSeasonId.tournament.tsx
new file mode 100644
index 0000000..9f589be
--- /dev/null
+++ b/app/routes/sports-seasons.$sportsSeasonId.tournament.tsx
@@ -0,0 +1,135 @@
+import { useEffect } from "react";
+import { Link, useRevalidator } from "react-router";
+import { eq, inArray } from "drizzle-orm";
+import type { Route } from "./+types/sports-seasons.$sportsSeasonId.tournament";
+
+import { database } from "~/database/context";
+import * as schema from "~/database/schema";
+import { type PlayoffMatch } from "~/models/playoff-match";
+import { findSeasonMatchesBySportsSeasonId } from "~/models/season-match";
+import { getBracketTemplate, getOrderedRoundsFromMatches } from "~/lib/bracket-templates";
+import { Cs2TournamentBracket } from "~/components/scoring/Cs2TournamentBracket";
+import { MatchSchedule } from "~/components/scoring/MatchSchedule";
+import { ArrowLeft } from "lucide-react";
+
+export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
+ return [{ title: `${data?.sportsSeason?.name ?? "Tournament"} — Schedule & Results` }];
+}
+
+export async function loader({ params }: Route.LoaderArgs) {
+ const { sportsSeasonId } = params;
+ const db = database();
+
+ const sportsSeason = await db.query.sportsSeasons.findFirst({
+ where: eq(schema.sportsSeasons.id, sportsSeasonId),
+ with: { sport: true },
+ });
+
+ if (!sportsSeason) throw new Response("Sports season not found", { status: 404 });
+
+ const simulatorType = sportsSeason.sport?.simulatorType ?? null;
+
+ const seasonMatches = await findSeasonMatchesBySportsSeasonId(sportsSeasonId);
+
+ // Load playoff matches for bracket sports
+ let playoffMatches: (PlayoffMatch & { participant1: { id: string; name: string } | null; participant2: { id: string; name: string } | null; winner: { id: string; name: string } | null; loser: { id: string; name: string } | null; })[] = [];
+ let playoffRounds: string[] = [];
+ let bracketTemplateId: string | null = null;
+
+ if (simulatorType?.endsWith("_bracket") || simulatorType === "cs2_major_qualifying_points") {
+ const events = await db.query.scoringEvents.findMany({
+ where: eq(schema.scoringEvents.sportsSeasonId, sportsSeasonId),
+ });
+
+ if (events.length > 0) {
+ const eventIds = events.map((e) => e.id);
+ const matches = await db.query.playoffMatches.findMany({
+ where: (pm) => inArray(pm.scoringEventId, eventIds),
+ with: {
+ participant1: true,
+ participant2: true,
+ winner: true,
+ loser: true,
+ },
+ });
+ playoffMatches = matches as typeof playoffMatches;
+
+ const templateId = events.find((e) => e.bracketTemplateId)?.bracketTemplateId ?? undefined;
+ bracketTemplateId = templateId ?? null;
+ const template = templateId ? getBracketTemplate(templateId) : undefined;
+ playoffRounds = getOrderedRoundsFromMatches(matches, template);
+ }
+ }
+
+ const hasLiveMatches =
+ seasonMatches.some((m) => m.status === "in_progress") ||
+ playoffMatches.some((m) => !m.isComplete && (m.participant1Id !== null || m.participant2Id !== null));
+
+ return {
+ sportsSeason,
+ simulatorType,
+ seasonMatches,
+ playoffMatches,
+ playoffRounds,
+ bracketTemplateId,
+ hasLiveMatches,
+ };
+}
+
+export default function TournamentPage({ loaderData }: Route.ComponentProps) {
+ const {
+ sportsSeason,
+ simulatorType,
+ seasonMatches,
+ playoffMatches,
+ playoffRounds,
+ bracketTemplateId,
+ hasLiveMatches,
+ } = loaderData;
+
+ const { revalidate } = useRevalidator();
+
+ // Poll every 30 seconds when any match is live
+ useEffect(() => {
+ if (!hasLiveMatches) return;
+ const interval = setInterval(() => revalidate(), 30_000);
+ return () => clearInterval(interval);
+ }, [hasLiveMatches, revalidate]);
+
+ const isCs2 = simulatorType === "cs2_major_qualifying_points";
+
+ return (
+
+
+
+
+ Back
+
+
{sportsSeason.name}
+ {sportsSeason.sport && (
+
{sportsSeason.sport.name}
+ )}
+ {hasLiveMatches && (
+
+
+ Live — updating every 30 seconds
+
+ )}
+
+
+ {isCs2 ? (
+
[0]["swissMatches"]}
+ playoffMatches={playoffMatches as Parameters[0]["playoffMatches"]}
+ playoffRounds={playoffRounds}
+ bracketTemplateId={bracketTemplateId}
+ />
+ ) : (
+ [0]["matches"]} />
+ )}
+
+ );
+}
diff --git a/app/services/match-sync/__tests__/espn-schedule.test.ts b/app/services/match-sync/__tests__/espn-schedule.test.ts
new file mode 100644
index 0000000..034159d
--- /dev/null
+++ b/app/services/match-sync/__tests__/espn-schedule.test.ts
@@ -0,0 +1,236 @@
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+import { EspnScheduleAdapter } from "../espn-schedule";
+
+const SAMPLE_RESPONSE = {
+ events: [
+ {
+ id: "401234567",
+ date: "2025-04-01T18:00:00Z",
+ competitions: [
+ {
+ competitors: [
+ {
+ id: "9",
+ team: { id: "9", displayName: "Boston Red Sox" },
+ score: "5",
+ homeAway: "home" as const,
+ winner: true,
+ },
+ {
+ id: "4",
+ team: { id: "4", displayName: "New York Yankees" },
+ score: "3",
+ homeAway: "away" as const,
+ winner: false,
+ },
+ ],
+ status: { type: { name: "STATUS_FINAL", completed: true } },
+ matchday: null,
+ },
+ ],
+ },
+ {
+ id: "401234568",
+ date: "2025-04-02T19:00:00Z",
+ competitions: [
+ {
+ competitors: [
+ {
+ id: "12",
+ team: { id: "12", displayName: "Los Angeles Dodgers" },
+ score: "0",
+ homeAway: "home" as const,
+ winner: false,
+ },
+ {
+ id: "15",
+ team: { id: "15", displayName: "San Francisco Giants" },
+ score: "0",
+ homeAway: "away" as const,
+ winner: false,
+ },
+ ],
+ status: { type: { name: "STATUS_SCHEDULED", completed: false } },
+ matchday: null,
+ },
+ ],
+ },
+ ],
+};
+
+describe("EspnScheduleAdapter", () => {
+ beforeEach(() => {
+ vi.stubGlobal("fetch", vi.fn());
+ });
+
+ afterEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it("maps completed matches with scores and winner", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: true,
+ json: async () => SAMPLE_RESPONSE,
+ } as Response);
+
+ const adapter = new EspnScheduleAdapter("baseball/mlb");
+ const matches = await adapter.fetchMatches("2025");
+
+ expect(matches).toHaveLength(2);
+ const completed = matches[0];
+ expect(completed.externalMatchId).toBe("401234567");
+ expect(completed.team1ExternalId).toBe("9");
+ expect(completed.team1Name).toBe("Boston Red Sox");
+ expect(completed.team2ExternalId).toBe("4");
+ expect(completed.team2Name).toBe("New York Yankees");
+ expect(completed.team1Score).toBe(5);
+ expect(completed.team2Score).toBe(3);
+ expect(completed.winnerExternalId).toBe("9");
+ expect(completed.status).toBe("complete");
+ expect(completed.completedAt).toBeInstanceOf(Date);
+ });
+
+ it("maps scheduled matches with null scores", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: true,
+ json: async () => SAMPLE_RESPONSE,
+ } as Response);
+
+ const [, scheduled] = await new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025");
+ expect(scheduled.status).toBe("scheduled");
+ expect(scheduled.winnerExternalId).toBeNull();
+ expect(scheduled.completedAt).toBeNull();
+ expect(scheduled.startedAt).toBeNull();
+ });
+
+ it("sets matchStage to null for all ESPN matches", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: true,
+ json: async () => SAMPLE_RESPONSE,
+ } as Response);
+
+ const matches = await new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025");
+ for (const m of matches) {
+ expect(m.matchStage).toBeNull();
+ }
+ });
+
+ it("builds correct ESPN URL with sport path and dates param", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: true,
+ json: async () => ({ events: [] }),
+ } as Response);
+
+ await new EspnScheduleAdapter("basketball/nba").fetchMatches("2025");
+
+ expect(fetch).toHaveBeenCalledWith(
+ expect.stringContaining("basketball/nba")
+ );
+ expect(fetch).toHaveBeenCalledWith(
+ expect.stringContaining("dates=2025")
+ );
+ });
+
+ it("throws on non-ok API response", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: false,
+ status: 429,
+ text: async () => "Too Many Requests",
+ } as Response);
+
+ await expect(new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025")).rejects.toThrow(
+ "ESPN API error 429"
+ );
+ });
+
+ it("handles in-progress matches", async () => {
+ const response = {
+ events: [
+ {
+ id: "999",
+ date: "2025-04-03T20:00:00Z",
+ competitions: [
+ {
+ competitors: [
+ { id: "1", team: { id: "1", displayName: "Home Team" }, score: "2", homeAway: "home" as const },
+ { id: "2", team: { id: "2", displayName: "Away Team" }, score: "1", homeAway: "away" as const },
+ ],
+ status: { type: { name: "STATUS_IN_PROGRESS", completed: false } },
+ },
+ ],
+ },
+ ],
+ };
+ vi.mocked(fetch).mockResolvedValueOnce({ ok: true, json: async () => response } as Response);
+
+ const [m] = await new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025");
+ expect(m.status).toBe("in_progress");
+ expect(m.startedAt).toBeInstanceOf(Date);
+ expect(m.completedAt).toBeNull();
+ });
+
+ it("preserves score of 0 — does not coerce falsy string to null", async () => {
+ const response = {
+ events: [
+ {
+ id: "777",
+ date: "2025-04-05T18:00:00Z",
+ competitions: [
+ {
+ competitors: [
+ { id: "10", team: { id: "10", displayName: "Team A" }, score: "0", homeAway: "home" as const, winner: false },
+ { id: "11", team: { id: "11", displayName: "Team B" }, score: "3", homeAway: "away" as const, winner: true },
+ ],
+ status: { type: { name: "STATUS_FINAL", completed: true } },
+ matchday: null,
+ },
+ ],
+ },
+ ],
+ };
+ vi.mocked(fetch).mockResolvedValueOnce({ ok: true, json: async () => response } as Response);
+
+ const [m] = await new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025");
+ expect(m.team1Score).toBe(0);
+ expect(m.team2Score).toBe(3);
+ });
+
+ it("returns null (not NaN) for non-numeric score strings", async () => {
+ const response = {
+ events: [
+ {
+ id: "778",
+ date: "2025-04-06T18:00:00Z",
+ competitions: [
+ {
+ competitors: [
+ { id: "10", team: { id: "10", displayName: "Team A" }, score: "F/OT", homeAway: "home" as const, winner: true },
+ { id: "11", team: { id: "11", displayName: "Team B" }, score: "TBD", homeAway: "away" as const, winner: false },
+ ],
+ status: { type: { name: "STATUS_FINAL", completed: true } },
+ matchday: null,
+ },
+ ],
+ },
+ ],
+ };
+ vi.mocked(fetch).mockResolvedValueOnce({ ok: true, json: async () => response } as Response);
+
+ const [m] = await new EspnScheduleAdapter("baseball/mlb").fetchMatches("2025");
+ expect(m.team1Score).toBeNull();
+ expect(m.team2Score).toBeNull();
+ });
+
+ it("appends seasontype param to URL when seasonType is provided", async () => {
+ vi.mocked(fetch).mockResolvedValueOnce({
+ ok: true,
+ json: async () => ({ events: [] }),
+ } as Response);
+
+ await new EspnScheduleAdapter("baseball/mlb", 3).fetchMatches("2025");
+
+ expect(fetch).toHaveBeenCalledWith(
+ expect.stringContaining("seasontype=3")
+ );
+ });
+});
diff --git a/app/services/match-sync/__tests__/pandascore.test.ts b/app/services/match-sync/__tests__/pandascore.test.ts
new file mode 100644
index 0000000..d95cee4
--- /dev/null
+++ b/app/services/match-sync/__tests__/pandascore.test.ts
@@ -0,0 +1,163 @@
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+import { PandaScoreMatchSyncAdapter } from "../pandascore";
+
+const SAMPLE_MATCH = {
+ id: 42,
+ name: "Team A vs Team B",
+ status: "finished",
+ scheduled_at: "2025-03-15T14:00:00Z",
+ begin_at: "2025-03-15T14:05:00Z",
+ end_at: "2025-03-15T15:30:00Z",
+ number_of_games: 3,
+ opponents: [
+ { opponent: { id: 1, name: "Team A" }, type: "Team" },
+ { opponent: { id: 2, name: "Team B" }, type: "Team" },
+ ],
+ results: [
+ { team_id: 1, score: 2 },
+ { team_id: 2, score: 1 },
+ ],
+ winner: { id: 1, name: "Team A" },
+ winner_id: 1,
+ games: [
+ {
+ id: 100,
+ position: 1,
+ map: { name: "Mirage" },
+ winner: { id: 1 },
+ teams: [
+ { team: { id: 1 }, score: 16 },
+ { team: { id: 2 }, score: 14 },
+ ],
+ status: "finished",
+ },
+ {
+ id: 101,
+ position: 2,
+ map: { name: "Inferno" },
+ winner: { id: 2 },
+ teams: [
+ { team: { id: 1 }, score: 12 },
+ { team: { id: 2 }, score: 16 },
+ ],
+ status: "finished",
+ },
+ {
+ id: 102,
+ position: 3,
+ map: { name: "Nuke" },
+ winner: { id: 1 },
+ teams: [
+ { team: { id: 1 }, score: 16 },
+ { team: { id: 2 }, score: 10 },
+ ],
+ status: "finished",
+ },
+ ],
+ tournament: { id: 200, name: "Opening Stage" },
+};
+
+describe("PandaScoreMatchSyncAdapter", () => {
+ beforeEach(() => {
+ vi.stubGlobal("fetch", vi.fn());
+ process.env.PANDASCORE_API_KEY = "test-key";
+ });
+
+ afterEach(() => {
+ vi.restoreAllMocks();
+ delete process.env.PANDASCORE_API_KEY;
+ });
+
+ it("maps a finished match to MatchRecord", async () => {
+ vi.mocked(fetch)
+ .mockResolvedValueOnce({ ok: true, json: async () => [SAMPLE_MATCH] } as Response)
+ .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response);
+
+ const adapter = new PandaScoreMatchSyncAdapter();
+ const matches = await adapter.fetchMatches("9999");
+
+ expect(matches).toHaveLength(1);
+ const m = matches[0];
+ expect(m.externalMatchId).toBe("42");
+ expect(m.team1ExternalId).toBe("1");
+ expect(m.team1Name).toBe("Team A");
+ expect(m.team2ExternalId).toBe("2");
+ expect(m.team2Name).toBe("Team B");
+ expect(m.team1Score).toBe(2);
+ expect(m.team2Score).toBe(1);
+ expect(m.winnerExternalId).toBe("1");
+ expect(m.status).toBe("complete");
+ expect(m.isSeries).toBe(true);
+ });
+
+ it("maps tournament name to matchStage", async () => {
+ const openingMatch = { ...SAMPLE_MATCH, tournament: { id: 1, name: "Opening Stage" } };
+ const challengersMatch = { ...SAMPLE_MATCH, id: 43, tournament: { id: 2, name: "Challengers Stage" } };
+ const legendsMatch = { ...SAMPLE_MATCH, id: 44, tournament: { id: 3, name: "Legends Stage" } };
+
+ vi.mocked(fetch)
+ .mockResolvedValueOnce({
+ ok: true,
+ json: async () => [openingMatch, challengersMatch, legendsMatch],
+ } as Response)
+ .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response);
+
+ const matches = await new PandaScoreMatchSyncAdapter().fetchMatches("9999");
+ expect(matches[0].matchStage).toBe(1);
+ expect(matches[1].matchStage).toBe(2);
+ expect(matches[2].matchStage).toBe(3);
+ });
+
+ it("includes sub-games with map labels and scores", async () => {
+ vi.mocked(fetch)
+ .mockResolvedValueOnce({ ok: true, json: async () => [SAMPLE_MATCH] } as Response)
+ .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response);
+
+ const [m] = await new PandaScoreMatchSyncAdapter().fetchMatches("9999");
+ expect(m.subGames).toHaveLength(3);
+
+ const subGames = m.subGames ?? [];
+ expect(subGames[0].gameNumber).toBe(1);
+ expect(subGames[0].gameLabel).toBe("Mirage");
+ expect(subGames[0].team1Score).toBe(16);
+ expect(subGames[0].team2Score).toBe(14);
+ expect(subGames[0].winnerExternalId).toBe("1");
+ expect(subGames[0].status).toBe("complete");
+
+ expect(subGames[1].gameLabel).toBe("Inferno");
+ expect(subGames[1].winnerExternalId).toBe("2");
+ });
+
+ it("maps status values correctly", async () => {
+ const inProgressMatch = { ...SAMPLE_MATCH, id: 50, status: "running", winner_id: null, winner: null, end_at: undefined };
+ vi.mocked(fetch)
+ .mockResolvedValueOnce({ ok: true, json: async () => [inProgressMatch] } as Response)
+ .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response);
+
+ const [m] = await new PandaScoreMatchSyncAdapter().fetchMatches("9999");
+ expect(m.status).toBe("in_progress");
+ expect(m.winnerExternalId).toBeNull();
+ });
+
+ it("throws when PANDASCORE_API_KEY is not set", async () => {
+ delete process.env.PANDASCORE_API_KEY;
+ await expect(new PandaScoreMatchSyncAdapter().fetchMatches("9999")).rejects.toThrow(
+ "PANDASCORE_API_KEY"
+ );
+ });
+
+ it("paginates until an empty page", async () => {
+ const page1 = Array.from({ length: 100 }, (_, i) => ({
+ ...SAMPLE_MATCH,
+ id: i + 1,
+ games: [],
+ }));
+ vi.mocked(fetch)
+ .mockResolvedValueOnce({ ok: true, json: async () => page1 } as Response)
+ .mockResolvedValueOnce({ ok: true, json: async () => [] } as Response);
+
+ const matches = await new PandaScoreMatchSyncAdapter().fetchMatches("9999");
+ expect(matches).toHaveLength(100);
+ expect(fetch).toHaveBeenCalledTimes(2);
+ });
+});
diff --git a/app/services/match-sync/espn-schedule.ts b/app/services/match-sync/espn-schedule.ts
new file mode 100644
index 0000000..cfef8ec
--- /dev/null
+++ b/app/services/match-sync/espn-schedule.ts
@@ -0,0 +1,96 @@
+import type { MatchRecord, MatchSyncAdapter, MatchStatusValue } from "./types";
+
+interface EspnCompetitor {
+ id: string;
+ team: { id: string; displayName: string; abbreviation?: string };
+ score?: string;
+ homeAway?: "home" | "away";
+ winner?: boolean;
+}
+interface EspnEvent {
+ id: string;
+ date: string;
+ competitions?: Array<{
+ competitors?: EspnCompetitor[];
+ status?: { type?: { name?: string; completed?: boolean; description?: string } };
+ matchday?: number;
+ }>;
+}
+interface EspnScheduleResponse {
+ events?: EspnEvent[];
+}
+
+function mapStatus(name: string | undefined, completed: boolean | undefined): MatchStatusValue {
+ if (completed) return "complete";
+ if (name === "STATUS_IN_PROGRESS" || name === "in_progress") return "in_progress";
+ if (name === "STATUS_CANCELED" || name === "canceled") return "canceled";
+ if (name === "STATUS_POSTPONED" || name === "postponed") return "postponed";
+ return "scheduled";
+}
+
+function parseScore(s: string | undefined): number | null {
+ if (s === undefined || s === "") return null;
+ const n = parseInt(s, 10);
+ return Number.isFinite(n) ? n : null;
+}
+
+export class EspnScheduleAdapter implements MatchSyncAdapter {
+ readonly supportsLiveScores = false;
+
+ // sport: e.g. "baseball/mlb", "basketball/nba"
+ // seasonType: ESPN season type (1=preseason, 2=regular, 3=postseason). Pass 3 for bracket sports
+ // to avoid the scoreboard limit silently truncating regular-season games.
+ constructor(private readonly sport: string, private readonly seasonType?: number) {}
+
+ // externalSeasonId is "YYYY" year string for ESPN sports
+ async fetchMatches(externalSeasonId: string): Promise
{
+ const seasonTypeParam = this.seasonType !== undefined ? `&seasontype=${this.seasonType}` : "";
+ const url = `https://site.api.espn.com/apis/site/v2/sports/${this.sport}/scoreboard?limit=1000&dates=${externalSeasonId}${seasonTypeParam}`;
+ const resp = await fetch(url);
+ if (!resp.ok) {
+ const body = await resp.text();
+ throw new Error(`ESPN API error ${resp.status}: ${body}`);
+ }
+
+ const data = (await resp.json()) as EspnScheduleResponse;
+ const matches: MatchRecord[] = [];
+
+ for (const event of data.events ?? []) {
+ const comp = event.competitions?.[0];
+ if (!comp) continue;
+
+ const competitors = comp.competitors ?? [];
+ const home = competitors.find((c) => c.homeAway === "home") ?? competitors[0];
+ const away = competitors.find((c) => c.homeAway === "away") ?? competitors[1];
+ if (!home || !away) continue;
+
+ const statusType = comp.status?.type;
+ const status = mapStatus(statusType?.name, statusType?.completed);
+
+ const homeScore = parseScore(home.score);
+ const awayScore = parseScore(away.score);
+ const winnerExternalId = home.winner ? home.team.id : away.winner ? away.team.id : null;
+
+ matches.push({
+ externalMatchId: event.id,
+ team1ExternalId: home.team.id,
+ team1Name: home.team.displayName,
+ team2ExternalId: away.team.id,
+ team2Name: away.team.displayName,
+ team1Score: homeScore,
+ team2Score: awayScore,
+ winnerExternalId,
+ status,
+ scheduledAt: new Date(event.date),
+ startedAt: status !== "scheduled" ? new Date(event.date) : null,
+ completedAt: status === "complete" ? new Date(event.date) : null,
+ matchStage: null,
+ matchRound: null,
+ matchday: comp.matchday ?? null,
+ isSeries: false,
+ });
+ }
+
+ return matches;
+ }
+}
diff --git a/app/services/match-sync/index.ts b/app/services/match-sync/index.ts
new file mode 100644
index 0000000..8435753
--- /dev/null
+++ b/app/services/match-sync/index.ts
@@ -0,0 +1,271 @@
+import { database } from "~/database/context";
+import { eq } from "drizzle-orm";
+import * as schema from "~/database/schema";
+import { findParticipantsBySportsSeasonId, updateParticipant } from "~/models/season-participant";
+import { upsertSeasonMatchBulk, upsertMatchSubGame } from "~/models/season-match";
+import { setMatchWinner, updatePlayoffMatch, advanceWinnerTemplate, findPlayoffMatchesByEventId, doesLoserAdvance } from "~/models/playoff-match";
+import { processMatchResult, autoCompleteRoundIfDone } from "~/models/scoring-calculator";
+import { findMatchingTeamName } from "~/lib/normalize-team-name";
+import { getBracketTemplate } from "~/lib/bracket-templates";
+import { PandaScoreMatchSyncAdapter } from "./pandascore";
+import { EspnScheduleAdapter } from "./espn-schedule";
+import type { MatchSyncAdapter, MatchSyncResult } from "./types";
+import { logger } from "~/lib/logger";
+
+function getMatchSyncAdapter(simulatorType: string): MatchSyncAdapter {
+ switch (simulatorType) {
+ case "cs2_major_qualifying_points":
+ return new PandaScoreMatchSyncAdapter();
+ case "mlb_bracket":
+ return new EspnScheduleAdapter("baseball/mlb", 3);
+ case "nba_bracket":
+ return new EspnScheduleAdapter("basketball/nba", 3);
+ case "mls_bracket":
+ return new EspnScheduleAdapter("soccer/mls", 3);
+ case "wnba_bracket":
+ return new EspnScheduleAdapter("basketball/wnba", 3);
+ case "nhl_bracket":
+ return new EspnScheduleAdapter("hockey/nhl", 3);
+ default:
+ throw new Error(
+ `No match sync adapter available for simulator type "${simulatorType}". ` +
+ "CS2, MLB, NBA, MLS, WNBA, and NHL are currently supported."
+ );
+ }
+}
+
+export async function syncMatches(sportsSeasonId: string): Promise {
+ const db = database();
+
+ const sportsSeason = await db.query.sportsSeasons.findFirst({
+ where: eq(schema.sportsSeasons.id, sportsSeasonId),
+ with: { sport: true },
+ });
+
+ if (!sportsSeason) throw new Error(`Sports season ${sportsSeasonId} not found`);
+
+ const externalSeasonId = sportsSeason.externalSeasonId;
+ if (!externalSeasonId) {
+ throw new Error(`Sports season "${sportsSeason.name}" has no externalSeasonId configured`);
+ }
+
+ const simulatorType = sportsSeason.sport?.simulatorType;
+ if (!simulatorType) {
+ throw new Error(`Sport "${sportsSeason.sport?.name ?? "(none)"}" has no simulator type configured`);
+ }
+
+ const adapter = getMatchSyncAdapter(simulatorType);
+ const fetchedMatches = await adapter.fetchMatches(externalSeasonId);
+
+ // Load participants, build lookup maps
+ const participants = await findParticipantsBySportsSeasonId(sportsSeasonId);
+ const participantNames = participants.map((p) => p.name);
+ const participantByExternalId = new Map(
+ participants.filter((p) => p.externalId).map((p) => [p.externalId as string, p])
+ );
+ const participantByName = new Map(participants.map((p) => [p.name, p]));
+
+ async function resolveParticipant(externalId: string, name: string) {
+ let participant = participantByExternalId.get(externalId) ?? null;
+ if (!participant) {
+ const matchedName = findMatchingTeamName(name, participantNames);
+ if (matchedName) {
+ participant = participantByName.get(matchedName) ?? null;
+ if (participant && !participant.externalId) {
+ await updateParticipant(participant.id, { externalId });
+ participantByExternalId.set(externalId, participant);
+ }
+ }
+ }
+ return participant;
+ }
+
+ // Find the scoring event for this sports season (needed for CS2 stage lookup + playoff sync)
+ const scoringEvents = await db.query.scoringEvents.findMany({
+ where: eq(schema.scoringEvents.sportsSeasonId, sportsSeasonId),
+ });
+
+ // Split matches: Swiss (matchStage set) vs playoff bracket (matchStage null)
+ const swissMatches = fetchedMatches.filter((m) => m.matchStage !== null && m.matchStage !== undefined);
+ const bracketMatches = fetchedMatches.filter((m) => m.matchStage === null || m.matchStage === undefined);
+
+ const unmatchedTeams: MatchSyncResult["unmatchedTeams"] = [];
+ const errors: MatchSyncResult["errors"] = [];
+ let swissCreated = 0;
+ let swissUpdated = 0;
+ let playoffUpdated = 0;
+
+ // --- Swiss matches → season_matches ---
+ if (swissMatches.length > 0) {
+ // For CS2, use the scoring event that has cs2_major_stage_results
+ const cs2Event = scoringEvents.find((e) => e.isQualifyingEvent) ?? scoringEvents[0] ?? null;
+
+ const toUpsert = [];
+ for (const m of swissMatches) {
+ const p1 = await resolveParticipant(m.team1ExternalId, m.team1Name);
+ const p2 = await resolveParticipant(m.team2ExternalId, m.team2Name);
+
+ if (!p1) unmatchedTeams.push({ externalId: m.team1ExternalId, name: m.team1Name });
+ if (!p2) unmatchedTeams.push({ externalId: m.team2ExternalId, name: m.team2Name });
+
+ const winnerParticipant = m.winnerExternalId
+ ? (await resolveParticipant(m.winnerExternalId, ""))
+ : null;
+
+ toUpsert.push({
+ sportsSeasonId,
+ scoringEventId: cs2Event?.id ?? null,
+ participant1Id: p1?.id ?? null,
+ participant2Id: p2?.id ?? null,
+ winnerId: winnerParticipant?.id ?? null,
+ participant1Score: m.team1Score,
+ participant2Score: m.team2Score,
+ matchStage: m.matchStage ?? null,
+ matchRound: m.matchRound ?? null,
+ matchday: m.matchday ?? null,
+ isSeries: m.isSeries ?? false,
+ status: m.status,
+ scheduledAt: m.scheduledAt,
+ startedAt: m.startedAt,
+ completedAt: m.completedAt,
+ externalMatchId: m.externalMatchId,
+ });
+ }
+
+ const upserted = await upsertSeasonMatchBulk(toUpsert);
+
+ // Track created vs updated (rough heuristic: if completedAt is within last 2 min, it's new)
+ swissCreated = upserted.filter((r) => {
+ const diff = r.createdAt ? Date.now() - r.createdAt.getTime() : Infinity;
+ return diff < 120_000;
+ }).length;
+ swissUpdated = upserted.length - swissCreated;
+
+ // Upsert sub-games (maps) for matches with subGames
+ for (const m of swissMatches) {
+ if (!m.subGames?.length) continue;
+ const upsertedMatch = upserted.find((u) => u.externalMatchId === m.externalMatchId);
+ if (!upsertedMatch) continue;
+ for (const g of m.subGames) {
+ const winnerParticipant = g.winnerExternalId
+ ? (await resolveParticipant(g.winnerExternalId, ""))
+ : null;
+ try {
+ await upsertMatchSubGame({
+ seasonMatchId: upsertedMatch.id,
+ gameNumber: g.gameNumber,
+ gameLabel: g.gameLabel ?? null,
+ participant1Score: g.team1Score,
+ participant2Score: g.team2Score,
+ winnerId: winnerParticipant?.id ?? null,
+ status: g.status,
+ externalGameId: g.externalGameId ?? null,
+ });
+ } catch (err) {
+ logger.error(`[match-sync] Error upserting sub-game ${g.gameNumber} for match ${m.externalMatchId}:`, err);
+ }
+ }
+ }
+ }
+
+ // --- Bracket matches → playoff_matches ---
+ if (bracketMatches.length > 0 && scoringEvents.length === 0) {
+ logger.warn(`[match-sync] ${bracketMatches.length} bracket match(es) found but no scoring events exist for season ${sportsSeasonId} — bracket sync skipped`);
+ }
+
+ if (bracketMatches.length > 0) {
+ for (const event of scoringEvents) {
+ const existingPlayoffMatches = await findPlayoffMatchesByEventId(event.id);
+ if (existingPlayoffMatches.length === 0) continue;
+
+ const bracketTemplate = event.bracketTemplateId
+ ? getBracketTemplate(event.bracketTemplateId)
+ : null;
+
+ for (const m of bracketMatches) {
+ if (m.status !== "complete") continue;
+
+ const p1 = await resolveParticipant(m.team1ExternalId, m.team1Name);
+ const p2 = await resolveParticipant(m.team2ExternalId, m.team2Name);
+ if (!p1 || !p2) continue;
+
+ const winnerParticipant = m.winnerExternalId
+ ? await resolveParticipant(m.winnerExternalId, "")
+ : null;
+ if (!winnerParticipant) continue;
+
+ const loserId = winnerParticipant.id === p1.id ? p2.id : p1.id;
+
+ // Find the matching playoff_matches row: prefer external_match_id match, fall back to participant ID match
+ let playoffMatch = existingPlayoffMatches.find(
+ (pm) => pm.externalMatchId === m.externalMatchId
+ );
+ if (!playoffMatch) {
+ playoffMatch = existingPlayoffMatches.find(
+ (pm) =>
+ !pm.isComplete &&
+ ((pm.participant1Id === p1.id && pm.participant2Id === p2.id) ||
+ (pm.participant1Id === p2.id && pm.participant2Id === p1.id))
+ );
+ }
+
+ if (!playoffMatch) continue;
+ if (playoffMatch.isComplete && playoffMatch.winnerId) continue; // idempotent
+
+ try {
+ await setMatchWinner(
+ playoffMatch.id,
+ winnerParticipant.id,
+ loserId,
+ winnerParticipant.id === p1.id ? (m.team1Score ?? undefined) : (m.team2Score ?? undefined),
+ winnerParticipant.id === p1.id ? (m.team2Score ?? undefined) : (m.team1Score ?? undefined)
+ );
+
+ // Set external_match_id for future upserts
+ if (!playoffMatch.externalMatchId) {
+ await updatePlayoffMatch(playoffMatch.id, { externalMatchId: m.externalMatchId });
+ }
+
+ if (bracketTemplate) {
+ try {
+ await advanceWinnerTemplate(playoffMatch.id, winnerParticipant.id, bracketTemplate);
+ } catch (err) {
+ if (!(err instanceof Error && err.message.includes("already filled"))) throw err;
+ }
+ }
+
+ const roundIsScoring = bracketTemplate?.rounds.find(
+ (r) => r.name === playoffMatch.round
+ )?.isScoring;
+
+ await processMatchResult({
+ round: playoffMatch.round,
+ winnerId: winnerParticipant.id,
+ loserId,
+ isScoring: roundIsScoring !== undefined ? roundIsScoring : (playoffMatch.isScoring ?? true),
+ sportsSeasonId,
+ bracketTemplateId: event.bracketTemplateId ?? null,
+ eventId: event.id,
+ eventName: event.name ?? undefined,
+ matchId: playoffMatch.id,
+ loserAdvances: event.bracketTemplateId
+ ? doesLoserAdvance(playoffMatch.round, playoffMatch.matchNumber, event.bracketTemplateId)
+ : false,
+ });
+
+ await autoCompleteRoundIfDone(event.id, playoffMatch.round, sportsSeasonId, db);
+
+ playoffUpdated++;
+ } catch (err) {
+ logger.error(`[match-sync] Error processing playoff match ${m.externalMatchId}:`, err);
+ errors.push({
+ externalMatchId: m.externalMatchId,
+ error: err instanceof Error ? err.message : String(err),
+ });
+ }
+ }
+ }
+ }
+
+ return { swissCreated, swissUpdated, playoffUpdated, unmatchedTeams, errors };
+}
diff --git a/app/services/match-sync/pandascore.ts b/app/services/match-sync/pandascore.ts
new file mode 100644
index 0000000..69d277f
--- /dev/null
+++ b/app/services/match-sync/pandascore.ts
@@ -0,0 +1,137 @@
+import type { MatchRecord, MatchSyncAdapter, MatchStatusValue, SubGameRecord } from "./types";
+
+// PandaScore API response types
+interface PandaScoreOpponent {
+ opponent: { id: number; name: string };
+ type: string;
+}
+interface PandaScoreResult {
+ team_id: number;
+ score: number;
+}
+interface PandaScoreGame {
+ id: number;
+ position: number; // map number (1, 2, 3)
+ map?: { name?: string };
+ winner?: { id: number } | null;
+ winner_type?: string;
+ teams?: Array<{ team: { id: number }; score?: number }>;
+ status: string; // "not_started" | "running" | "finished"
+ begin_at?: string;
+ end_at?: string;
+}
+interface PandaScoreTournament {
+ id: number;
+ name: string;
+}
+interface PandaScoreMatch {
+ id: number;
+ name: string;
+ status: string; // "not_started" | "running" | "finished" | "canceled" | "postponed"
+ scheduled_at?: string;
+ begin_at?: string;
+ end_at?: string;
+ opponents?: PandaScoreOpponent[];
+ results?: PandaScoreResult[];
+ winner?: { id: number; name: string } | null;
+ winner_id?: number | null;
+ number_of_games?: number;
+ games?: PandaScoreGame[];
+ tournament?: PandaScoreTournament;
+}
+
+function mapStatus(s: string): MatchStatusValue {
+ switch (s) {
+ case "running": return "in_progress";
+ case "finished": return "complete";
+ case "canceled": return "canceled";
+ case "postponed": return "postponed";
+ default: return "scheduled";
+ }
+}
+
+function tournamentNameToStage(name: string): number | null {
+ const lower = name.toLowerCase();
+ if (lower.includes("opening")) return 1;
+ if (lower.includes("challengers") || lower.includes("elimination")) return 2;
+ if (lower.includes("legends") || lower.includes("decider")) return 3;
+ return null;
+}
+
+export class PandaScoreMatchSyncAdapter implements MatchSyncAdapter {
+ readonly supportsLiveScores = true;
+
+ async fetchMatches(externalSeasonId: string): Promise {
+ const apiKey = process.env.PANDASCORE_API_KEY;
+ if (!apiKey) throw new Error("PANDASCORE_API_KEY is not configured");
+
+ const allMatches: PandaScoreMatch[] = [];
+ let page = 1;
+ const perPage = 100;
+
+ // externalSeasonId is a PandaScore serie_id for CS2 Majors
+ while (true) {
+ const url = `https://api.pandascore.co/csgo/matches?filter[serie_id]=${externalSeasonId}&per_page=${perPage}&page=${page}&sort=scheduled_at`;
+ const resp = await fetch(url, {
+ headers: { Authorization: `Bearer ${apiKey}` },
+ });
+
+ if (!resp.ok) {
+ const body = await resp.text();
+ throw new Error(`PandaScore API error ${resp.status}: ${body}`);
+ }
+
+ const batch = (await resp.json()) as PandaScoreMatch[];
+ if (batch.length === 0) break;
+ allMatches.push(...batch);
+ if (batch.length < perPage) break;
+ page++;
+ }
+
+ return allMatches.map((m) => this.mapMatch(m));
+ }
+
+ private mapMatch(m: PandaScoreMatch): MatchRecord {
+ const team1 = m.opponents?.[0]?.opponent ?? null;
+ const team2 = m.opponents?.[1]?.opponent ?? null;
+
+ const r1 = m.results?.find((r) => r.team_id === team1?.id);
+ const r2 = m.results?.find((r) => r.team_id === team2?.id);
+
+ const matchStage = m.tournament ? tournamentNameToStage(m.tournament.name) : null;
+
+ const subGames: SubGameRecord[] = (m.games ?? []).map((g): SubGameRecord => {
+ const t1score = g.teams?.find((t) => t.team.id === team1?.id)?.score ?? null;
+ const t2score = g.teams?.find((t) => t.team.id === team2?.id)?.score ?? null;
+ const winnerExternalId = g.winner !== null && g.winner !== undefined ? String(g.winner.id) : null;
+ return {
+ externalGameId: String(g.id),
+ gameNumber: g.position,
+ gameLabel: g.map?.name ?? undefined,
+ team1Score: t1score !== undefined ? t1score : null,
+ team2Score: t2score !== undefined ? t2score : null,
+ winnerExternalId,
+ status: g.status === "running" ? "in_progress" : g.status === "finished" ? "complete" : "scheduled",
+ };
+ });
+
+ return {
+ externalMatchId: String(m.id),
+ team1ExternalId: team1 ? String(team1.id) : "",
+ team1Name: team1?.name ?? "",
+ team2ExternalId: team2 ? String(team2.id) : "",
+ team2Name: team2?.name ?? "",
+ team1Score: r1?.score ?? null,
+ team2Score: r2?.score ?? null,
+ winnerExternalId: m.winner_id !== null && m.winner_id !== undefined ? String(m.winner_id) : null,
+ status: mapStatus(m.status),
+ scheduledAt: m.scheduled_at ? new Date(m.scheduled_at) : null,
+ startedAt: m.begin_at ? new Date(m.begin_at) : null,
+ completedAt: m.end_at ? new Date(m.end_at) : null,
+ matchStage,
+ matchRound: null, // rounds within a stage require additional API calls or ordering
+ isSeries: (m.number_of_games ?? 1) > 1,
+ subGames: subGames.length > 0 ? subGames : undefined,
+ };
+ }
+}
diff --git a/app/services/match-sync/types.ts b/app/services/match-sync/types.ts
new file mode 100644
index 0000000..a5f49c9
--- /dev/null
+++ b/app/services/match-sync/types.ts
@@ -0,0 +1,44 @@
+export type MatchStatusValue = "scheduled" | "in_progress" | "complete" | "canceled" | "postponed";
+
+export interface SubGameRecord {
+ externalGameId?: string;
+ gameNumber: number;
+ gameLabel?: string; // CS2 map name ("Mirage"), etc.
+ team1Score: number | null;
+ team2Score: number | null;
+ winnerExternalId?: string | null;
+ status: "scheduled" | "in_progress" | "complete";
+}
+
+export interface MatchRecord {
+ externalMatchId: string;
+ team1ExternalId: string;
+ team1Name: string;
+ team2ExternalId: string;
+ team2Name: string;
+ team1Score: number | null;
+ team2Score: number | null;
+ winnerExternalId: string | null;
+ status: MatchStatusValue;
+ scheduledAt: Date | null;
+ startedAt: Date | null;
+ completedAt: Date | null;
+ matchStage?: number | null; // CS2: 1/2/3; null for MLB/NBA bracket matches
+ matchRound?: number | null; // CS2: round within stage; null for MLB/NBA
+ matchday?: number | null; // EPL/MLS fixture week
+ isSeries?: boolean;
+ subGames?: SubGameRecord[];
+}
+
+export interface MatchSyncAdapter {
+ fetchMatches(externalSeasonId: string): Promise;
+ readonly supportsLiveScores: boolean;
+}
+
+export interface MatchSyncResult {
+ swissCreated: number;
+ swissUpdated: number;
+ playoffUpdated: number;
+ unmatchedTeams: { externalId: string; name: string }[];
+ errors: { externalMatchId: string; error: string }[];
+}
diff --git a/database/schema.ts b/database/schema.ts
index 4998dec..96fadae 100644
--- a/database/schema.ts
+++ b/database/schema.ts
@@ -371,6 +371,14 @@ export const sports = pgTable("sports", {
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
+export const matchStatusEnum = pgEnum("match_status", [
+ "scheduled",
+ "in_progress",
+ "complete",
+ "canceled",
+ "postponed",
+]);
+
export const sportsSeasons = pgTable("sports_seasons", {
id: uuid("id").primaryKey().defaultRandom(),
sportId: uuid("sport_id")
@@ -384,6 +392,7 @@ export const sportsSeasons = pgTable("sports_seasons", {
startDate: date("start_date"),
endDate: date("end_date"),
status: sportsSeasonStatusEnum("status").notNull().default("upcoming"),
+ externalSeasonId: varchar("external_season_id", { length: 255 }),
scoringType: scoringTypeEnum("scoring_type").notNull(),
// New scoring pattern field (replaces/augments scoringType)
scoringPattern: scoringPatternEnum("scoring_pattern"),
@@ -692,6 +701,7 @@ export const playoffMatches = pgTable("playoff_matches", {
isScoring: boolean("is_scoring").notNull().default(true), // Does this match affect fantasy points?
templateRound: varchar("template_round", { length: 50 }), // "First Four", "Round of 64", "Elite Eight", etc.
seedInfo: varchar("seed_info", { length: 50 }), // "1 vs 16", "11a vs 11b", etc. (for display)
+ externalMatchId: varchar("external_match_id", { length: 255 }),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
@@ -1004,6 +1014,7 @@ export const sportsSeasonsRelations = relations(sportsSeasons, ({ one, many }) =
participantResults: many(seasonParticipantResults),
regularSeasonStandings: many(regularSeasonStandings),
pendingStandingsMappings: many(pendingStandingsMappings),
+ seasonMatches: many(seasonMatches),
}));
export const simulatorProfilesRelations = relations(simulatorProfiles, ({ many }) => ({
@@ -1238,6 +1249,7 @@ export const scoringEventsRelations = relations(scoringEvents, ({ one, many }) =
playoffMatches: many(playoffMatches),
tournamentGroups: many(tournamentGroups),
cs2MajorStageResults: many(cs2MajorStageResults),
+ seasonMatches: many(seasonMatches),
}));
export const eventResultsRelations = relations(eventResults, ({ one }) => ({
@@ -1619,6 +1631,111 @@ export const cs2MajorStageResultsRelations = relations(cs2MajorStageResults, ({
}),
}));
+// ─── Season Matches (Generic) ──────────────────────────────────────────────────
+// Generic match records for regular season games, Swiss rounds, group stage
+// fixtures, and any other "two-participant matchup with a score" format.
+//
+// CS2 Swiss: match_stage (1-3) + match_round (1-5), is_series = true
+// MLB/NBA etc: match_stage/match_round = NULL, matchday = NULL or week number
+// EPL/MLS: matchday = fixture week, match_stage/match_round = NULL
+//
+// Playoff bracket matches (with bracket progression logic) stay in playoff_matches.
+
+export const seasonMatches = pgTable("season_matches", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ sportsSeasonId: uuid("sports_season_id")
+ .notNull()
+ .references(() => sportsSeasons.id, { onDelete: "cascade" }),
+ scoringEventId: uuid("scoring_event_id")
+ .references(() => scoringEvents.id, { onDelete: "cascade" }),
+ participant1Id: uuid("participant1_id")
+ .references(() => seasonParticipants.id, { onDelete: "set null" }),
+ participant2Id: uuid("participant2_id")
+ .references(() => seasonParticipants.id, { onDelete: "set null" }),
+ winnerId: uuid("winner_id")
+ .references(() => seasonParticipants.id, { onDelete: "set null" }),
+ participant1Score: integer("participant1_score"),
+ participant2Score: integer("participant2_score"),
+ matchStage: integer("match_stage"), // CS2: 1/2/3 for Opening/Challengers/Legends
+ matchRound: integer("match_round"), // CS2: round within stage (1-5)
+ matchday: integer("matchday"), // EPL/MLS fixture week
+ isSeries: boolean("is_series").notNull().default(false),
+ status: matchStatusEnum("status").notNull().default("scheduled"),
+ scheduledAt: timestamp("scheduled_at"),
+ startedAt: timestamp("started_at"),
+ completedAt: timestamp("completed_at"),
+ externalMatchId: varchar("external_match_id", { length: 255 }),
+ createdAt: timestamp("created_at").defaultNow().notNull(),
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
+}, (t) => [
+ uniqueIndex("season_matches_external_id_unique")
+ .on(t.externalMatchId)
+ .where(sql`${t.externalMatchId} IS NOT NULL`),
+ index("season_matches_sports_season_status_idx").on(t.sportsSeasonId, t.status),
+ index("season_matches_sports_season_stage_round_idx").on(t.sportsSeasonId, t.matchStage, t.matchRound),
+ index("season_matches_scoring_event_idx").on(t.scoringEventId),
+]);
+
+export const matchSubGames = pgTable("match_sub_games", {
+ id: uuid("id").primaryKey().defaultRandom(),
+ seasonMatchId: uuid("season_match_id")
+ .notNull()
+ .references(() => seasonMatches.id, { onDelete: "cascade" }),
+ gameNumber: integer("game_number").notNull(),
+ gameLabel: varchar("game_label", { length: 100 }), // CS2 map name, "Game 1", etc.
+ participant1Score: integer("participant1_score"),
+ participant2Score: integer("participant2_score"),
+ winnerId: uuid("winner_id")
+ .references(() => seasonParticipants.id, { onDelete: "set null" }),
+ status: matchStatusEnum("status").notNull().default("scheduled"),
+ startedAt: timestamp("started_at"),
+ completedAt: timestamp("completed_at"),
+ externalGameId: varchar("external_game_id", { length: 255 }),
+ createdAt: timestamp("created_at").defaultNow().notNull(),
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
+}, (t) => [
+ uniqueIndex("match_sub_games_match_game_number_unique").on(t.seasonMatchId, t.gameNumber),
+]);
+
+export const seasonMatchesRelations = relations(seasonMatches, ({ one, many }) => ({
+ sportsSeason: one(sportsSeasons, {
+ fields: [seasonMatches.sportsSeasonId],
+ references: [sportsSeasons.id],
+ }),
+ scoringEvent: one(scoringEvents, {
+ fields: [seasonMatches.scoringEventId],
+ references: [scoringEvents.id],
+ }),
+ participant1: one(seasonParticipants, {
+ fields: [seasonMatches.participant1Id],
+ references: [seasonParticipants.id],
+ relationName: "seasonMatchParticipant1",
+ }),
+ participant2: one(seasonParticipants, {
+ fields: [seasonMatches.participant2Id],
+ references: [seasonParticipants.id],
+ relationName: "seasonMatchParticipant2",
+ }),
+ winner: one(seasonParticipants, {
+ fields: [seasonMatches.winnerId],
+ references: [seasonParticipants.id],
+ relationName: "seasonMatchWinner",
+ }),
+ subGames: many(matchSubGames),
+}));
+
+export const matchSubGamesRelations = relations(matchSubGames, ({ one }) => ({
+ match: one(seasonMatches, {
+ fields: [matchSubGames.seasonMatchId],
+ references: [seasonMatches.id],
+ }),
+ winner: one(seasonParticipants, {
+ fields: [matchSubGames.winnerId],
+ references: [seasonParticipants.id],
+ relationName: "matchSubGameWinner",
+ }),
+}));
+
// ─── Commissioner Audit Log ────────────────────────────────────────────────────
// Immutable log of significant commissioner/admin actions per season.
// Readable by all league members for transparency; writable only by the
diff --git a/docs/plans/match-sync-display.md b/docs/plans/match-sync-display.md
new file mode 100644
index 0000000..4002626
--- /dev/null
+++ b/docs/plans/match-sync-display.md
@@ -0,0 +1,255 @@
+# Plan: Generalized Match Import, Swiss Stage Tracking, Live Scores, and Display System
+
+## Context
+
+The current system tracks tournament stage entry/exit manually with no match-level data, no automated schedule/result imports, and no public tournament display. The goal is a sport-agnostic match sync infrastructure (usable for MLB schedules, CS2 Swiss rounds, EPL fixtures, etc.) with CS2 as the first implementation target.
+
+**Scope decision**: The new `season_matches` table is generic from day one. CS2 Swiss uses nullable `match_stage`/`match_round` columns; MLB just leaves those NULL. Playoff bracket matches remain in the existing `playoff_matches` table (already works well with complex progression logic). This avoids proliferating per-sport match tables.
+
+---
+
+## Status
+
+- [x] Phase 1 — Generic Data Model + CS2 Admin UI ✓
+- [x] Phase 2 — Generic Match Sync Adapter + Cron Job ✓
+- [x] Phase 3 — Public Tournament & Schedule Display + Live Scores ✓
+- [x] Phase 4 — Automated Playoff Bracket Updates ✓
+
+---
+
+## Phase 1 — Generic Data Model + CS2 Admin UI (no external API)
+
+### 1a. Schema additions (`database/schema.ts`)
+
+**New enum**: `matchStatusEnum` = `["scheduled", "in_progress", "complete", "canceled", "postponed"]`
+
+**New table: `season_matches`** — generic match record for regular season, Swiss rounds, group stages, fixtures
+```
+id (uuid PK)
+sports_season_id (uuid FK → sportsSeasons, onDelete: cascade)
+scoring_event_id (uuid FK → scoringEvents, nullable — set for CS2 stage matches, null for MLB regular season)
+participant1_id (uuid FK → seasonParticipants, nullable)
+participant2_id (uuid FK → seasonParticipants, nullable)
+winner_id (uuid FK → seasonParticipants, nullable)
+participant1_score (integer nullable)
+participant2_score (integer nullable)
+match_stage (integer nullable) — CS2: 1/2/3 for Opening/Challengers/Legends; NULL for MLB
+match_round (integer nullable) — CS2: round within stage (1-5); MLB: series game number or NULL
+matchday (integer nullable) — EPL/MLS fixture week; NULL for CS2
+is_series (boolean default false) — true for Bo3/Bo5 CS2 matches
+status (matchStatusEnum default 'scheduled')
+scheduled_at (timestamp nullable)
+started_at (timestamp nullable)
+completed_at (timestamp nullable)
+external_match_id (varchar 255 nullable) — API ID for upsert conflict key
+created_at, updated_at (timestamps)
+```
+Indexes: unique on `external_match_id` (partial, WHERE NOT NULL), index on `(sports_season_id, status)`, index on `(sports_season_id, match_stage, match_round)`, index on `(scoring_event_id)`.
+
+**New table: `match_sub_games`** — per-sub-game scores (CS2 maps, MLB innings if desired, etc.)
+```
+id (uuid PK)
+season_match_id (uuid FK → seasonMatches, onDelete: cascade)
+game_number (integer) — map 1/2/3 for CS2, game 1-7 for series, inning for baseball
+game_label (varchar 100 nullable) — CS2: "Mirage", "Inferno"; others: NULL or "Game 1"
+participant1_score (integer nullable)
+participant2_score (integer nullable)
+winner_id (uuid FK → seasonParticipants, nullable)
+status (matchStatusEnum default 'scheduled')
+started_at, completed_at (timestamps nullable)
+external_game_id (varchar 255 nullable)
+```
+Unique index on `(season_match_id, game_number)`.
+
+**New column on `sportsSeasons`**: `external_season_id varchar(255) nullable` — links to the API's identifier for this season/tournament (PandaScore tournament ID for CS2, ESPN league season ID for MLB, etc.)
+
+Add Drizzle `relations()` for both new tables following the existing patterns.
+
+Run `npm run db:generate` after changes.
+
+### 1b. New model: `app/models/season-match.ts`
+- `upsertSeasonMatch(data)` — conflict on `external_match_id`, update scores/status/timestamps
+- `findSeasonMatchesBySportsSeasonId(sportsSeasonId, filters?)` — joined with participant names
+- `findSeasonMatchesByScoringEventId(scoringEventId)` — for CS2 stage view, ordered stage → round
+- `findSeasonMatchesByStage(sportsSeasonId, stage)` — CS2 per-stage query
+- `upsertMatchSubGame(data)`
+- `findMatchSubGamesByMatchId(matchId)`
+
+### 1c. Extend cs2-setup admin route
+File: `app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx`
+- Add loader query calling `findSeasonMatchesByScoringEventId`
+- Add read-only Swiss rounds section below existing stage assignment UI: per round shows `Team A (W-L) vs Team B (W-L) → maps [16-14, 14-16, 16-12]`
+- "Sync from API" button (fetcher POST to cron endpoint, wired in Phase 2)
+
+### 1d. New admin route: manual match entry
+File: `app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx`
+Actions: `update-match-result`, `create-manual-match`, `delete-match` — manual fallback when API unavailable
+Register in `app/routes.ts` under admin layout.
+
+### 1e. Tests
+- `app/models/__tests__/season-match.test.ts` — upsert conflict resolution, ordering, null stage/round handling
+
+---
+
+## Phase 2 — Generic Match Sync Adapter + Cron Job
+
+### External Data Sources
+- **CS2** (and future Dota2/LoL): **PandaScore** — free tier, 1,000 req/hour, no credit card needed. `PANDASCORE_API_KEY` env var.
+- **MLB/NBA/NFL/MLS/NHL etc.**: ESPN public API (already used for standings), or sport-specific APIs already in `standings-sync/`. Same free, no-auth pattern.
+
+### 2a. New service directory: `app/services/match-sync/`
+
+**`types.ts`** — generic adapter interface:
+```typescript
+interface MatchRecord {
+ externalMatchId: string;
+ team1ExternalId: string;
+ team2ExternalId: string;
+ team1Score: number | null;
+ team2Score: number | null;
+ winnerExternalId: string | null;
+ status: "scheduled" | "in_progress" | "complete" | "canceled" | "postponed";
+ scheduledAt: Date | null;
+ startedAt: Date | null;
+ completedAt: Date | null;
+ matchStage?: number | null; // CS2: 1/2/3; omit for MLB
+ matchRound?: number | null; // CS2: round within stage; omit for MLB
+ matchday?: number | null; // EPL/MLS fixture week
+ isSeries?: boolean;
+ subGames?: SubGameRecord[];
+}
+interface SubGameRecord {
+ externalGameId?: string;
+ gameNumber: number;
+ gameLabel?: string; // CS2 map name, etc.
+ team1Score: number | null;
+ team2Score: number | null;
+ winnerExternalId?: string | null;
+ status: "scheduled" | "in_progress" | "complete";
+}
+interface MatchSyncAdapter {
+ fetchMatches(externalSeasonId: string): Promise;
+ supportsLiveScores: boolean;
+}
+interface MatchSyncResult {
+ created: number;
+ updated: number;
+ unchanged: number;
+ unmatchedTeams: {externalId: string; name: string}[];
+ errors: {externalMatchId: string; error: string}[];
+}
+```
+
+**`pandascore.ts`** — `PandaScoreMatchSyncAdapter implements MatchSyncAdapter`. Calls PandaScore CS2 matches endpoint. Maps stage/round/game (map) fields.
+
+**`espn-schedule.ts`** — `EspnScheduleAdapter implements MatchSyncAdapter` (Phase 2b). Calls ESPN schedule endpoints for MLB, NBA, MLS, etc. `team1Score`/`team2Score` from ESPN scores.
+
+**`index.ts`** — `syncMatches(sportsSeasonId)` orchestrator, mirrors `syncStandings()` exactly:
+1. Load sportsSeason + sport, extract `externalSeasonId`
+2. `getMatchSyncAdapter(simulatorType)` → picks adapter
+3. Fetch matches, resolve participants via `externalId` → name fallback
+4. Bulk upsert into `season_matches` + `match_sub_games`
+5. Return `MatchSyncResult`
+
+```typescript
+function getMatchSyncAdapter(simulatorType: string): MatchSyncAdapter {
+ switch (simulatorType) {
+ case "cs2_major_qualifying_points": return new PandaScoreMatchSyncAdapter();
+ case "mlb_bracket": return new EspnScheduleAdapter("baseball/mlb");
+ case "nba_bracket": return new EspnScheduleAdapter("basketball/nba");
+ case "mls_bracket": return new EspnScheduleAdapter("soccer/mls");
+ // ... expand as needed
+ default: throw new Error(`No match sync adapter for "${simulatorType}"`);
+ }
+}
+```
+
+### 2b. New cron job: `app/routes/admin/jobs.sync-matches.ts`
+Exact same pattern as `jobs.sync-and-simulate.ts`:
+- `POST /admin/jobs/sync-matches` with `requireCronSecret` auth
+- Finds active sports seasons where `externalSeasonId IS NOT NULL`
+- Calls `syncMatches(season.id)` for each; triggers simulation if results changed
+- Returns `{ synced, unchanged, errors }`
+
+Register in `app/routes.ts`.
+
+### 2c. Admin form: add `external_season_id` field to sports season admin form
+
+### 2d. Tests
+- `app/services/match-sync/__tests__/pandascore.test.ts`
+- `app/services/match-sync/__tests__/espn-schedule.test.ts`
+- `app/services/match-sync/__tests__/sync.test.ts` — idempotency, name matching, null stage/round handling
+
+---
+
+## Phase 3 — Public Tournament & Schedule Display + Live Scores
+
+### 3a. CS2 Tournament component: `app/components/scoring/Cs2TournamentBracket.tsx`
+Tab layout: **Swiss Stages** | **Champions Stage**
+- Swiss Stages tab: sub-tabs Stage 1 / 2 / 3. Each shows W-L standings table + rounds accordion. Each round: pairing, map scores, status badge.
+- Champions Stage tab: reuses existing ` ` with `bracketTemplateId="simple_8"`.
+- Status badges: `scheduled` (gray), `in_progress` (amber pulse), `complete` (green).
+
+### 3b. Generic schedule component: `app/components/scoring/MatchSchedule.tsx`
+Reusable across all sports. Shows upcoming + completed matches with scores. Used for MLB schedule view, EPL fixtures, etc. Props: `matches: SeasonMatch[]`, `sport`.
+
+### 3c. New public route: `app/routes/sports-seasons.$sportsSeasonId.tournament.tsx`
+URL: `/sports-seasons/:sportsSeasonId/tournament` — league-independent.
+Loader: fetches `season_matches` + playoff matches (Champions Stage) + cs2 stage results.
+CS2 renders ``, other sports render `` based on `simulatorType`.
+Live polling: if any match `in_progress`, `useRevalidator()` re-fetches every 30 seconds.
+
+Register in `app/routes.ts` outside admin layout.
+
+### 3d. Optional: Socket.IO push
+Emit `season-match-updated` from `syncMatches` when a match transitions to `in_progress` or `complete`. Phase 3 enhancement, deferred until polling is stable.
+
+---
+
+## Phase 4 — Automated Playoff Bracket Updates (future)
+
+Playoff bracket matches (`playoff_matches`) can also be auto-synced using the same `MatchSyncAdapter` interface. This is deferred because playoff sync is more complex than schedule sync — it must trigger `processMatchResult()` and bracket progression logic correctly, not just upsert data.
+
+**What's needed to enable this:**
+1. Add `external_match_id varchar(255) nullable` column to `playoff_matches` (one migration)
+2. Add `fetchPlayoffMatches(externalSeasonId)` to the adapter (or reuse `fetchMatches` with a `matchType` flag)
+3. Add a `syncPlayoffResults(sportsSeasonId)` path in `match-sync/index.ts` that writes to `playoff_matches` and calls the existing `setMatchWinner()` / `processMatchResult()` pipeline
+4. Handle idempotency — don't re-trigger scoring if winner is already set
+
+The same `PandaScoreMatchSyncAdapter` and `EspnScheduleAdapter` used for schedule sync will handle playoff data too, since they already return match results regardless of format.
+
+---
+
+## What Does NOT Change (Phases 1–3)
+- `cs2_major_stage_results` — still the source of truth for CS2 stage entry/exit/placement
+- Fantasy scoring pipeline — fully untouched
+- `playoff_matches` / `playoff_match_games` — unchanged, still used for all bracket progression
+- Existing CS2 admin setup UI — works as before, just gains a new read-only section
+
+---
+
+## Key Files
+
+| File | Action |
+|------|--------|
+| `database/schema.ts` | Add `matchStatusEnum`, `season_matches`, `match_sub_games` tables, `externalSeasonId` on sportsSeasons |
+| `app/models/season-match.ts` | New — all DB queries for new tables |
+| `app/services/match-sync/types.ts` | New — generic adapter interface |
+| `app/services/match-sync/pandascore.ts` | New — PandaScore CS2 implementation |
+| `app/services/match-sync/espn-schedule.ts` | New — ESPN schedule implementation (MLB etc.) |
+| `app/services/match-sync/index.ts` | New — orchestrator (mirrors standings-sync/index.ts) |
+| `app/routes/admin/jobs.sync-matches.ts` | New — cron job (mirrors jobs.sync-and-simulate.ts) |
+| `app/routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx` | Extend loader + Swiss rounds display section |
+| `app/routes/admin.sports-seasons.$id.events.$eventId.swiss-matches.tsx` | New — manual match entry admin route |
+| `app/components/scoring/Cs2TournamentBracket.tsx` | New — CS2 tournament display |
+| `app/components/scoring/MatchSchedule.tsx` | New — generic match schedule display |
+| `app/routes/sports-seasons.$sportsSeasonId.tournament.tsx` | New — public tournament/schedule route |
+| `app/routes.ts` | Register 3 new routes |
+
+## Verification
+1. `npm run db:generate` produces migration for 2 new tables + column
+2. `npm run db:migrate` applies cleanly
+3. `npm run typecheck` passes
+4. `npm run test:run` passes including new model + adapter tests
+5. Manual: set `externalSeasonId` on a CS2 sports season, call `/admin/jobs/sync-matches`, verify `season_matches` rows created with stage/round populated
+6. Manual: navigate to `/sports-seasons/:id/tournament`, confirm CS2 Swiss stage display renders with rounds and map scores
diff --git a/drizzle/0120_tidy_invaders.sql b/drizzle/0120_tidy_invaders.sql
new file mode 100644
index 0000000..6c60198
--- /dev/null
+++ b/drizzle/0120_tidy_invaders.sql
@@ -0,0 +1,87 @@
+CREATE TYPE "public"."match_status" AS ENUM('scheduled', 'in_progress', 'complete', 'canceled', 'postponed');--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "match_sub_games" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "season_match_id" uuid NOT NULL,
+ "game_number" integer NOT NULL,
+ "game_label" varchar(100),
+ "participant1_score" integer,
+ "participant2_score" integer,
+ "winner_id" uuid,
+ "status" "match_status" DEFAULT 'scheduled' NOT NULL,
+ "started_at" timestamp,
+ "completed_at" timestamp,
+ "external_game_id" varchar(255),
+ "created_at" timestamp DEFAULT now() NOT NULL,
+ "updated_at" timestamp DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "season_matches" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "sports_season_id" uuid NOT NULL,
+ "scoring_event_id" uuid,
+ "participant1_id" uuid,
+ "participant2_id" uuid,
+ "winner_id" uuid,
+ "participant1_score" integer,
+ "participant2_score" integer,
+ "match_stage" integer,
+ "match_round" integer,
+ "matchday" integer,
+ "is_series" boolean DEFAULT false NOT NULL,
+ "status" "match_status" DEFAULT 'scheduled' NOT NULL,
+ "scheduled_at" timestamp,
+ "started_at" timestamp,
+ "completed_at" timestamp,
+ "external_match_id" varchar(255),
+ "created_at" timestamp DEFAULT now() NOT NULL,
+ "updated_at" timestamp DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+ALTER TABLE "sports_seasons" ADD COLUMN "external_season_id" varchar(255);--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "match_sub_games" ADD CONSTRAINT "match_sub_games_season_match_id_season_matches_id_fk" FOREIGN KEY ("season_match_id") REFERENCES "public"."season_matches"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "match_sub_games" ADD CONSTRAINT "match_sub_games_winner_id_season_participants_id_fk" FOREIGN KEY ("winner_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "season_matches" ADD CONSTRAINT "season_matches_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "season_matches" ADD CONSTRAINT "season_matches_scoring_event_id_scoring_events_id_fk" FOREIGN KEY ("scoring_event_id") REFERENCES "public"."scoring_events"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "season_matches" ADD CONSTRAINT "season_matches_participant1_id_season_participants_id_fk" FOREIGN KEY ("participant1_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "season_matches" ADD CONSTRAINT "season_matches_participant2_id_season_participants_id_fk" FOREIGN KEY ("participant2_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "season_matches" ADD CONSTRAINT "season_matches_winner_id_season_participants_id_fk" FOREIGN KEY ("winner_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "match_sub_games_match_game_number_unique" ON "match_sub_games" USING btree ("season_match_id","game_number");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "season_matches_external_id_unique" ON "season_matches" USING btree ("external_match_id") WHERE "season_matches"."external_match_id" IS NOT NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "season_matches_sports_season_status_idx" ON "season_matches" USING btree ("sports_season_id","status");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "season_matches_sports_season_stage_round_idx" ON "season_matches" USING btree ("sports_season_id","match_stage","match_round");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "season_matches_scoring_event_idx" ON "season_matches" USING btree ("scoring_event_id");
\ No newline at end of file
diff --git a/drizzle/0121_even_gambit.sql b/drizzle/0121_even_gambit.sql
new file mode 100644
index 0000000..e474259
--- /dev/null
+++ b/drizzle/0121_even_gambit.sql
@@ -0,0 +1 @@
+ALTER TABLE "playoff_matches" ADD COLUMN "external_match_id" varchar(255);
\ No newline at end of file
diff --git a/drizzle/meta/0120_snapshot.json b/drizzle/meta/0120_snapshot.json
new file mode 100644
index 0000000..2f3a212
--- /dev/null
+++ b/drizzle/meta/0120_snapshot.json
@@ -0,0 +1,6712 @@
+{
+ "id": "ec076c22-a4af-4cf8-bd22-c8856382826d",
+ "prevId": "0b9c567b-40e7-45c3-ab9f-e40088f2863b",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.accounts": {
+ "name": "accounts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "accounts_user_id_users_id_fk": {
+ "name": "accounts_user_id_users_id_fk",
+ "tableFrom": "accounts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.autodraft_settings": {
+ "name": "autodraft_settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_enabled": {
+ "name": "is_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "mode": {
+ "name": "mode",
+ "type": "autodraft_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'next_pick'"
+ },
+ "queue_only": {
+ "name": "queue_only",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "autodraft_settings_season_id_seasons_id_fk": {
+ "name": "autodraft_settings_season_id_seasons_id_fk",
+ "tableFrom": "autodraft_settings",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "autodraft_settings_team_id_teams_id_fk": {
+ "name": "autodraft_settings_team_id_teams_id_fk",
+ "tableFrom": "autodraft_settings",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.commissioner_audit_log": {
+ "name": "commissioner_audit_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_display_name": {
+ "name": "actor_display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "audit_action",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "affected_team_ids": {
+ "name": "affected_team_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "details": {
+ "name": "details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "audit_log_season_id_idx": {
+ "name": "audit_log_season_id_idx",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "commissioner_audit_log_season_id_seasons_id_fk": {
+ "name": "commissioner_audit_log_season_id_seasons_id_fk",
+ "tableFrom": "commissioner_audit_log",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "commissioner_audit_log_league_id_leagues_id_fk": {
+ "name": "commissioner_audit_log_league_id_leagues_id_fk",
+ "tableFrom": "commissioner_audit_log",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.commissioners": {
+ "name": "commissioners",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "commissioners_league_id_leagues_id_fk": {
+ "name": "commissioners_league_id_leagues_id_fk",
+ "tableFrom": "commissioners",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cs2_major_stage_results": {
+ "name": "cs2_major_stage_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_entry": {
+ "name": "stage_entry",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_eliminated": {
+ "name": "stage_eliminated",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stage_eliminated_wins": {
+ "name": "stage_eliminated_wins",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "final_placement": {
+ "name": "final_placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cs2_major_stage_results_unique": {
+ "name": "cs2_major_stage_results_unique",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cs2_major_stage_results_scoring_event_id_scoring_events_id_fk": {
+ "name": "cs2_major_stage_results_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "cs2_major_stage_results",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cs2_major_stage_results_participant_id_season_participants_id_fk": {
+ "name": "cs2_major_stage_results_participant_id_season_participants_id_fk",
+ "tableFrom": "cs2_major_stage_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_picks": {
+ "name": "draft_picks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pick_number": {
+ "name": "pick_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "round": {
+ "name": "round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pick_in_round": {
+ "name": "pick_in_round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picked_by_user_id": {
+ "name": "picked_by_user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picked_by_type": {
+ "name": "picked_by_type",
+ "type": "picked_by_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time_used": {
+ "name": "time_used",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "draft_picks_season_pick_unique": {
+ "name": "draft_picks_season_pick_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pick_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "draft_picks_season_id_seasons_id_fk": {
+ "name": "draft_picks_season_id_seasons_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_picks_team_id_teams_id_fk": {
+ "name": "draft_picks_team_id_teams_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_picks_participant_id_season_participants_id_fk": {
+ "name": "draft_picks_participant_id_season_participants_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_queue": {
+ "name": "draft_queue",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "queue_position": {
+ "name": "queue_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_queue_season_id_seasons_id_fk": {
+ "name": "draft_queue_season_id_seasons_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_queue_team_id_teams_id_fk": {
+ "name": "draft_queue_team_id_teams_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_queue_participant_id_season_participants_id_fk": {
+ "name": "draft_queue_participant_id_season_participants_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_slots": {
+ "name": "draft_slots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_order": {
+ "name": "draft_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_slots_season_id_seasons_id_fk": {
+ "name": "draft_slots_season_id_seasons_id_fk",
+ "tableFrom": "draft_slots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_slots_team_id_teams_id_fk": {
+ "name": "draft_slots_team_id_teams_id_fk",
+ "tableFrom": "draft_slots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_timers": {
+ "name": "draft_timers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time_remaining": {
+ "name": "time_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picks_expires_at": {
+ "name": "picks_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "picks_started_at": {
+ "name": "picks_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_timers_season_id_seasons_id_fk": {
+ "name": "draft_timers_season_id_seasons_id_fk",
+ "tableFrom": "draft_timers",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_timers_team_id_teams_id_fk": {
+ "name": "draft_timers_team_id_teams_id_fk",
+ "tableFrom": "draft_timers",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.event_results": {
+ "name": "event_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_participant_id": {
+ "name": "season_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "qualifying_points_awarded": {
+ "name": "qualifying_points_awarded",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "eliminated": {
+ "name": "eliminated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_score": {
+ "name": "raw_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "not_participating": {
+ "name": "not_participating",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "event_results_event_participant_unique": {
+ "name": "event_results_event_participant_unique",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "event_results_scoring_event_id_scoring_events_id_fk": {
+ "name": "event_results_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "event_results",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "event_results_season_participant_id_season_participants_id_fk": {
+ "name": "event_results_season_participant_id_season_participants_id_fk",
+ "tableFrom": "event_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "season_participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.group_stage_matches": {
+ "name": "group_stage_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_group_id": {
+ "name": "tournament_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "matchday": {
+ "name": "matchday",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "group_stage_matches_group_pair_unique": {
+ "name": "group_stage_matches_group_pair_unique",
+ "columns": [
+ {
+ "expression": "tournament_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant1_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant2_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_stage_matches_tournament_group_id_tournament_groups_id_fk": {
+ "name": "group_stage_matches_tournament_group_id_tournament_groups_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "tournament_groups",
+ "columnsFrom": [
+ "tournament_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_stage_matches_participant1_id_season_participants_id_fk": {
+ "name": "group_stage_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "group_stage_matches_participant2_id_season_participants_id_fk": {
+ "name": "group_stage_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.leagues": {
+ "name": "leagues",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_season_id": {
+ "name": "current_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_public_draft_board": {
+ "name": "is_public_draft_board",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "discord_webhook_url": {
+ "name": "discord_webhook_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "discord_picks_announcement_enabled": {
+ "name": "discord_picks_announcement_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.match_sub_games": {
+ "name": "match_sub_games",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_match_id": {
+ "name": "season_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_number": {
+ "name": "game_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_label": {
+ "name": "game_label",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "match_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_game_id": {
+ "name": "external_game_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "match_sub_games_match_game_number_unique": {
+ "name": "match_sub_games_match_game_number_unique",
+ "columns": [
+ {
+ "expression": "season_match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "game_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "match_sub_games_season_match_id_season_matches_id_fk": {
+ "name": "match_sub_games_season_match_id_season_matches_id_fk",
+ "tableFrom": "match_sub_games",
+ "tableTo": "season_matches",
+ "columnsFrom": [
+ "season_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "match_sub_games_winner_id_season_participants_id_fk": {
+ "name": "match_sub_games_winner_id_season_participants_id_fk",
+ "tableFrom": "match_sub_games",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_ev_snapshots": {
+ "name": "participant_ev_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prob_first": {
+ "name": "prob_first",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_second": {
+ "name": "prob_second",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_third": {
+ "name": "prob_third",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fourth": {
+ "name": "prob_fourth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fifth": {
+ "name": "prob_fifth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_sixth": {
+ "name": "prob_sixth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_seventh": {
+ "name": "prob_seventh",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_eighth": {
+ "name": "prob_eighth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "calculated_ev": {
+ "name": "calculated_ev",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "source": {
+ "name": "source",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_ev_snapshots_unique": {
+ "name": "participant_ev_snapshots_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_ev_snapshots_participant_id_season_participants_id_fk": {
+ "name": "participant_ev_snapshots_participant_id_season_participants_id_fk",
+ "tableFrom": "participant_ev_snapshots",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "participant_ev_snapshots_sports_season_id_sports_seasons_id_fk": {
+ "name": "participant_ev_snapshots_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "participant_ev_snapshots",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_golf_skills": {
+ "name": "participant_golf_skills",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sg_total": {
+ "name": "sg_total",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "datagolf_rank": {
+ "name": "datagolf_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "masters_odds": {
+ "name": "masters_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "us_open_odds": {
+ "name": "us_open_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "open_championship_odds": {
+ "name": "open_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pga_championship_odds": {
+ "name": "pga_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_golf_skills_participant_unique": {
+ "name": "participant_golf_skills_participant_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_golf_skills_participant_id_participants_id_fk": {
+ "name": "participant_golf_skills_participant_id_participants_id_fk",
+ "tableFrom": "participant_golf_skills",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_season_results": {
+ "name": "participant_season_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_points": {
+ "name": "current_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "current_position": {
+ "name": "current_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "psr_participant_season_idx": {
+ "name": "psr_participant_season_idx",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_season_results_participant_id_season_participants_id_fk": {
+ "name": "participant_season_results_participant_id_season_participants_id_fk",
+ "tableFrom": "participant_season_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "participant_season_results_sports_season_id_sports_seasons_id_fk": {
+ "name": "participant_season_results_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "participant_season_results",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_surface_elos": {
+ "name": "participant_surface_elos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_hard": {
+ "name": "elo_hard",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_clay": {
+ "name": "elo_clay",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_grass": {
+ "name": "elo_grass",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_surface_elos_participant_unique": {
+ "name": "participant_surface_elos_participant_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_surface_elos_participant_id_participants_id_fk": {
+ "name": "participant_surface_elos_participant_id_participants_id_fk",
+ "tableFrom": "participant_surface_elos",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participants": {
+ "name": "participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_key": {
+ "name": "external_key",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participants_sport_name_unique": {
+ "name": "participants_sport_name_unique",
+ "columns": [
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participants_sport_id_sports_id_fk": {
+ "name": "participants_sport_id_sports_id_fk",
+ "tableFrom": "participants",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pending_standings_mappings": {
+ "name": "pending_standings_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_team_id": {
+ "name": "external_team_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_name": {
+ "name": "team_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "standing_data": {
+ "name": "standing_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "psm_season_external_id_idx": {
+ "name": "psm_season_external_id_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "pending_standings_mappings_sports_season_id_sports_seasons_id_fk": {
+ "name": "pending_standings_mappings_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "pending_standings_mappings",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_match_games": {
+ "name": "playoff_match_games",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "playoff_match_id": {
+ "name": "playoff_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_number": {
+ "name": "game_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "playoff_match_game_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_match_games_playoff_match_id_playoff_matches_id_fk": {
+ "name": "playoff_match_games_playoff_match_id_playoff_matches_id_fk",
+ "tableFrom": "playoff_match_games",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "playoff_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_match_games_winner_id_season_participants_id_fk": {
+ "name": "playoff_match_games_winner_id_season_participants_id_fk",
+ "tableFrom": "playoff_match_games",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_match_odds": {
+ "name": "playoff_match_odds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "playoff_match_id": {
+ "name": "playoff_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "moneyline_odds": {
+ "name": "moneyline_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "implied_probability": {
+ "name": "implied_probability",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "odds_source": {
+ "name": "odds_source",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recorded_at": {
+ "name": "recorded_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_match_odds_playoff_match_id_playoff_matches_id_fk": {
+ "name": "playoff_match_odds_playoff_match_id_playoff_matches_id_fk",
+ "tableFrom": "playoff_match_odds",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "playoff_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_match_odds_participant_id_season_participants_id_fk": {
+ "name": "playoff_match_odds_participant_id_season_participants_id_fk",
+ "tableFrom": "playoff_match_odds",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_matches": {
+ "name": "playoff_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "round": {
+ "name": "round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "match_number": {
+ "name": "match_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "loser_id": {
+ "name": "loser_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_scoring": {
+ "name": "is_scoring",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "template_round": {
+ "name": "template_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seed_info": {
+ "name": "seed_info",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_matches_scoring_event_id_scoring_events_id_fk": {
+ "name": "playoff_matches_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_participant1_id_season_participants_id_fk": {
+ "name": "playoff_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_participant2_id_season_participants_id_fk": {
+ "name": "playoff_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_winner_id_season_participants_id_fk": {
+ "name": "playoff_matches_winner_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_loser_id_season_participants_id_fk": {
+ "name": "playoff_matches_loser_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "loser_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.qualifying_point_config": {
+ "name": "qualifying_point_config",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "points": {
+ "name": "points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "qualifying_point_config_sports_season_id_sports_seasons_id_fk": {
+ "name": "qualifying_point_config_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "qualifying_point_config",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.regular_season_standings": {
+ "name": "regular_season_standings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wins": {
+ "name": "wins",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "losses": {
+ "name": "losses",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "ot_losses": {
+ "name": "ot_losses",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ties": {
+ "name": "ties",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "table_points": {
+ "name": "table_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goals_for": {
+ "name": "goals_for",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goals_against": {
+ "name": "goals_against",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_difference": {
+ "name": "goal_difference",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "win_pct": {
+ "name": "win_pct",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "games_played": {
+ "name": "games_played",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "games_back": {
+ "name": "games_back",
+ "type": "numeric(5, 1)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conference": {
+ "name": "conference",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "division": {
+ "name": "division",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conference_rank": {
+ "name": "conference_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "division_rank": {
+ "name": "division_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "league_rank": {
+ "name": "league_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "streak": {
+ "name": "streak",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_ten": {
+ "name": "last_ten",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "home_record": {
+ "name": "home_record",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "away_record": {
+ "name": "away_record",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_team_id": {
+ "name": "external_team_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "srs": {
+ "name": "srs",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "synced_at": {
+ "name": "synced_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "rss_participant_season_idx": {
+ "name": "rss_participant_season_idx",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "regular_season_standings_participant_id_season_participants_id_fk": {
+ "name": "regular_season_standings_participant_id_season_participants_id_fk",
+ "tableFrom": "regular_season_standings",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "regular_season_standings_sports_season_id_sports_seasons_id_fk": {
+ "name": "regular_season_standings_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "regular_season_standings",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scoring_events": {
+ "name": "scoring_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tournament_id": {
+ "name": "tournament_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_date": {
+ "name": "event_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_starts_at": {
+ "name": "event_starts_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "event_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "playoff_round": {
+ "name": "playoff_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_qualifying_event": {
+ "name": "is_qualifying_event",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "bracket_template_id": {
+ "name": "bracket_template_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_starts_at_round": {
+ "name": "scoring_starts_at_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bracket_region_config": {
+ "name": "bracket_region_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "scoring_events_sports_season_id_sports_seasons_id_fk": {
+ "name": "scoring_events_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "scoring_events",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scoring_events_tournament_id_tournaments_id_fk": {
+ "name": "scoring_events_tournament_id_tournaments_id_fk",
+ "tableFrom": "scoring_events",
+ "tableTo": "tournaments",
+ "columnsFrom": [
+ "tournament_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "scoring_events_qualifying_require_tournament": {
+ "name": "scoring_events_qualifying_require_tournament",
+ "value": "NOT \"scoring_events\".\"is_qualifying_event\" OR \"scoring_events\".\"tournament_id\" IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.season_matches": {
+ "name": "season_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_stage": {
+ "name": "match_stage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_round": {
+ "name": "match_round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matchday": {
+ "name": "matchday",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_series": {
+ "name": "is_series",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "status": {
+ "name": "status",
+ "type": "match_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_match_id": {
+ "name": "external_match_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_matches_external_id_unique": {
+ "name": "season_matches_external_id_unique",
+ "columns": [
+ {
+ "expression": "external_match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"season_matches\".\"external_match_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_sports_season_status_idx": {
+ "name": "season_matches_sports_season_status_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_sports_season_stage_round_idx": {
+ "name": "season_matches_sports_season_stage_round_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_stage",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_round",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_scoring_event_idx": {
+ "name": "season_matches_scoring_event_idx",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_matches_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_matches_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_matches_scoring_event_id_scoring_events_id_fk": {
+ "name": "season_matches_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_matches_participant1_id_season_participants_id_fk": {
+ "name": "season_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "season_matches_participant2_id_season_participants_id_fk": {
+ "name": "season_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "season_matches_winner_id_season_participants_id_fk": {
+ "name": "season_matches_winner_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_expected_values": {
+ "name": "season_participant_expected_values",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prob_first": {
+ "name": "prob_first",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_second": {
+ "name": "prob_second",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_third": {
+ "name": "prob_third",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fourth": {
+ "name": "prob_fourth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fifth": {
+ "name": "prob_fifth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_sixth": {
+ "name": "prob_sixth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_seventh": {
+ "name": "prob_seventh",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_eighth": {
+ "name": "prob_eighth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "expected_value": {
+ "name": "expected_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "source": {
+ "name": "source",
+ "type": "probability_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'manual'"
+ },
+ "source_odds": {
+ "name": "source_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_elo": {
+ "name": "source_elo",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_ev_participant_season_unique": {
+ "name": "participant_ev_participant_season_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_expected_values_participant_id_season_participants_id_fk": {
+ "name": "season_participant_expected_values_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_expected_values",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_expected_values_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_expected_values_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_expected_values",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_golf_skills": {
+ "name": "season_participant_golf_skills",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sg_total": {
+ "name": "sg_total",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "datagolf_rank": {
+ "name": "datagolf_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "masters_odds": {
+ "name": "masters_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "us_open_odds": {
+ "name": "us_open_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "open_championship_odds": {
+ "name": "open_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pga_championship_odds": {
+ "name": "pga_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_participant_golf_skills_unique": {
+ "name": "season_participant_golf_skills_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_golf_skills_participant_id_season_participants_id_fk": {
+ "name": "season_participant_golf_skills_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_golf_skills",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_golf_skills_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_golf_skills_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_golf_skills",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_qualifying_totals": {
+ "name": "season_participant_qualifying_totals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_qualifying_points": {
+ "name": "total_qualifying_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "events_scored": {
+ "name": "events_scored",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "final_ranking": {
+ "name": "final_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_participant_qualifying_totals_participant_id_season_participants_id_fk": {
+ "name": "season_participant_qualifying_totals_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_qualifying_totals",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_qualifying_totals_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_qualifying_totals_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_qualifying_totals",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_results": {
+ "name": "season_participant_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "final_position": {
+ "name": "final_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_partial_score": {
+ "name": "is_partial_score",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "qualifying_points": {
+ "name": "qualifying_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_participant_results_participant_id_season_participants_id_fk": {
+ "name": "season_participant_results_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_results_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_results_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_results",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_simulator_inputs": {
+ "name": "season_participant_simulator_inputs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_odds": {
+ "name": "source_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_elo": {
+ "name": "source_elo",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rating": {
+ "name": "rating",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_wins": {
+ "name": "projected_wins",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_table_points": {
+ "name": "projected_table_points",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seed": {
+ "name": "seed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "region": {
+ "name": "region",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_participant_simulator_inputs_unique": {
+ "name": "season_participant_simulator_inputs_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_participant_simulator_inputs_season_idx": {
+ "name": "season_participant_simulator_inputs_season_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_simulator_inputs_participant_id_season_participants_id_fk": {
+ "name": "season_participant_simulator_inputs_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_simulator_inputs",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_simulator_inputs_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_simulator_inputs_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_simulator_inputs",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participants": {
+ "name": "season_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "short_name": {
+ "name": "short_name",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expected_value": {
+ "name": "expected_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "vorp_value": {
+ "name": "vorp_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participants_sports_season_name_unique": {
+ "name": "participants_sports_season_name_unique",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participants_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participants_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participants",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participants_participant_id_participants_id_fk": {
+ "name": "season_participants_participant_id_participants_id_fk",
+ "tableFrom": "season_participants",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_sports": {
+ "name": "season_sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_sports_season_id_seasons_id_fk": {
+ "name": "season_sports_season_id_seasons_id_fk",
+ "tableFrom": "season_sports",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_sports_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_sports_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_sports",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_template_sports": {
+ "name": "season_template_sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_template_sports_template_sport_unique": {
+ "name": "season_template_sports_template_sport_unique",
+ "columns": [
+ {
+ "expression": "template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_template_sports_template_id_season_templates_id_fk": {
+ "name": "season_template_sports_template_id_season_templates_id_fk",
+ "tableFrom": "season_template_sports",
+ "tableTo": "season_templates",
+ "columnsFrom": [
+ "template_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_template_sports_sport_id_sports_id_fk": {
+ "name": "season_template_sports_sport_id_sports_id_fk",
+ "tableFrom": "season_template_sports",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_templates": {
+ "name": "season_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_templates_name_unique": {
+ "name": "season_templates_name_unique",
+ "columns": [
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.seasons": {
+ "name": "seasons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "season_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pre_draft'"
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_rounds": {
+ "name": "draft_rounds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 20
+ },
+ "flex_spots": {
+ "name": "flex_spots",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "draft_date_time": {
+ "name": "draft_date_time",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auto_start_draft": {
+ "name": "auto_start_draft",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "draft_initial_time": {
+ "name": "draft_initial_time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 120
+ },
+ "draft_increment_time": {
+ "name": "draft_increment_time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 30
+ },
+ "draft_timer_mode": {
+ "name": "draft_timer_mode",
+ "type": "draft_timer_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'chess_clock'"
+ },
+ "current_pick_number": {
+ "name": "current_pick_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1
+ },
+ "draft_started_at": {
+ "name": "draft_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_completed_at": {
+ "name": "draft_completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_paused": {
+ "name": "draft_paused",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "overnight_pause_mode": {
+ "name": "overnight_pause_mode",
+ "type": "overnight_pause_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "overnight_pause_start": {
+ "name": "overnight_pause_start",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "overnight_pause_end": {
+ "name": "overnight_pause_end",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "overnight_pause_timezone": {
+ "name": "overnight_pause_timezone",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invite_code": {
+ "name": "invite_code",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "points_for_1st": {
+ "name": "points_for_1st",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "points_for_2nd": {
+ "name": "points_for_2nd",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 70
+ },
+ "points_for_3rd": {
+ "name": "points_for_3rd",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 50
+ },
+ "points_for_4th": {
+ "name": "points_for_4th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 40
+ },
+ "points_for_5th": {
+ "name": "points_for_5th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 25
+ },
+ "points_for_6th": {
+ "name": "points_for_6th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 25
+ },
+ "points_for_7th": {
+ "name": "points_for_7th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 15
+ },
+ "points_for_8th": {
+ "name": "points_for_8th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 15
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "seasons_league_id_leagues_id_fk": {
+ "name": "seasons_league_id_leagues_id_fk",
+ "tableFrom": "seasons",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "seasons_template_id_season_templates_id_fk": {
+ "name": "seasons_template_id_season_templates_id_fk",
+ "tableFrom": "seasons",
+ "tableTo": "season_templates",
+ "columnsFrom": [
+ "template_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "seasons_invite_code_unique": {
+ "name": "seasons_invite_code_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "invite_code"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sessions": {
+ "name": "sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sessions_user_id_users_id_fk": {
+ "name": "sessions_user_id_users_id_fk",
+ "tableFrom": "sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "sessions_token_unique": {
+ "name": "sessions_token_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "token"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.simulator_profiles": {
+ "name": "simulator_profiles",
+ "schema": "",
+ "columns": {
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "default_config": {
+ "name": "default_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "input_schema": {
+ "name": "input_schema",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports": {
+ "name": "sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "sport_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon_url": {
+ "name": "icon_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exclude_from_homepage": {
+ "name": "exclude_from_homepage",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "sports_slug_unique": {
+ "name": "sports_slug_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "slug"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports_season_simulator_configs": {
+ "name": "sports_season_simulator_configs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "sports_season_simulator_config_unique": {
+ "name": "sports_season_simulator_config_unique",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sports_season_simulator_config_type_idx": {
+ "name": "sports_season_simulator_config_type_idx",
+ "columns": [
+ {
+ "expression": "simulator_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "sports_season_simulator_configs_sports_season_id_sports_seasons_id_fk": {
+ "name": "sports_season_simulator_configs_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "sports_season_simulator_configs",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports_seasons": {
+ "name": "sports_seasons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fantasy_season_id": {
+ "name": "fantasy_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "start_date": {
+ "name": "start_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_date": {
+ "name": "end_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "sports_season_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'upcoming'"
+ },
+ "external_season_id": {
+ "name": "external_season_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_type": {
+ "name": "scoring_type",
+ "type": "scoring_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_pattern": {
+ "name": "scoring_pattern",
+ "type": "scoring_pattern",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_majors": {
+ "name": "total_majors",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "majors_completed": {
+ "name": "majors_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "qualifying_points_finalized": {
+ "name": "qualifying_points_finalized",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "elo_calibration_exponent": {
+ "name": "elo_calibration_exponent",
+ "type": "numeric(3, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_min_rating": {
+ "name": "elo_min_rating",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1250
+ },
+ "elo_max_rating": {
+ "name": "elo_max_rating",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1750
+ },
+ "simulation_status": {
+ "name": "simulation_status",
+ "type": "simulation_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "standings_last_changed_at": {
+ "name": "standings_last_changed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_simulated_at": {
+ "name": "last_simulated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_on": {
+ "name": "draft_on",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_off": {
+ "name": "draft_off",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sports_seasons_sport_id_sports_id_fk": {
+ "name": "sports_seasons_sport_id_sports_id_fk",
+ "tableFrom": "sports_seasons",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "sports_seasons_fantasy_season_id_seasons_id_fk": {
+ "name": "sports_seasons_fantasy_season_id_seasons_id_fk",
+ "tableFrom": "sports_seasons",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "fantasy_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_ev_snapshots": {
+ "name": "team_ev_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_ev_snapshots_unique": {
+ "name": "team_ev_snapshots_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_ev_snapshots_team_id_teams_id_fk": {
+ "name": "team_ev_snapshots_team_id_teams_id_fk",
+ "tableFrom": "team_ev_snapshots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_ev_snapshots_season_id_seasons_id_fk": {
+ "name": "team_ev_snapshots_season_id_seasons_id_fk",
+ "tableFrom": "team_ev_snapshots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_score_events": {
+ "name": "team_score_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_event_name": {
+ "name": "scoring_event_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sport_name": {
+ "name": "sport_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_id": {
+ "name": "match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant_ids": {
+ "name": "participant_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "points_delta": {
+ "name": "points_delta",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_score_events_match_unique": {
+ "name": "team_score_events_match_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "match_id IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "team_score_events_event_unique": {
+ "name": "team_score_events_event_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "match_id IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_score_events_team_id_teams_id_fk": {
+ "name": "team_score_events_team_id_teams_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_score_events_season_id_seasons_id_fk": {
+ "name": "team_score_events_season_id_seasons_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_score_events_scoring_event_id_scoring_events_id_fk": {
+ "name": "team_score_events_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "team_score_events_match_id_playoff_matches_id_fk": {
+ "name": "team_score_events_match_id_playoff_matches_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_sport_scores": {
+ "name": "team_sport_scores",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "participants_completed": {
+ "name": "participants_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_total": {
+ "name": "participants_total",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "team_sport_scores_team_id_teams_id_fk": {
+ "name": "team_sport_scores_team_id_teams_id_fk",
+ "tableFrom": "team_sport_scores",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_sport_scores_sports_season_id_sports_seasons_id_fk": {
+ "name": "team_sport_scores_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "team_sport_scores",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_standings": {
+ "name": "team_standings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "current_rank": {
+ "name": "current_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_rank": {
+ "name": "previous_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_place_count": {
+ "name": "first_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "second_place_count": {
+ "name": "second_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "third_place_count": {
+ "name": "third_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fourth_place_count": {
+ "name": "fourth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fifth_place_count": {
+ "name": "fifth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "sixth_place_count": {
+ "name": "sixth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "seventh_place_count": {
+ "name": "seventh_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "eighth_place_count": {
+ "name": "eighth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_remaining": {
+ "name": "participants_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participants_finished": {
+ "name": "participants_finished",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "team_standings_team_id_teams_id_fk": {
+ "name": "team_standings_team_id_teams_id_fk",
+ "tableFrom": "team_standings",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_standings_season_id_seasons_id_fk": {
+ "name": "team_standings_season_id_seasons_id_fk",
+ "tableFrom": "team_standings",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_standings_snapshots": {
+ "name": "team_standings_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "rank": {
+ "name": "rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_place_count": {
+ "name": "first_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "second_place_count": {
+ "name": "second_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "third_place_count": {
+ "name": "third_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fourth_place_count": {
+ "name": "fourth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fifth_place_count": {
+ "name": "fifth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "sixth_place_count": {
+ "name": "sixth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "seventh_place_count": {
+ "name": "seventh_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "eighth_place_count": {
+ "name": "eighth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_remaining": {
+ "name": "participants_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participants_finished": {
+ "name": "participants_finished",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_standings_snapshots_unique": {
+ "name": "team_standings_snapshots_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_standings_snapshots_team_id_teams_id_fk": {
+ "name": "team_standings_snapshots_team_id_teams_id_fk",
+ "tableFrom": "team_standings_snapshots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_standings_snapshots_season_id_seasons_id_fk": {
+ "name": "team_standings_snapshots_season_id_seasons_id_fk",
+ "tableFrom": "team_standings_snapshots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.teams": {
+ "name": "teams",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "logo_url": {
+ "name": "logo_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "flag_config": {
+ "name": "flag_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avatar_type": {
+ "name": "avatar_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'owner'"
+ },
+ "owner_id": {
+ "name": "owner_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "teams_season_id_lower_name_unique": {
+ "name": "teams_season_id_lower_name_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"name\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "teams_season_id_seasons_id_fk": {
+ "name": "teams_season_id_seasons_id_fk",
+ "tableFrom": "teams",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_group_members": {
+ "name": "tournament_group_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_group_id": {
+ "name": "tournament_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "eliminated": {
+ "name": "eliminated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "tournament_group_members_tournament_group_id_tournament_groups_id_fk": {
+ "name": "tournament_group_members_tournament_group_id_tournament_groups_id_fk",
+ "tableFrom": "tournament_group_members",
+ "tableTo": "tournament_groups",
+ "columnsFrom": [
+ "tournament_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "tournament_group_members_participant_id_season_participants_id_fk": {
+ "name": "tournament_group_members_participant_id_season_participants_id_fk",
+ "tableFrom": "tournament_group_members",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_groups": {
+ "name": "tournament_groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_name": {
+ "name": "group_name",
+ "type": "varchar(10)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "tournament_groups_scoring_event_id_scoring_events_id_fk": {
+ "name": "tournament_groups_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "tournament_groups",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_results": {
+ "name": "tournament_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_id": {
+ "name": "tournament_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_score": {
+ "name": "raw_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tournament_results_tournament_participant_unique": {
+ "name": "tournament_results_tournament_participant_unique",
+ "columns": [
+ {
+ "expression": "tournament_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "tournament_results_tournament_id_tournaments_id_fk": {
+ "name": "tournament_results_tournament_id_tournaments_id_fk",
+ "tableFrom": "tournament_results",
+ "tableTo": "tournaments",
+ "columnsFrom": [
+ "tournament_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "tournament_results_participant_id_participants_id_fk": {
+ "name": "tournament_results_participant_id_participants_id_fk",
+ "tableFrom": "tournament_results",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournaments": {
+ "name": "tournaments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "surface": {
+ "name": "surface",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "location": {
+ "name": "location",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "tournament_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "external_key": {
+ "name": "external_key",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tournaments_sport_name_year_unique": {
+ "name": "tournaments_sport_name_year_unique",
+ "columns": [
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "year",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "tournaments_sport_id_sports_id_fk": {
+ "name": "tournaments_sport_id_sports_id_fk",
+ "tableFrom": "tournaments",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "clerk_id": {
+ "name": "clerk_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "username": {
+ "name": "username",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image_url": {
+ "name": "image_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "flag_config": {
+ "name": "flag_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "custom_avatar_url": {
+ "name": "custom_avatar_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avatar_type": {
+ "name": "avatar_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'flag'"
+ },
+ "is_admin": {
+ "name": "is_admin",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "discord_ping_enabled": {
+ "name": "discord_ping_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "draft_email_notifications_enabled": {
+ "name": "draft_email_notifications_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "last_data_request_at": {
+ "name": "last_data_request_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "users_username_lower_unique": {
+ "name": "users_username_lower_unique",
+ "columns": [
+ {
+ "expression": "lower(\"username\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "users_clerk_id_unique": {
+ "name": "users_clerk_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "clerk_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verifications": {
+ "name": "verifications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.watchlist": {
+ "name": "watchlist",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "watchlist_season_team_participant_unique": {
+ "name": "watchlist_season_team_participant_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "watchlist_season_id_seasons_id_fk": {
+ "name": "watchlist_season_id_seasons_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "watchlist_team_id_teams_id_fk": {
+ "name": "watchlist_team_id_teams_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "watchlist_participant_id_season_participants_id_fk": {
+ "name": "watchlist_participant_id_season_participants_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.audit_action": {
+ "name": "audit_action",
+ "schema": "public",
+ "values": [
+ "league_settings_changed",
+ "draft_settings_changed",
+ "scoring_rules_changed",
+ "sports_changed",
+ "draft_order_set",
+ "draft_order_randomized",
+ "draft_started",
+ "draft_paused",
+ "draft_resumed",
+ "draft_reset",
+ "draft_rollback",
+ "force_autopick",
+ "force_manual_pick",
+ "draft_pick_changed",
+ "time_bank_edited",
+ "brackt_resolved"
+ ]
+ },
+ "public.autodraft_mode": {
+ "name": "autodraft_mode",
+ "schema": "public",
+ "values": [
+ "next_pick",
+ "while_on"
+ ]
+ },
+ "public.draft_timer_mode": {
+ "name": "draft_timer_mode",
+ "schema": "public",
+ "values": [
+ "chess_clock",
+ "standard"
+ ]
+ },
+ "public.event_type": {
+ "name": "event_type",
+ "schema": "public",
+ "values": [
+ "playoff_game",
+ "major_tournament",
+ "final_standings",
+ "schedule_event"
+ ]
+ },
+ "public.match_status": {
+ "name": "match_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "in_progress",
+ "complete",
+ "canceled",
+ "postponed"
+ ]
+ },
+ "public.overnight_pause_mode": {
+ "name": "overnight_pause_mode",
+ "schema": "public",
+ "values": [
+ "none",
+ "league",
+ "per_user"
+ ]
+ },
+ "public.picked_by_type": {
+ "name": "picked_by_type",
+ "schema": "public",
+ "values": [
+ "owner",
+ "commissioner",
+ "admin",
+ "auto"
+ ]
+ },
+ "public.playoff_match_game_status": {
+ "name": "playoff_match_game_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "complete",
+ "postponed"
+ ]
+ },
+ "public.probability_source": {
+ "name": "probability_source",
+ "schema": "public",
+ "values": [
+ "manual",
+ "futures_odds",
+ "elo_simulation",
+ "performance_model"
+ ]
+ },
+ "public.scoring_pattern": {
+ "name": "scoring_pattern",
+ "schema": "public",
+ "values": [
+ "playoff_bracket",
+ "season_standings",
+ "qualifying_points"
+ ]
+ },
+ "public.scoring_type": {
+ "name": "scoring_type",
+ "schema": "public",
+ "values": [
+ "playoffs",
+ "regular_season",
+ "majors"
+ ]
+ },
+ "public.season_status": {
+ "name": "season_status",
+ "schema": "public",
+ "values": [
+ "pre_draft",
+ "draft",
+ "active",
+ "completed"
+ ]
+ },
+ "public.simulation_status": {
+ "name": "simulation_status",
+ "schema": "public",
+ "values": [
+ "idle",
+ "running",
+ "failed"
+ ]
+ },
+ "public.simulator_type": {
+ "name": "simulator_type",
+ "schema": "public",
+ "values": [
+ "f1_standings",
+ "indycar_standings",
+ "golf_qualifying_points",
+ "playoff_bracket",
+ "ucl_bracket",
+ "ncaam_bracket",
+ "ncaaw_bracket",
+ "nba_bracket",
+ "nhl_bracket",
+ "nfl_bracket",
+ "afl_bracket",
+ "epl_standings",
+ "snooker_bracket",
+ "tennis_qualifying_points",
+ "mlb_bracket",
+ "wnba_bracket",
+ "world_cup",
+ "darts_bracket",
+ "cs2_major_qualifying_points",
+ "ncaa_football_bracket",
+ "llws_bracket",
+ "college_hockey_bracket",
+ "brackt",
+ "nll_bracket",
+ "mls_bracket"
+ ]
+ },
+ "public.sport_type": {
+ "name": "sport_type",
+ "schema": "public",
+ "values": [
+ "team",
+ "individual"
+ ]
+ },
+ "public.sports_season_status": {
+ "name": "sports_season_status",
+ "schema": "public",
+ "values": [
+ "upcoming",
+ "active",
+ "completed"
+ ]
+ },
+ "public.tournament_status": {
+ "name": "tournament_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "in_progress",
+ "completed"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/0121_snapshot.json b/drizzle/meta/0121_snapshot.json
new file mode 100644
index 0000000..58acdb7
--- /dev/null
+++ b/drizzle/meta/0121_snapshot.json
@@ -0,0 +1,6718 @@
+{
+ "id": "d52f9777-c0fe-4ecd-a6b9-ad9500c21913",
+ "prevId": "ec076c22-a4af-4cf8-bd22-c8856382826d",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.accounts": {
+ "name": "accounts",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "accounts_user_id_users_id_fk": {
+ "name": "accounts_user_id_users_id_fk",
+ "tableFrom": "accounts",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.autodraft_settings": {
+ "name": "autodraft_settings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_enabled": {
+ "name": "is_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "mode": {
+ "name": "mode",
+ "type": "autodraft_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'next_pick'"
+ },
+ "queue_only": {
+ "name": "queue_only",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "autodraft_settings_season_id_seasons_id_fk": {
+ "name": "autodraft_settings_season_id_seasons_id_fk",
+ "tableFrom": "autodraft_settings",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "autodraft_settings_team_id_teams_id_fk": {
+ "name": "autodraft_settings_team_id_teams_id_fk",
+ "tableFrom": "autodraft_settings",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.commissioner_audit_log": {
+ "name": "commissioner_audit_log",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_user_id": {
+ "name": "actor_user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "actor_display_name": {
+ "name": "actor_display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "action": {
+ "name": "action",
+ "type": "audit_action",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "affected_team_ids": {
+ "name": "affected_team_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "details": {
+ "name": "details",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "audit_log_season_id_idx": {
+ "name": "audit_log_season_id_idx",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "commissioner_audit_log_season_id_seasons_id_fk": {
+ "name": "commissioner_audit_log_season_id_seasons_id_fk",
+ "tableFrom": "commissioner_audit_log",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "commissioner_audit_log_league_id_leagues_id_fk": {
+ "name": "commissioner_audit_log_league_id_leagues_id_fk",
+ "tableFrom": "commissioner_audit_log",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.commissioners": {
+ "name": "commissioners",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "commissioners_league_id_leagues_id_fk": {
+ "name": "commissioners_league_id_leagues_id_fk",
+ "tableFrom": "commissioners",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.cs2_major_stage_results": {
+ "name": "cs2_major_stage_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_entry": {
+ "name": "stage_entry",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "stage_eliminated": {
+ "name": "stage_eliminated",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "stage_eliminated_wins": {
+ "name": "stage_eliminated_wins",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "final_placement": {
+ "name": "final_placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "cs2_major_stage_results_unique": {
+ "name": "cs2_major_stage_results_unique",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "cs2_major_stage_results_scoring_event_id_scoring_events_id_fk": {
+ "name": "cs2_major_stage_results_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "cs2_major_stage_results",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "cs2_major_stage_results_participant_id_season_participants_id_fk": {
+ "name": "cs2_major_stage_results_participant_id_season_participants_id_fk",
+ "tableFrom": "cs2_major_stage_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_picks": {
+ "name": "draft_picks",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pick_number": {
+ "name": "pick_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "round": {
+ "name": "round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "pick_in_round": {
+ "name": "pick_in_round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picked_by_user_id": {
+ "name": "picked_by_user_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picked_by_type": {
+ "name": "picked_by_type",
+ "type": "picked_by_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time_used": {
+ "name": "time_used",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "draft_picks_season_pick_unique": {
+ "name": "draft_picks_season_pick_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "pick_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "draft_picks_season_id_seasons_id_fk": {
+ "name": "draft_picks_season_id_seasons_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_picks_team_id_teams_id_fk": {
+ "name": "draft_picks_team_id_teams_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_picks_participant_id_season_participants_id_fk": {
+ "name": "draft_picks_participant_id_season_participants_id_fk",
+ "tableFrom": "draft_picks",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_queue": {
+ "name": "draft_queue",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "queue_position": {
+ "name": "queue_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_queue_season_id_seasons_id_fk": {
+ "name": "draft_queue_season_id_seasons_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_queue_team_id_teams_id_fk": {
+ "name": "draft_queue_team_id_teams_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_queue_participant_id_season_participants_id_fk": {
+ "name": "draft_queue_participant_id_season_participants_id_fk",
+ "tableFrom": "draft_queue",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_slots": {
+ "name": "draft_slots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_order": {
+ "name": "draft_order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_slots_season_id_seasons_id_fk": {
+ "name": "draft_slots_season_id_seasons_id_fk",
+ "tableFrom": "draft_slots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_slots_team_id_teams_id_fk": {
+ "name": "draft_slots_team_id_teams_id_fk",
+ "tableFrom": "draft_slots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.draft_timers": {
+ "name": "draft_timers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time_remaining": {
+ "name": "time_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "picks_expires_at": {
+ "name": "picks_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "picks_started_at": {
+ "name": "picks_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "draft_timers_season_id_seasons_id_fk": {
+ "name": "draft_timers_season_id_seasons_id_fk",
+ "tableFrom": "draft_timers",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "draft_timers_team_id_teams_id_fk": {
+ "name": "draft_timers_team_id_teams_id_fk",
+ "tableFrom": "draft_timers",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.event_results": {
+ "name": "event_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_participant_id": {
+ "name": "season_participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "qualifying_points_awarded": {
+ "name": "qualifying_points_awarded",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "eliminated": {
+ "name": "eliminated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_score": {
+ "name": "raw_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "not_participating": {
+ "name": "not_participating",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "event_results_event_participant_unique": {
+ "name": "event_results_event_participant_unique",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "event_results_scoring_event_id_scoring_events_id_fk": {
+ "name": "event_results_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "event_results",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "event_results_season_participant_id_season_participants_id_fk": {
+ "name": "event_results_season_participant_id_season_participants_id_fk",
+ "tableFrom": "event_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "season_participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.group_stage_matches": {
+ "name": "group_stage_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_group_id": {
+ "name": "tournament_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "matchday": {
+ "name": "matchday",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "group_stage_matches_group_pair_unique": {
+ "name": "group_stage_matches_group_pair_unique",
+ "columns": [
+ {
+ "expression": "tournament_group_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant1_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant2_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "group_stage_matches_tournament_group_id_tournament_groups_id_fk": {
+ "name": "group_stage_matches_tournament_group_id_tournament_groups_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "tournament_groups",
+ "columnsFrom": [
+ "tournament_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "group_stage_matches_participant1_id_season_participants_id_fk": {
+ "name": "group_stage_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "group_stage_matches_participant2_id_season_participants_id_fk": {
+ "name": "group_stage_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "group_stage_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.leagues": {
+ "name": "leagues",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_by": {
+ "name": "created_by",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_season_id": {
+ "name": "current_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_public_draft_board": {
+ "name": "is_public_draft_board",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "discord_webhook_url": {
+ "name": "discord_webhook_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "discord_picks_announcement_enabled": {
+ "name": "discord_picks_announcement_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.match_sub_games": {
+ "name": "match_sub_games",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_match_id": {
+ "name": "season_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_number": {
+ "name": "game_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_label": {
+ "name": "game_label",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "match_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_game_id": {
+ "name": "external_game_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "match_sub_games_match_game_number_unique": {
+ "name": "match_sub_games_match_game_number_unique",
+ "columns": [
+ {
+ "expression": "season_match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "game_number",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "match_sub_games_season_match_id_season_matches_id_fk": {
+ "name": "match_sub_games_season_match_id_season_matches_id_fk",
+ "tableFrom": "match_sub_games",
+ "tableTo": "season_matches",
+ "columnsFrom": [
+ "season_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "match_sub_games_winner_id_season_participants_id_fk": {
+ "name": "match_sub_games_winner_id_season_participants_id_fk",
+ "tableFrom": "match_sub_games",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_ev_snapshots": {
+ "name": "participant_ev_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prob_first": {
+ "name": "prob_first",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_second": {
+ "name": "prob_second",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_third": {
+ "name": "prob_third",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fourth": {
+ "name": "prob_fourth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fifth": {
+ "name": "prob_fifth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_sixth": {
+ "name": "prob_sixth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_seventh": {
+ "name": "prob_seventh",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_eighth": {
+ "name": "prob_eighth",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "calculated_ev": {
+ "name": "calculated_ev",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "source": {
+ "name": "source",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_ev_snapshots_unique": {
+ "name": "participant_ev_snapshots_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_ev_snapshots_participant_id_season_participants_id_fk": {
+ "name": "participant_ev_snapshots_participant_id_season_participants_id_fk",
+ "tableFrom": "participant_ev_snapshots",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "participant_ev_snapshots_sports_season_id_sports_seasons_id_fk": {
+ "name": "participant_ev_snapshots_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "participant_ev_snapshots",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_golf_skills": {
+ "name": "participant_golf_skills",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sg_total": {
+ "name": "sg_total",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "datagolf_rank": {
+ "name": "datagolf_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "masters_odds": {
+ "name": "masters_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "us_open_odds": {
+ "name": "us_open_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "open_championship_odds": {
+ "name": "open_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pga_championship_odds": {
+ "name": "pga_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_golf_skills_participant_unique": {
+ "name": "participant_golf_skills_participant_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_golf_skills_participant_id_participants_id_fk": {
+ "name": "participant_golf_skills_participant_id_participants_id_fk",
+ "tableFrom": "participant_golf_skills",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_season_results": {
+ "name": "participant_season_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_points": {
+ "name": "current_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "current_position": {
+ "name": "current_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "psr_participant_season_idx": {
+ "name": "psr_participant_season_idx",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_season_results_participant_id_season_participants_id_fk": {
+ "name": "participant_season_results_participant_id_season_participants_id_fk",
+ "tableFrom": "participant_season_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "participant_season_results_sports_season_id_sports_seasons_id_fk": {
+ "name": "participant_season_results_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "participant_season_results",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participant_surface_elos": {
+ "name": "participant_surface_elos",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_hard": {
+ "name": "elo_hard",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_clay": {
+ "name": "elo_clay",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_grass": {
+ "name": "elo_grass",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_surface_elos_participant_unique": {
+ "name": "participant_surface_elos_participant_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participant_surface_elos_participant_id_participants_id_fk": {
+ "name": "participant_surface_elos_participant_id_participants_id_fk",
+ "tableFrom": "participant_surface_elos",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.participants": {
+ "name": "participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_key": {
+ "name": "external_key",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participants_sport_name_unique": {
+ "name": "participants_sport_name_unique",
+ "columns": [
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "participants_sport_id_sports_id_fk": {
+ "name": "participants_sport_id_sports_id_fk",
+ "tableFrom": "participants",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.pending_standings_mappings": {
+ "name": "pending_standings_mappings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "external_team_id": {
+ "name": "external_team_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_name": {
+ "name": "team_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "standing_data": {
+ "name": "standing_data",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "psm_season_external_id_idx": {
+ "name": "psm_season_external_id_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "external_team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "pending_standings_mappings_sports_season_id_sports_seasons_id_fk": {
+ "name": "pending_standings_mappings_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "pending_standings_mappings",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_match_games": {
+ "name": "playoff_match_games",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "playoff_match_id": {
+ "name": "playoff_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "game_number": {
+ "name": "game_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "playoff_match_game_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_match_games_playoff_match_id_playoff_matches_id_fk": {
+ "name": "playoff_match_games_playoff_match_id_playoff_matches_id_fk",
+ "tableFrom": "playoff_match_games",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "playoff_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_match_games_winner_id_season_participants_id_fk": {
+ "name": "playoff_match_games_winner_id_season_participants_id_fk",
+ "tableFrom": "playoff_match_games",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_match_odds": {
+ "name": "playoff_match_odds",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "playoff_match_id": {
+ "name": "playoff_match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "moneyline_odds": {
+ "name": "moneyline_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "implied_probability": {
+ "name": "implied_probability",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "odds_source": {
+ "name": "odds_source",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "recorded_at": {
+ "name": "recorded_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_match_odds_playoff_match_id_playoff_matches_id_fk": {
+ "name": "playoff_match_odds_playoff_match_id_playoff_matches_id_fk",
+ "tableFrom": "playoff_match_odds",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "playoff_match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_match_odds_participant_id_season_participants_id_fk": {
+ "name": "playoff_match_odds_participant_id_season_participants_id_fk",
+ "tableFrom": "playoff_match_odds",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.playoff_matches": {
+ "name": "playoff_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "round": {
+ "name": "round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "match_number": {
+ "name": "match_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "loser_id": {
+ "name": "loser_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_scoring": {
+ "name": "is_scoring",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "template_round": {
+ "name": "template_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seed_info": {
+ "name": "seed_info",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_match_id": {
+ "name": "external_match_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "playoff_matches_scoring_event_id_scoring_events_id_fk": {
+ "name": "playoff_matches_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_participant1_id_season_participants_id_fk": {
+ "name": "playoff_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_participant2_id_season_participants_id_fk": {
+ "name": "playoff_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_winner_id_season_participants_id_fk": {
+ "name": "playoff_matches_winner_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "playoff_matches_loser_id_season_participants_id_fk": {
+ "name": "playoff_matches_loser_id_season_participants_id_fk",
+ "tableFrom": "playoff_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "loser_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.qualifying_point_config": {
+ "name": "qualifying_point_config",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "points": {
+ "name": "points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "qualifying_point_config_sports_season_id_sports_seasons_id_fk": {
+ "name": "qualifying_point_config_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "qualifying_point_config",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.regular_season_standings": {
+ "name": "regular_season_standings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "wins": {
+ "name": "wins",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "losses": {
+ "name": "losses",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "ot_losses": {
+ "name": "ot_losses",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ties": {
+ "name": "ties",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "table_points": {
+ "name": "table_points",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goals_for": {
+ "name": "goals_for",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goals_against": {
+ "name": "goals_against",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal_difference": {
+ "name": "goal_difference",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "win_pct": {
+ "name": "win_pct",
+ "type": "numeric(5, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "games_played": {
+ "name": "games_played",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "games_back": {
+ "name": "games_back",
+ "type": "numeric(5, 1)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conference": {
+ "name": "conference",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "division": {
+ "name": "division",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conference_rank": {
+ "name": "conference_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "division_rank": {
+ "name": "division_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "league_rank": {
+ "name": "league_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "streak": {
+ "name": "streak",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_ten": {
+ "name": "last_ten",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "home_record": {
+ "name": "home_record",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "away_record": {
+ "name": "away_record",
+ "type": "varchar(15)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_team_id": {
+ "name": "external_team_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "srs": {
+ "name": "srs",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "synced_at": {
+ "name": "synced_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "rss_participant_season_idx": {
+ "name": "rss_participant_season_idx",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "regular_season_standings_participant_id_season_participants_id_fk": {
+ "name": "regular_season_standings_participant_id_season_participants_id_fk",
+ "tableFrom": "regular_season_standings",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "regular_season_standings_sports_season_id_sports_seasons_id_fk": {
+ "name": "regular_season_standings_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "regular_season_standings",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scoring_events": {
+ "name": "scoring_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tournament_id": {
+ "name": "tournament_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "event_date": {
+ "name": "event_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_starts_at": {
+ "name": "event_starts_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "event_type": {
+ "name": "event_type",
+ "type": "event_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "playoff_round": {
+ "name": "playoff_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_qualifying_event": {
+ "name": "is_qualifying_event",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "bracket_template_id": {
+ "name": "bracket_template_id",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_starts_at_round": {
+ "name": "scoring_starts_at_round",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "bracket_region_config": {
+ "name": "bracket_region_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_complete": {
+ "name": "is_complete",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "scoring_events_sports_season_id_sports_seasons_id_fk": {
+ "name": "scoring_events_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "scoring_events",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "scoring_events_tournament_id_tournaments_id_fk": {
+ "name": "scoring_events_tournament_id_tournaments_id_fk",
+ "tableFrom": "scoring_events",
+ "tableTo": "tournaments",
+ "columnsFrom": [
+ "tournament_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "scoring_events_qualifying_require_tournament": {
+ "name": "scoring_events_qualifying_require_tournament",
+ "value": "NOT \"scoring_events\".\"is_qualifying_event\" OR \"scoring_events\".\"tournament_id\" IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ },
+ "public.season_matches": {
+ "name": "season_matches",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_id": {
+ "name": "participant1_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_id": {
+ "name": "participant2_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "winner_id": {
+ "name": "winner_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant1_score": {
+ "name": "participant1_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant2_score": {
+ "name": "participant2_score",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_stage": {
+ "name": "match_stage",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_round": {
+ "name": "match_round",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "matchday": {
+ "name": "matchday",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_series": {
+ "name": "is_series",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "status": {
+ "name": "status",
+ "type": "match_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "scheduled_at": {
+ "name": "scheduled_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "started_at": {
+ "name": "started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "completed_at": {
+ "name": "completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_match_id": {
+ "name": "external_match_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_matches_external_id_unique": {
+ "name": "season_matches_external_id_unique",
+ "columns": [
+ {
+ "expression": "external_match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "\"season_matches\".\"external_match_id\" IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_sports_season_status_idx": {
+ "name": "season_matches_sports_season_status_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "status",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_sports_season_stage_round_idx": {
+ "name": "season_matches_sports_season_stage_round_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_stage",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_round",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_matches_scoring_event_idx": {
+ "name": "season_matches_scoring_event_idx",
+ "columns": [
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_matches_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_matches_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_matches_scoring_event_id_scoring_events_id_fk": {
+ "name": "season_matches_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_matches_participant1_id_season_participants_id_fk": {
+ "name": "season_matches_participant1_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant1_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "season_matches_participant2_id_season_participants_id_fk": {
+ "name": "season_matches_participant2_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant2_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "season_matches_winner_id_season_participants_id_fk": {
+ "name": "season_matches_winner_id_season_participants_id_fk",
+ "tableFrom": "season_matches",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "winner_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_expected_values": {
+ "name": "season_participant_expected_values",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "prob_first": {
+ "name": "prob_first",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_second": {
+ "name": "prob_second",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_third": {
+ "name": "prob_third",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fourth": {
+ "name": "prob_fourth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_fifth": {
+ "name": "prob_fifth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_sixth": {
+ "name": "prob_sixth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_seventh": {
+ "name": "prob_seventh",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "prob_eighth": {
+ "name": "prob_eighth",
+ "type": "numeric(6, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "expected_value": {
+ "name": "expected_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "source": {
+ "name": "source",
+ "type": "probability_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'manual'"
+ },
+ "source_odds": {
+ "name": "source_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_elo": {
+ "name": "source_elo",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participant_ev_participant_season_unique": {
+ "name": "participant_ev_participant_season_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_expected_values_participant_id_season_participants_id_fk": {
+ "name": "season_participant_expected_values_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_expected_values",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_expected_values_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_expected_values_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_expected_values",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_golf_skills": {
+ "name": "season_participant_golf_skills",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sg_total": {
+ "name": "sg_total",
+ "type": "numeric(5, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "datagolf_rank": {
+ "name": "datagolf_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "masters_odds": {
+ "name": "masters_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "us_open_odds": {
+ "name": "us_open_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "open_championship_odds": {
+ "name": "open_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "pga_championship_odds": {
+ "name": "pga_championship_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_participant_golf_skills_unique": {
+ "name": "season_participant_golf_skills_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_golf_skills_participant_id_season_participants_id_fk": {
+ "name": "season_participant_golf_skills_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_golf_skills",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_golf_skills_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_golf_skills_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_golf_skills",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_qualifying_totals": {
+ "name": "season_participant_qualifying_totals",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_qualifying_points": {
+ "name": "total_qualifying_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "events_scored": {
+ "name": "events_scored",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "final_ranking": {
+ "name": "final_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_participant_qualifying_totals_participant_id_season_participants_id_fk": {
+ "name": "season_participant_qualifying_totals_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_qualifying_totals",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_qualifying_totals_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_qualifying_totals_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_qualifying_totals",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_results": {
+ "name": "season_participant_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "final_position": {
+ "name": "final_position",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_partial_score": {
+ "name": "is_partial_score",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "qualifying_points": {
+ "name": "qualifying_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_participant_results_participant_id_season_participants_id_fk": {
+ "name": "season_participant_results_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_results",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_results_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_results_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_results",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participant_simulator_inputs": {
+ "name": "season_participant_simulator_inputs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "source_odds": {
+ "name": "source_odds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "source_elo": {
+ "name": "source_elo",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "world_ranking": {
+ "name": "world_ranking",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rating": {
+ "name": "rating",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_wins": {
+ "name": "projected_wins",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_table_points": {
+ "name": "projected_table_points",
+ "type": "numeric(6, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "seed": {
+ "name": "seed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "region": {
+ "name": "region",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "metadata": {
+ "name": "metadata",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_participant_simulator_inputs_unique": {
+ "name": "season_participant_simulator_inputs_unique",
+ "columns": [
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "season_participant_simulator_inputs_season_idx": {
+ "name": "season_participant_simulator_inputs_season_idx",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participant_simulator_inputs_participant_id_season_participants_id_fk": {
+ "name": "season_participant_simulator_inputs_participant_id_season_participants_id_fk",
+ "tableFrom": "season_participant_simulator_inputs",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participant_simulator_inputs_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participant_simulator_inputs_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participant_simulator_inputs",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_participants": {
+ "name": "season_participants",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "short_name": {
+ "name": "short_name",
+ "type": "varchar(100)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "external_id": {
+ "name": "external_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expected_value": {
+ "name": "expected_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "vorp_value": {
+ "name": "vorp_value",
+ "type": "numeric(10, 4)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "participants_sports_season_name_unique": {
+ "name": "participants_sports_season_name_unique",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_participants_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_participants_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_participants",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_participants_participant_id_participants_id_fk": {
+ "name": "season_participants_participant_id_participants_id_fk",
+ "tableFrom": "season_participants",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "restrict",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_sports": {
+ "name": "season_sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "season_sports_season_id_seasons_id_fk": {
+ "name": "season_sports_season_id_seasons_id_fk",
+ "tableFrom": "season_sports",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_sports_sports_season_id_sports_seasons_id_fk": {
+ "name": "season_sports_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "season_sports",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_template_sports": {
+ "name": "season_template_sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_template_sports_template_sport_unique": {
+ "name": "season_template_sports_template_sport_unique",
+ "columns": [
+ {
+ "expression": "template_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "season_template_sports_template_id_season_templates_id_fk": {
+ "name": "season_template_sports_template_id_season_templates_id_fk",
+ "tableFrom": "season_template_sports",
+ "tableTo": "season_templates",
+ "columnsFrom": [
+ "template_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "season_template_sports_sport_id_sports_id_fk": {
+ "name": "season_template_sports_sport_id_sports_id_fk",
+ "tableFrom": "season_template_sports",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.season_templates": {
+ "name": "season_templates",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "season_templates_name_unique": {
+ "name": "season_templates_name_unique",
+ "columns": [
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.seasons": {
+ "name": "seasons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "league_id": {
+ "name": "league_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "status": {
+ "name": "status",
+ "type": "season_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'pre_draft'"
+ },
+ "template_id": {
+ "name": "template_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_rounds": {
+ "name": "draft_rounds",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 20
+ },
+ "flex_spots": {
+ "name": "flex_spots",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "draft_date_time": {
+ "name": "draft_date_time",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "auto_start_draft": {
+ "name": "auto_start_draft",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "draft_initial_time": {
+ "name": "draft_initial_time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 120
+ },
+ "draft_increment_time": {
+ "name": "draft_increment_time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 30
+ },
+ "draft_timer_mode": {
+ "name": "draft_timer_mode",
+ "type": "draft_timer_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'chess_clock'"
+ },
+ "current_pick_number": {
+ "name": "current_pick_number",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1
+ },
+ "draft_started_at": {
+ "name": "draft_started_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_completed_at": {
+ "name": "draft_completed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_paused": {
+ "name": "draft_paused",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "overnight_pause_mode": {
+ "name": "overnight_pause_mode",
+ "type": "overnight_pause_mode",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "overnight_pause_start": {
+ "name": "overnight_pause_start",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "overnight_pause_end": {
+ "name": "overnight_pause_end",
+ "type": "varchar(5)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "overnight_pause_timezone": {
+ "name": "overnight_pause_timezone",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "invite_code": {
+ "name": "invite_code",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "points_for_1st": {
+ "name": "points_for_1st",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 100
+ },
+ "points_for_2nd": {
+ "name": "points_for_2nd",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 70
+ },
+ "points_for_3rd": {
+ "name": "points_for_3rd",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 50
+ },
+ "points_for_4th": {
+ "name": "points_for_4th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 40
+ },
+ "points_for_5th": {
+ "name": "points_for_5th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 25
+ },
+ "points_for_6th": {
+ "name": "points_for_6th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 25
+ },
+ "points_for_7th": {
+ "name": "points_for_7th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 15
+ },
+ "points_for_8th": {
+ "name": "points_for_8th",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 15
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "seasons_league_id_leagues_id_fk": {
+ "name": "seasons_league_id_leagues_id_fk",
+ "tableFrom": "seasons",
+ "tableTo": "leagues",
+ "columnsFrom": [
+ "league_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "seasons_template_id_season_templates_id_fk": {
+ "name": "seasons_template_id_season_templates_id_fk",
+ "tableFrom": "seasons",
+ "tableTo": "season_templates",
+ "columnsFrom": [
+ "template_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "seasons_invite_code_unique": {
+ "name": "seasons_invite_code_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "invite_code"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sessions": {
+ "name": "sessions",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sessions_user_id_users_id_fk": {
+ "name": "sessions_user_id_users_id_fk",
+ "tableFrom": "sessions",
+ "tableTo": "users",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "sessions_token_unique": {
+ "name": "sessions_token_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "token"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.simulator_profiles": {
+ "name": "simulator_profiles",
+ "schema": "",
+ "columns": {
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "default_config": {
+ "name": "default_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "input_schema": {
+ "name": "input_schema",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports": {
+ "name": "sports",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "sport_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon_url": {
+ "name": "icon_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exclude_from_homepage": {
+ "name": "exclude_from_homepage",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "sports_slug_unique": {
+ "name": "sports_slug_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "slug"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports_season_simulator_configs": {
+ "name": "sports_season_simulator_configs",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "simulator_type": {
+ "name": "simulator_type",
+ "type": "simulator_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "config": {
+ "name": "config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "sports_season_simulator_config_unique": {
+ "name": "sports_season_simulator_config_unique",
+ "columns": [
+ {
+ "expression": "sports_season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "sports_season_simulator_config_type_idx": {
+ "name": "sports_season_simulator_config_type_idx",
+ "columns": [
+ {
+ "expression": "simulator_type",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "sports_season_simulator_configs_sports_season_id_sports_seasons_id_fk": {
+ "name": "sports_season_simulator_configs_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "sports_season_simulator_configs",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sports_seasons": {
+ "name": "sports_seasons",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fantasy_season_id": {
+ "name": "fantasy_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "start_date": {
+ "name": "start_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "end_date": {
+ "name": "end_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "sports_season_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'upcoming'"
+ },
+ "external_season_id": {
+ "name": "external_season_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_type": {
+ "name": "scoring_type",
+ "type": "scoring_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_pattern": {
+ "name": "scoring_pattern",
+ "type": "scoring_pattern",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_majors": {
+ "name": "total_majors",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "majors_completed": {
+ "name": "majors_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "qualifying_points_finalized": {
+ "name": "qualifying_points_finalized",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "elo_calibration_exponent": {
+ "name": "elo_calibration_exponent",
+ "type": "numeric(3, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "elo_min_rating": {
+ "name": "elo_min_rating",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1250
+ },
+ "elo_max_rating": {
+ "name": "elo_max_rating",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 1750
+ },
+ "simulation_status": {
+ "name": "simulation_status",
+ "type": "simulation_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'idle'"
+ },
+ "standings_last_changed_at": {
+ "name": "standings_last_changed_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_simulated_at": {
+ "name": "last_simulated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "draft_on": {
+ "name": "draft_on",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "draft_off": {
+ "name": "draft_off",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sports_seasons_sport_id_sports_id_fk": {
+ "name": "sports_seasons_sport_id_sports_id_fk",
+ "tableFrom": "sports_seasons",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "sports_seasons_fantasy_season_id_seasons_id_fk": {
+ "name": "sports_seasons_fantasy_season_id_seasons_id_fk",
+ "tableFrom": "sports_seasons",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "fantasy_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_ev_snapshots": {
+ "name": "team_ev_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_ev_snapshots_unique": {
+ "name": "team_ev_snapshots_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_ev_snapshots_team_id_teams_id_fk": {
+ "name": "team_ev_snapshots_team_id_teams_id_fk",
+ "tableFrom": "team_ev_snapshots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_ev_snapshots_season_id_seasons_id_fk": {
+ "name": "team_ev_snapshots_season_id_seasons_id_fk",
+ "tableFrom": "team_ev_snapshots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_score_events": {
+ "name": "team_score_events",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scoring_event_name": {
+ "name": "scoring_event_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sport_name": {
+ "name": "sport_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "match_id": {
+ "name": "match_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participant_ids": {
+ "name": "participant_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "points_delta": {
+ "name": "points_delta",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "occurred_at": {
+ "name": "occurred_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_score_events_match_unique": {
+ "name": "team_score_events_match_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "match_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "match_id IS NOT NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ },
+ "team_score_events_event_unique": {
+ "name": "team_score_events_event_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "scoring_event_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "where": "match_id IS NULL",
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_score_events_team_id_teams_id_fk": {
+ "name": "team_score_events_team_id_teams_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_score_events_season_id_seasons_id_fk": {
+ "name": "team_score_events_season_id_seasons_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_score_events_scoring_event_id_scoring_events_id_fk": {
+ "name": "team_score_events_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "team_score_events_match_id_playoff_matches_id_fk": {
+ "name": "team_score_events_match_id_playoff_matches_id_fk",
+ "tableFrom": "team_score_events",
+ "tableTo": "playoff_matches",
+ "columnsFrom": [
+ "match_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_sport_scores": {
+ "name": "team_sport_scores",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sports_season_id": {
+ "name": "sports_season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "participants_completed": {
+ "name": "participants_completed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_total": {
+ "name": "participants_total",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "team_sport_scores_team_id_teams_id_fk": {
+ "name": "team_sport_scores_team_id_teams_id_fk",
+ "tableFrom": "team_sport_scores",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_sport_scores_sports_season_id_sports_seasons_id_fk": {
+ "name": "team_sport_scores_sports_season_id_sports_seasons_id_fk",
+ "tableFrom": "team_sport_scores",
+ "tableTo": "sports_seasons",
+ "columnsFrom": [
+ "sports_season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_standings": {
+ "name": "team_standings",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "current_rank": {
+ "name": "current_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "previous_rank": {
+ "name": "previous_rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_place_count": {
+ "name": "first_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "second_place_count": {
+ "name": "second_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "third_place_count": {
+ "name": "third_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fourth_place_count": {
+ "name": "fourth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fifth_place_count": {
+ "name": "fifth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "sixth_place_count": {
+ "name": "sixth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "seventh_place_count": {
+ "name": "seventh_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "eighth_place_count": {
+ "name": "eighth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_remaining": {
+ "name": "participants_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participants_finished": {
+ "name": "participants_finished",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "calculated_at": {
+ "name": "calculated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "team_standings_team_id_teams_id_fk": {
+ "name": "team_standings_team_id_teams_id_fk",
+ "tableFrom": "team_standings",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_standings_season_id_seasons_id_fk": {
+ "name": "team_standings_season_id_seasons_id_fk",
+ "tableFrom": "team_standings",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.team_standings_snapshots": {
+ "name": "team_standings_snapshots",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "snapshot_date": {
+ "name": "snapshot_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_points": {
+ "name": "total_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'0'"
+ },
+ "rank": {
+ "name": "rank",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "first_place_count": {
+ "name": "first_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "second_place_count": {
+ "name": "second_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "third_place_count": {
+ "name": "third_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fourth_place_count": {
+ "name": "fourth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "fifth_place_count": {
+ "name": "fifth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "sixth_place_count": {
+ "name": "sixth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "seventh_place_count": {
+ "name": "seventh_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "eighth_place_count": {
+ "name": "eighth_place_count",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "participants_remaining": {
+ "name": "participants_remaining",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "actual_points": {
+ "name": "actual_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "projected_points": {
+ "name": "projected_points",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "participants_finished": {
+ "name": "participants_finished",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "team_standings_snapshots_unique": {
+ "name": "team_standings_snapshots_unique",
+ "columns": [
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "snapshot_date",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "team_standings_snapshots_team_id_teams_id_fk": {
+ "name": "team_standings_snapshots_team_id_teams_id_fk",
+ "tableFrom": "team_standings_snapshots",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "team_standings_snapshots_season_id_seasons_id_fk": {
+ "name": "team_standings_snapshots_season_id_seasons_id_fk",
+ "tableFrom": "team_standings_snapshots",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.teams": {
+ "name": "teams",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "logo_url": {
+ "name": "logo_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "flag_config": {
+ "name": "flag_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avatar_type": {
+ "name": "avatar_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'owner'"
+ },
+ "owner_id": {
+ "name": "owner_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "teams_season_id_lower_name_unique": {
+ "name": "teams_season_id_lower_name_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "lower(\"name\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "teams_season_id_seasons_id_fk": {
+ "name": "teams_season_id_seasons_id_fk",
+ "tableFrom": "teams",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_group_members": {
+ "name": "tournament_group_members",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_group_id": {
+ "name": "tournament_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "eliminated": {
+ "name": "eliminated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "tournament_group_members_tournament_group_id_tournament_groups_id_fk": {
+ "name": "tournament_group_members_tournament_group_id_tournament_groups_id_fk",
+ "tableFrom": "tournament_group_members",
+ "tableTo": "tournament_groups",
+ "columnsFrom": [
+ "tournament_group_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "tournament_group_members_participant_id_season_participants_id_fk": {
+ "name": "tournament_group_members_participant_id_season_participants_id_fk",
+ "tableFrom": "tournament_group_members",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_groups": {
+ "name": "tournament_groups",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "scoring_event_id": {
+ "name": "scoring_event_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "group_name": {
+ "name": "group_name",
+ "type": "varchar(10)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "tournament_groups_scoring_event_id_scoring_events_id_fk": {
+ "name": "tournament_groups_scoring_event_id_scoring_events_id_fk",
+ "tableFrom": "tournament_groups",
+ "tableTo": "scoring_events",
+ "columnsFrom": [
+ "scoring_event_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournament_results": {
+ "name": "tournament_results",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "tournament_id": {
+ "name": "tournament_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "placement": {
+ "name": "placement",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "raw_score": {
+ "name": "raw_score",
+ "type": "numeric(10, 2)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tournament_results_tournament_participant_unique": {
+ "name": "tournament_results_tournament_participant_unique",
+ "columns": [
+ {
+ "expression": "tournament_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "tournament_results_tournament_id_tournaments_id_fk": {
+ "name": "tournament_results_tournament_id_tournaments_id_fk",
+ "tableFrom": "tournament_results",
+ "tableTo": "tournaments",
+ "columnsFrom": [
+ "tournament_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "tournament_results_participant_id_participants_id_fk": {
+ "name": "tournament_results_participant_id_participants_id_fk",
+ "tableFrom": "tournament_results",
+ "tableTo": "participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.tournaments": {
+ "name": "tournaments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "sport_id": {
+ "name": "sport_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "year": {
+ "name": "year",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starts_at": {
+ "name": "starts_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ends_at": {
+ "name": "ends_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "surface": {
+ "name": "surface",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "location": {
+ "name": "location",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "tournament_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'scheduled'"
+ },
+ "external_key": {
+ "name": "external_key",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "tournaments_sport_name_year_unique": {
+ "name": "tournaments_sport_name_year_unique",
+ "columns": [
+ {
+ "expression": "sport_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "year",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "tournaments_sport_id_sports_id_fk": {
+ "name": "tournaments_sport_id_sports_id_fk",
+ "tableFrom": "tournaments",
+ "tableTo": "sports",
+ "columnsFrom": [
+ "sport_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.users": {
+ "name": "users",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "clerk_id": {
+ "name": "clerk_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "username": {
+ "name": "username",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image_url": {
+ "name": "image_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "flag_config": {
+ "name": "flag_config",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "custom_avatar_url": {
+ "name": "custom_avatar_url",
+ "type": "varchar(512)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avatar_type": {
+ "name": "avatar_type",
+ "type": "varchar(20)",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'flag'"
+ },
+ "is_admin": {
+ "name": "is_admin",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "varchar(50)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "discord_ping_enabled": {
+ "name": "discord_ping_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "draft_email_notifications_enabled": {
+ "name": "draft_email_notifications_enabled",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "last_data_request_at": {
+ "name": "last_data_request_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "users_username_lower_unique": {
+ "name": "users_username_lower_unique",
+ "columns": [
+ {
+ "expression": "lower(\"username\")",
+ "asc": true,
+ "isExpression": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "users_clerk_id_unique": {
+ "name": "users_clerk_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "clerk_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verifications": {
+ "name": "verifications",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.watchlist": {
+ "name": "watchlist",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "season_id": {
+ "name": "season_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "team_id": {
+ "name": "team_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "participant_id": {
+ "name": "participant_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "watchlist_season_team_participant_unique": {
+ "name": "watchlist_season_team_participant_unique",
+ "columns": [
+ {
+ "expression": "season_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "team_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "participant_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "watchlist_season_id_seasons_id_fk": {
+ "name": "watchlist_season_id_seasons_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "seasons",
+ "columnsFrom": [
+ "season_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "watchlist_team_id_teams_id_fk": {
+ "name": "watchlist_team_id_teams_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "teams",
+ "columnsFrom": [
+ "team_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "watchlist_participant_id_season_participants_id_fk": {
+ "name": "watchlist_participant_id_season_participants_id_fk",
+ "tableFrom": "watchlist",
+ "tableTo": "season_participants",
+ "columnsFrom": [
+ "participant_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.audit_action": {
+ "name": "audit_action",
+ "schema": "public",
+ "values": [
+ "league_settings_changed",
+ "draft_settings_changed",
+ "scoring_rules_changed",
+ "sports_changed",
+ "draft_order_set",
+ "draft_order_randomized",
+ "draft_started",
+ "draft_paused",
+ "draft_resumed",
+ "draft_reset",
+ "draft_rollback",
+ "force_autopick",
+ "force_manual_pick",
+ "draft_pick_changed",
+ "time_bank_edited",
+ "brackt_resolved"
+ ]
+ },
+ "public.autodraft_mode": {
+ "name": "autodraft_mode",
+ "schema": "public",
+ "values": [
+ "next_pick",
+ "while_on"
+ ]
+ },
+ "public.draft_timer_mode": {
+ "name": "draft_timer_mode",
+ "schema": "public",
+ "values": [
+ "chess_clock",
+ "standard"
+ ]
+ },
+ "public.event_type": {
+ "name": "event_type",
+ "schema": "public",
+ "values": [
+ "playoff_game",
+ "major_tournament",
+ "final_standings",
+ "schedule_event"
+ ]
+ },
+ "public.match_status": {
+ "name": "match_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "in_progress",
+ "complete",
+ "canceled",
+ "postponed"
+ ]
+ },
+ "public.overnight_pause_mode": {
+ "name": "overnight_pause_mode",
+ "schema": "public",
+ "values": [
+ "none",
+ "league",
+ "per_user"
+ ]
+ },
+ "public.picked_by_type": {
+ "name": "picked_by_type",
+ "schema": "public",
+ "values": [
+ "owner",
+ "commissioner",
+ "admin",
+ "auto"
+ ]
+ },
+ "public.playoff_match_game_status": {
+ "name": "playoff_match_game_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "complete",
+ "postponed"
+ ]
+ },
+ "public.probability_source": {
+ "name": "probability_source",
+ "schema": "public",
+ "values": [
+ "manual",
+ "futures_odds",
+ "elo_simulation",
+ "performance_model"
+ ]
+ },
+ "public.scoring_pattern": {
+ "name": "scoring_pattern",
+ "schema": "public",
+ "values": [
+ "playoff_bracket",
+ "season_standings",
+ "qualifying_points"
+ ]
+ },
+ "public.scoring_type": {
+ "name": "scoring_type",
+ "schema": "public",
+ "values": [
+ "playoffs",
+ "regular_season",
+ "majors"
+ ]
+ },
+ "public.season_status": {
+ "name": "season_status",
+ "schema": "public",
+ "values": [
+ "pre_draft",
+ "draft",
+ "active",
+ "completed"
+ ]
+ },
+ "public.simulation_status": {
+ "name": "simulation_status",
+ "schema": "public",
+ "values": [
+ "idle",
+ "running",
+ "failed"
+ ]
+ },
+ "public.simulator_type": {
+ "name": "simulator_type",
+ "schema": "public",
+ "values": [
+ "f1_standings",
+ "indycar_standings",
+ "golf_qualifying_points",
+ "playoff_bracket",
+ "ucl_bracket",
+ "ncaam_bracket",
+ "ncaaw_bracket",
+ "nba_bracket",
+ "nhl_bracket",
+ "nfl_bracket",
+ "afl_bracket",
+ "epl_standings",
+ "snooker_bracket",
+ "tennis_qualifying_points",
+ "mlb_bracket",
+ "wnba_bracket",
+ "world_cup",
+ "darts_bracket",
+ "cs2_major_qualifying_points",
+ "ncaa_football_bracket",
+ "llws_bracket",
+ "college_hockey_bracket",
+ "brackt",
+ "nll_bracket",
+ "mls_bracket"
+ ]
+ },
+ "public.sport_type": {
+ "name": "sport_type",
+ "schema": "public",
+ "values": [
+ "team",
+ "individual"
+ ]
+ },
+ "public.sports_season_status": {
+ "name": "sports_season_status",
+ "schema": "public",
+ "values": [
+ "upcoming",
+ "active",
+ "completed"
+ ]
+ },
+ "public.tournament_status": {
+ "name": "tournament_status",
+ "schema": "public",
+ "values": [
+ "scheduled",
+ "in_progress",
+ "completed"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index c0c2bd9..d31049a 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -841,6 +841,20 @@
"when": 1781031439603,
"tag": "0119_eminent_siren",
"breakpoints": true
+ },
+ {
+ "idx": 120,
+ "version": "7",
+ "when": 1781294866660,
+ "tag": "0120_tidy_invaders",
+ "breakpoints": true
+ },
+ {
+ "idx": 121,
+ "version": "7",
+ "when": 1781296473277,
+ "tag": "0121_even_gambit",
+ "breakpoints": true
}
]
}
\ No newline at end of file