diff --git a/app/components/scoring/Cs2TournamentBracket.tsx b/app/components/scoring/Cs2TournamentBracket.tsx
new file mode 100644
index 0000000..31ac74d
--- /dev/null
+++ b/app/components/scoring/Cs2TournamentBracket.tsx
@@ -0,0 +1,201 @@
+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 STAGE_NAMES: Record = {
+ 1: "Opening Stage",
+ 2: "Challengers Stage",
+ 3: "Legends Stage",
+};
+
+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, 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;
+ if (!rounds.has(r)) rounds.set(r, []);
+ rounds.get(r)!.push(m);
+ }
+
+ const sortedRounds = [...rounds.entries()].sort(([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) => (
+
+ ))}
+
+
+ {/* 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..b6da163
--- /dev/null
+++ b/app/components/scoring/MatchSchedule.tsx
@@ -0,0 +1,142 @@
+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)}
+
+
+ );
+}
+
+function groupByMatchday(matches: MatchWithRelations[]) {
+ const groups = new Map();
+ for (const m of matches) {
+ const key = m.matchday != null ? `Matchday ${m.matchday}` : formatDate(m.scheduledAt)?.split(",")[0] ?? "TBD";
+ if (!groups.has(key)) groups.set(key, []);
+ groups.get(key)!.push(m);
+ }
+ return groups;
+}
+
+export function MatchSchedule({ matches, title = "Schedule" }: MatchScheduleProps) {
+ if (matches.length === 0) {
+ return (
+
+ No matches scheduled yet.
+
+ );
+ }
+
+ const hasMatchdays = matches.some((m) => m.matchday != null);
+ const grouped = hasMatchdays ? groupByMatchday(matches) : null;
+
+ if (grouped) {
+ return (
+
+ {title &&
{title}
}
+ {[...grouped.entries()].map(([label, group]) => (
+
+
+ {label}
+
+ {group.map((m) => (
+
+ ))}
+
+ ))}
+
+ );
+ }
+
+ return (
+
+ {title &&
{title}
}
+
+ {matches.map((m) => (
+
+ ))}
+
+
+ );
+}
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/routes.ts b/app/routes.ts
index 44357b2..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", [
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 6810ff5..4ba21d1 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';
@@ -134,6 +134,8 @@ export default function AdminCs2Setup() {
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>(() => {
@@ -334,16 +336,23 @@ export default function AdminCs2Setup() {
Swiss Rounds
-
+
- Match-level results imported via API (Phase 2). "Sync from API" will be enabled once a PandaScore tournament ID is configured.
+ {sportsSeason.externalSeasonId
+ ? `Syncing from external ID: ${sportsSeason.externalSeasonId}`
+ : 'Set an External Season ID on the sports season to enable API sync.'}
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).
+
+
+
+
+ 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
)}
+
+
+
+
+ Used by the match sync cron job. For CS2: PandaScore serie_id. For MLB/NBA: year (e.g., 2025).
+
+
+
diff --git a/app/routes/admin/jobs.sync-matches.ts b/app/routes/admin/jobs.sync-matches.ts
new file mode 100644
index 0000000..3d4dee0
--- /dev/null
+++ b/app/routes/admin/jobs.sync-matches.ts
@@ -0,0 +1,38 @@
+import { 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: isNotNull(schema.sportsSeasons.externalSeasonId),
+ 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..5e546f0
--- /dev/null
+++ b/app/routes/sports-seasons.$sportsSeasonId.tournament.tsx
@@ -0,0 +1,137 @@
+import { useEffect } from "react";
+import { 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";
+import { Link } from "react-router";
+
+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);
+
+ return {
+ sportsSeason,
+ simulatorType,
+ seasonMatches,
+ playoffMatches,
+ playoffRounds,
+ bracketTemplateId,
+ hasLiveMatches,
+ };
+}
+
+type LoaderData = Awaited
>;
+
+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..7945c44
--- /dev/null
+++ b/app/services/match-sync/__tests__/espn-schedule.test.ts
@@ -0,0 +1,171 @@
+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();
+ });
+});
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..c982fbe
--- /dev/null
+++ b/app/services/match-sync/__tests__/pandascore.test.ts
@@ -0,0 +1,162 @@
+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);
+
+ expect(m.subGames![0].gameNumber).toBe(1);
+ expect(m.subGames![0].gameLabel).toBe("Mirage");
+ expect(m.subGames![0].team1Score).toBe(16);
+ expect(m.subGames![0].team2Score).toBe(14);
+ expect(m.subGames![0].winnerExternalId).toBe("1");
+ expect(m.subGames![0].status).toBe("complete");
+
+ expect(m.subGames![1].gameLabel).toBe("Inferno");
+ expect(m.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..6956d8a
--- /dev/null
+++ b/app/services/match-sync/espn-schedule.ts
@@ -0,0 +1,89 @@
+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";
+}
+
+export class EspnScheduleAdapter implements MatchSyncAdapter {
+ readonly supportsLiveScores = false;
+ private readonly sport: string; // e.g. "baseball/mlb", "basketball/nba"
+
+ constructor(sport: string) {
+ this.sport = sport;
+ }
+
+ // externalSeasonId is "YYYY" year string for ESPN sports
+ async fetchMatches(externalSeasonId: string): Promise {
+ const url = `https://site.api.espn.com/apis/site/v2/sports/${this.sport}/scoreboard?limit=1000&dates=${externalSeasonId}`;
+ 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 = home.score ? parseInt(home.score, 10) : null;
+ const awayScore = away.score ? parseInt(away.score, 10) : null;
+ 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..b641f64
--- /dev/null
+++ b/app/services/match-sync/index.ts
@@ -0,0 +1,265 @@
+import { database } from "~/database/context";
+import { eq, isNull, or } 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 } 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, MatchRecord } 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");
+ case "nba_bracket":
+ return new EspnScheduleAdapter("basketball/nba");
+ case "mls_bracket":
+ return new EspnScheduleAdapter("soccer/mls");
+ case "wnba_bracket":
+ return new EspnScheduleAdapter("basketball/wnba");
+ case "nhl_bracket":
+ return new EspnScheduleAdapter("hockey/nhl");
+ 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!, 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);
+ const bracketMatches = fetchedMatches.filter((m) => m.matchStage == null);
+
+ 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) {
+ 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: 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..6458f81
--- /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?.id != null ? 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 ? 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 a736714..96fadae 100644
--- a/database/schema.ts
+++ b/database/schema.ts
@@ -701,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(),
});
diff --git a/docs/plans/match-sync-display.md b/docs/plans/match-sync-display.md
index 842689e..4002626 100644
--- a/docs/plans/match-sync-display.md
+++ b/docs/plans/match-sync-display.md
@@ -10,10 +10,10 @@ The current system tracks tournament stage entry/exit manually with no match-lev
## Status
-- [ ] Phase 1 — Generic Data Model + CS2 Admin UI
-- [ ] Phase 2 — Generic Match Sync Adapter + Cron Job
-- [ ] Phase 3 — Public Tournament & Schedule Display + Live Scores
-- [ ] Phase 4 — Automated Playoff Bracket Updates (future)
+- [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 ✓
---
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/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 81890c3..d31049a 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -848,6 +848,13 @@
"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