From 501c5b183f123c4c77a34dec2490c4f9ac91e927 Mon Sep 17 00:00:00 2001 From: Chris Parsons Date: Wed, 15 Oct 2025 21:50:02 -0700 Subject: [PATCH] feat: add draft rounds configuration to league settings --- app/routes/leagues/$leagueId.settings.tsx | 322 ++++--- app/routes/leagues/$leagueId.tsx | 37 +- app/routes/leagues/new.tsx | 66 ++ database/schema.ts | 1 + drizzle/0015_exotic_loners.sql | 1 + drizzle/meta/0015_snapshot.json | 1052 +++++++++++++++++++++ drizzle/meta/_journal.json | 7 + 7 files changed, 1356 insertions(+), 130 deletions(-) create mode 100644 drizzle/0015_exotic_loners.sql create mode 100644 drizzle/meta/0015_snapshot.json diff --git a/app/routes/leagues/$leagueId.settings.tsx b/app/routes/leagues/$leagueId.settings.tsx index 7f02a44..81101e9 100644 --- a/app/routes/leagues/$leagueId.settings.tsx +++ b/app/routes/leagues/$leagueId.settings.tsx @@ -3,7 +3,7 @@ import { Form, Link, redirect, useNavigation } from "react-router"; import { getAuth } from "@clerk/react-router/server"; import { findLeagueById, updateLeague, deleteLeague } from "~/models/league"; import { isCommissioner } from "~/models/commissioner"; -import { findCurrentSeasonWithSports } from "~/models/season"; +import { findCurrentSeasonWithSports, updateSeason } from "~/models/season"; import { findTeamsBySeasonId, createManyTeams, deleteTeam } from "~/models/team"; import { unlinkSportFromSeason, linkMultipleSportsToSeason } from "~/models/season-sport"; import { findAllSportsSeasons } from "~/models/sports-season"; @@ -117,6 +117,31 @@ export async function action(args: Route.ActionArgs) { return { error: "No active season found" }; } + if (intent === "update-draft-rounds") { + if (season.status !== "pre_draft") { + return { error: "Cannot modify draft rounds after draft has started" }; + } + + const draftRounds = formData.get("draftRounds"); + const draftRoundsNum = typeof draftRounds === "string" ? parseInt(draftRounds, 10) : null; + + if (draftRoundsNum === null || isNaN(draftRoundsNum)) { + return { error: "Draft rounds must be a valid number" }; + } + + const sportsCount = season.seasonSports?.length || 0; + if (draftRoundsNum < sportsCount) { + return { error: `Draft rounds must be at least ${sportsCount} (number of sports selected)` }; + } + + if (draftRoundsNum < 1 || draftRoundsNum > 50) { + return { error: "Draft rounds must be between 1 and 50" }; + } + + await updateSeason(season.id, { draftRounds: draftRoundsNum }); + return { success: true, message: "Draft rounds updated successfully" }; + } + if (intent === "update-sports") { if (season.status !== "pre_draft") { return { error: "Cannot modify sports after draft has started" }; @@ -281,6 +306,7 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone ? draftSlots.map((slot: any) => slot.teamId) : teams.map((team: any) => team.id) ); + const [draftRounds, setDraftRounds] = useState(season?.draftRounds || 20); // Update draft order when loader data changes (after randomization) useEffect(() => { @@ -293,8 +319,15 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone const canEditSports = season && season.status === "pre_draft"; const canEditTeamCount = season && season.status === "pre_draft"; const canEditDraftOrder = season && season.status === "pre_draft"; + const canEditDraftRounds = season && season.status === "pre_draft"; const minTeamCount = Math.max(6, teamsWithOwners); + // Calculate flex spots and minimum rounds + const sportsCount = selectedSports.size; + const minRounds = sportsCount; + const recommendedRounds = Math.ceil(sportsCount * 1.25); + const flexSpots = Math.max(0, draftRounds - sportsCount); + const handleSportToggle = (sportId: string) => { const newSelected = new Set(selectedSports); if (newSelected.has(sportId)) { @@ -333,8 +366,10 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone

{league.name}

-
- {/* Update League Form */} +
+ + + {/* General Settings */} General Settings @@ -342,68 +377,111 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone Update your league's basic information - - - - -
- - -
+ +
+ + +
-
- - -

- {canEditTeamCount - ? `Can be changed before draft starts (minimum ${minTeamCount} based on registered teams)` - : "Team count cannot be changed after draft has started"} -

-
- - {actionData?.error && ( -
- {actionData.error} -
- )} - - - +
+ + +

+ {canEditTeamCount + ? `Can be changed before draft starts (minimum ${minTeamCount} based on registered teams)` + : "Team count cannot be changed after draft has started"} +

+
- {/* Sports Seasons Management */} + {/* Draft Rounds */} + + + Draft Rounds + + {canEditDraftRounds + ? "Set the number of draft rounds for your league" + : "Draft rounds cannot be modified after the draft has started"} + + + +
+ + +
+

+ Minimum: {minRounds} (number of sports selected) + {recommendedRounds > minRounds && ` • Recommended: ${recommendedRounds}`} +

+ {sportsCount > 0 && draftRounds < sportsCount && ( +

+ ⚠️ You need at least {sportsCount} rounds for the {sportsCount} sports selected +

+ )} + {sportsCount > 0 && draftRounds >= sportsCount && ( +

+ Flex Spots: {flexSpots} +

+ )} +
+
+
+
+ + {/* Sports Seasons */} Sports Seasons @@ -413,74 +491,72 @@ export default function LeagueSettings({ loaderData, actionData }: Route.Compone : "Sports cannot be modified after the draft has started"} - -
- + -
-
-

- Recommendation: Select 16-20 sports seasons for optimal league balance and variety. -

-
- -
- -
- {allSportsSeasons.length > 0 ? ( - allSportsSeasons.map((season) => ( -
- handleSportToggle(season.id)} - disabled={!canEditSports} - /> - -
- )) - ) : ( -

- No sports seasons available -

- )} -
+
+
+

+ Recommendation: Select 16-20 sports seasons for optimal league balance and variety. +

+
+ +
+ +
+ {allSportsSeasons.length > 0 ? ( + allSportsSeasons.map((season) => ( +
+ handleSportToggle(season.id)} + disabled={!canEditSports} + /> + +
+ )) + ) : ( +

+ No sports seasons available +

+ )}
- - {canEditSports && ( - - )} - - {actionData?.success && ( -
- Sports updated successfully! -
- )} - - {actionData?.error && ( -
- {actionData.error} -
- )} - +
+ {/* Save Button */} + {actionData?.error && ( +
+ {actionData.error} +
+ )} + + {actionData?.success && ( +
+ Settings updated successfully! +
+ )} + + + + +
{/* Draft Order Management */} diff --git a/app/routes/leagues/$leagueId.tsx b/app/routes/leagues/$leagueId.tsx index 103669b..2694256 100644 --- a/app/routes/leagues/$leagueId.tsx +++ b/app/routes/leagues/$leagueId.tsx @@ -12,6 +12,7 @@ import { findUserByClerkId, findDraftSlotsBySeasonId, } from "~/models"; +import { findSeasonWithSportsSeasons } from "~/models/season"; import type { Route } from "./+types/$leagueId"; import { Button } from "~/components/ui/button"; import { @@ -34,8 +35,9 @@ export async function loader(args: Route.LoaderArgs) { throw new Response("League not found", { status: 404 }); } - // Fetch current season + // Fetch current season with sports const season = await findCurrentSeason(leagueId); + const seasonWithSports = season ? await findSeasonWithSportsSeasons(season.id) : null; // Fetch commissioners const commissioners = await findCommissionersByLeagueId(leagueId); @@ -110,6 +112,9 @@ export async function loader(args: Route.LoaderArgs) { // Count available teams const availableTeamCount = teams.filter((t) => !t.ownerId).length; + // Count sports in season + const sportsCount = seasonWithSports?.seasonSports?.length || 0; + return { league, season, @@ -121,6 +126,7 @@ export async function loader(args: Route.LoaderArgs) { commissionerMap: Object.fromEntries(commissionerMap), availableTeamCount, draftSlots, + sportsCount, }; } @@ -136,6 +142,7 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) { commissionerMap, availableTeamCount, draftSlots, + sportsCount, } = loaderData; const [searchParams, setSearchParams] = useSearchParams(); const [copied, setCopied] = useState(false); @@ -332,12 +339,28 @@ export default function LeagueHome({ loaderData }: Route.ComponentProps) {

{season && ( -
-

Season Status

-

- {season.status.replace("_", " ")} -

-
+ <> +
+

Season Status

+

+ {season.status.replace("_", " ")} +

+
+
+

Draft Rounds

+

{season.draftRounds}

+
+
+

Sports Selected

+

{sportsCount}

+
+
+

Flex Spots

+

+ {Math.max(0, season.draftRounds - sportsCount)} +

+
+ )} diff --git a/app/routes/leagues/new.tsx b/app/routes/leagues/new.tsx index 18fc291..99606ec 100644 --- a/app/routes/leagues/new.tsx +++ b/app/routes/leagues/new.tsx @@ -66,6 +66,7 @@ export async function action(args: Route.ActionArgs) { const name = formData.get("name"); const teamCount = formData.get("teamCount"); const templateId = formData.get("templateId"); + const draftRounds = formData.get("draftRounds"); // Validation if (typeof name !== "string" || !name.trim()) { @@ -81,6 +82,11 @@ export async function action(args: Route.ActionArgs) { return { error: "Number of teams must be between 6 and 16" }; } + const draftRoundsNum = typeof draftRounds === "string" ? parseInt(draftRounds, 10) : 20; + if (isNaN(draftRoundsNum) || draftRoundsNum < 1 || draftRoundsNum > 50) { + return { error: "Draft rounds must be between 1 and 50" }; + } + try { // Create league const league = await createLeague({ @@ -101,6 +107,7 @@ export async function action(args: Route.ActionArgs) { year: currentYear, status: "pre_draft", templateId: typeof templateId === "string" && templateId !== "" ? templateId : null, + draftRounds: draftRoundsNum, }); // Set this as the current season for the league @@ -108,6 +115,14 @@ export async function action(args: Route.ActionArgs) { // Add selected sports to the season const selectedSports = formData.getAll("sportsSeasons"); + + // Validate that draft rounds is at least the number of sports + if (selectedSports.length > draftRoundsNum) { + return { + error: `You need at least ${selectedSports.length} draft rounds for the ${selectedSports.length} sports selected. Currently set to ${draftRoundsNum} rounds.` + }; + } + if (selectedSports.length > 0) { await linkMultipleSportsToSeason( selectedSports.map((id) => ({ @@ -139,6 +154,7 @@ export default function NewLeague({ loaderData, actionData }: Route.ComponentPro const { templates, allSportsSeasons } = loaderData; const [selectedTemplate, setSelectedTemplate] = useState(""); const [selectedSports, setSelectedSports] = useState>(new Set()); + const [draftRounds, setDraftRounds] = useState(20); const handleSportToggle = (sportId: string) => { const newSelected = new Set(selectedSports); @@ -154,6 +170,13 @@ export default function NewLeague({ loaderData, actionData }: Route.ComponentPro setSelectedTemplate(templateId); setSelectedSports(new Set(sportsSeasonIds)); }; + + // Calculate flex spots and minimum rounds + const sportsCount = selectedSports.size; + const minRounds = sportsCount; + const recommendedRounds = Math.ceil(sportsCount * 1.25); + const flexSpots = Math.max(0, draftRounds - sportsCount); + return (
@@ -203,6 +226,49 @@ export default function NewLeague({ loaderData, actionData }: Route.ComponentPro

+
+ + +
+

+ Minimum: {minRounds} (number of sports selected) + {recommendedRounds > minRounds && ` • Recommended: ${recommendedRounds}`} +

+ {sportsCount > 0 && draftRounds < sportsCount && ( +

+ ⚠️ You need at least {sportsCount} rounds for the {sportsCount} sports selected +

+ )} + {sportsCount > 0 && draftRounds >= sportsCount && ( +

+ Flex Spots: {flexSpots} +

+ )} +
+
+

diff --git a/database/schema.ts b/database/schema.ts index 8735fe5..d71aea7 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -67,6 +67,7 @@ export const seasons = pgTable("seasons", { status: seasonStatusEnum("status").notNull().default("pre_draft"), templateId: uuid("template_id") .references(() => seasonTemplates.id, { onDelete: "set null" }), + draftRounds: integer("draft_rounds").notNull().default(20), flexSpots: integer("flex_spots").notNull().default(0), inviteCode: varchar("invite_code", { length: 20 }).notNull().unique(), createdAt: timestamp("created_at").defaultNow().notNull(), diff --git a/drizzle/0015_exotic_loners.sql b/drizzle/0015_exotic_loners.sql new file mode 100644 index 0000000..62068b7 --- /dev/null +++ b/drizzle/0015_exotic_loners.sql @@ -0,0 +1 @@ +ALTER TABLE "seasons" ADD COLUMN "draft_rounds" integer DEFAULT 20 NOT NULL; \ No newline at end of file diff --git a/drizzle/meta/0015_snapshot.json b/drizzle/meta/0015_snapshot.json new file mode 100644 index 0000000..b2c40ec --- /dev/null +++ b/drizzle/meta/0015_snapshot.json @@ -0,0 +1,1052 @@ +{ + "id": "cdfd2392-b745-4384-baa3-e565618d9e45", + "prevId": "28a418b0-3f3e-460e-8407-e971ae451790", + "version": "7", + "dialect": "postgresql", + "tables": { + "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.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.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 + }, + "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.participant_results": { + "name": "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 + }, + "points_awarded": { + "name": "points_awarded", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "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": { + "participant_results_participant_id_participants_id_fk": { + "name": "participant_results_participant_id_participants_id_fk", + "tableFrom": "participant_results", + "tableTo": "participants", + "columnsFrom": [ + "participant_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "participant_results_sports_season_id_sports_seasons_id_fk": { + "name": "participant_results_sports_season_id_sports_seasons_id_fk", + "tableFrom": "participant_results", + "tableTo": "sports_seasons", + "columnsFrom": [ + "sports_season_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()" + }, + "sports_season_id": { + "name": "sports_season_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "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": "integer", + "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": {}, + "foreignKeys": { + "participants_sports_season_id_sports_seasons_id_fk": { + "name": "participants_sports_season_id_sports_seasons_id_fk", + "tableFrom": "participants", + "tableTo": "sports_seasons", + "columnsFrom": [ + "sports_season_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "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 + }, + "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_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_sports_season_id_sports_seasons_id_fk": { + "name": "season_template_sports_sports_season_id_sports_seasons_id_fk", + "tableFrom": "season_template_sports", + "tableTo": "sports_seasons", + "columnsFrom": [ + "sports_season_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 + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "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.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 + }, + "invite_code": { + "name": "invite_code", + "type": "varchar(20)", + "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": { + "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.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(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": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sports_slug_unique": { + "name": "sports_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "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 + }, + "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'" + }, + "scoring_type": { + "name": "scoring_type", + "type": "scoring_type", + "typeSchema": "public", + "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" + } + }, + "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 + }, + "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": {}, + "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.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": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_name": { + "name": "display_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "first_name": { + "name": "first_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "image_url": { + "name": "image_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_admin": { + "name": "is_admin", + "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": { + "users_clerk_id_unique": { + "name": "users_clerk_id_unique", + "nullsNotDistinct": false, + "columns": [ + "clerk_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "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.sport_type": { + "name": "sport_type", + "schema": "public", + "values": [ + "team", + "individual" + ] + }, + "public.sports_season_status": { + "name": "sports_season_status", + "schema": "public", + "values": [ + "upcoming", + "active", + "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 7fac20a..92babcd 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -106,6 +106,13 @@ "when": 1760588333462, "tag": "0014_lowly_gateway", "breakpoints": true + }, + { + "idx": 15, + "version": "7", + "when": 1760589195551, + "tag": "0015_exotic_loners", + "breakpoints": true } ] } \ No newline at end of file