feat: add draft pick, queue, and timer models with database schema updates
This commit is contained in:
parent
6e19a23e35
commit
469a85a0f8
9 changed files with 1896 additions and 0 deletions
65
app/models/draft-pick.ts
Normal file
65
app/models/draft-pick.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
|
||||
export async function createDraftPick(data: {
|
||||
seasonId: string;
|
||||
teamId: string;
|
||||
participantId: string;
|
||||
pickNumber: number;
|
||||
round: number;
|
||||
pickInRound: number;
|
||||
pickedByUserId: string;
|
||||
pickedByType: "owner" | "commissioner" | "auto";
|
||||
timeUsed: number;
|
||||
}) {
|
||||
const db = database();
|
||||
const [pick] = await db.insert(schema.draftPicks).values(data).returning();
|
||||
return pick;
|
||||
}
|
||||
|
||||
export async function getDraftPicks(seasonId: string) {
|
||||
const db = database();
|
||||
return await db
|
||||
.select()
|
||||
.from(schema.draftPicks)
|
||||
.where(eq(schema.draftPicks.seasonId, seasonId))
|
||||
.orderBy(schema.draftPicks.pickNumber);
|
||||
}
|
||||
|
||||
export async function getDraftPickByNumber(seasonId: string, pickNumber: number) {
|
||||
const db = database();
|
||||
const [pick] = await db
|
||||
.select()
|
||||
.from(schema.draftPicks)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.draftPicks.seasonId, seasonId),
|
||||
eq(schema.draftPicks.pickNumber, pickNumber)
|
||||
)
|
||||
);
|
||||
return pick;
|
||||
}
|
||||
|
||||
export async function getTeamDraftPicks(teamId: string) {
|
||||
const db = database();
|
||||
return await db
|
||||
.select()
|
||||
.from(schema.draftPicks)
|
||||
.where(eq(schema.draftPicks.teamId, teamId))
|
||||
.orderBy(schema.draftPicks.pickNumber);
|
||||
}
|
||||
|
||||
export async function isParticipantDrafted(seasonId: string, participantId: string) {
|
||||
const db = database();
|
||||
const [pick] = await db
|
||||
.select()
|
||||
.from(schema.draftPicks)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.draftPicks.seasonId, seasonId),
|
||||
eq(schema.draftPicks.participantId, participantId)
|
||||
)
|
||||
);
|
||||
return !!pick;
|
||||
}
|
||||
76
app/models/draft-queue.ts
Normal file
76
app/models/draft-queue.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
import { eq, and, asc } from "drizzle-orm";
|
||||
|
||||
export async function addToQueue(data: {
|
||||
seasonId: string;
|
||||
teamId: string;
|
||||
participantId: string;
|
||||
queuePosition: number;
|
||||
}) {
|
||||
const db = database();
|
||||
const [item] = await db.insert(schema.draftQueue).values(data).returning();
|
||||
return item;
|
||||
}
|
||||
|
||||
export async function removeFromQueue(queueId: string) {
|
||||
const db = database();
|
||||
await db.delete(schema.draftQueue).where(eq(schema.draftQueue.id, queueId));
|
||||
}
|
||||
|
||||
export async function getTeamQueue(teamId: string) {
|
||||
const db = database();
|
||||
return await db
|
||||
.select()
|
||||
.from(schema.draftQueue)
|
||||
.where(eq(schema.draftQueue.teamId, teamId))
|
||||
.orderBy(asc(schema.draftQueue.queuePosition));
|
||||
}
|
||||
|
||||
export async function clearTeamQueue(teamId: string) {
|
||||
const db = database();
|
||||
await db.delete(schema.draftQueue).where(eq(schema.draftQueue.teamId, teamId));
|
||||
}
|
||||
|
||||
export async function reorderQueue(teamId: string, participantIds: string[]) {
|
||||
// Delete existing queue
|
||||
await clearTeamQueue(teamId);
|
||||
|
||||
// Get season ID from first queue item (or we need to pass it)
|
||||
// For now, we'll need to pass seasonId
|
||||
return participantIds;
|
||||
}
|
||||
|
||||
export async function reorderQueueWithSeason(
|
||||
seasonId: string,
|
||||
teamId: string,
|
||||
participantIds: string[]
|
||||
) {
|
||||
// Delete existing queue
|
||||
await clearTeamQueue(teamId);
|
||||
|
||||
// Insert new queue in order
|
||||
const items = participantIds.map((participantId, index) => ({
|
||||
seasonId,
|
||||
teamId,
|
||||
participantId,
|
||||
queuePosition: index + 1,
|
||||
}));
|
||||
|
||||
if (items.length > 0) {
|
||||
const db = database();
|
||||
await db.insert(schema.draftQueue).values(items);
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeParticipantFromQueue(teamId: string, participantId: string) {
|
||||
const db = database();
|
||||
await db
|
||||
.delete(schema.draftQueue)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.draftQueue.teamId, teamId),
|
||||
eq(schema.draftQueue.participantId, participantId)
|
||||
)
|
||||
);
|
||||
}
|
||||
46
app/models/draft-timer.ts
Normal file
46
app/models/draft-timer.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export async function initializeDraftTimers(seasonId: string, teams: { id: string }[], initialTime: number) {
|
||||
const timerData = teams.map((team) => ({
|
||||
seasonId,
|
||||
teamId: team.id,
|
||||
timeRemaining: initialTime,
|
||||
}));
|
||||
|
||||
const db = database();
|
||||
await db.insert(schema.draftTimers).values(timerData);
|
||||
}
|
||||
|
||||
export async function getTeamTimer(teamId: string) {
|
||||
const db = database();
|
||||
const [timer] = await db
|
||||
.select()
|
||||
.from(schema.draftTimers)
|
||||
.where(eq(schema.draftTimers.teamId, teamId));
|
||||
return timer;
|
||||
}
|
||||
|
||||
export async function getSeasonTimers(seasonId: string) {
|
||||
const db = database();
|
||||
return await db
|
||||
.select()
|
||||
.from(schema.draftTimers)
|
||||
.where(eq(schema.draftTimers.seasonId, seasonId));
|
||||
}
|
||||
|
||||
export async function updateTeamTimer(teamId: string, timeRemaining: number) {
|
||||
const db = database();
|
||||
const [timer] = await db
|
||||
.update(schema.draftTimers)
|
||||
.set({ timeRemaining, updatedAt: new Date() })
|
||||
.where(eq(schema.draftTimers.teamId, teamId))
|
||||
.returning();
|
||||
return timer;
|
||||
}
|
||||
|
||||
export async function deleteSeasonTimers(seasonId: string) {
|
||||
const db = database();
|
||||
await db.delete(schema.draftTimers).where(eq(schema.draftTimers.seasonId, seasonId));
|
||||
}
|
||||
160
app/models/draft-utils.ts
Normal file
160
app/models/draft-utils.ts
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
import { eq, and, notInArray, desc } from "drizzle-orm";
|
||||
import { getTeamQueue } from "./draft-queue";
|
||||
import { isParticipantDrafted } from "./draft-pick";
|
||||
|
||||
/**
|
||||
* Auto-pick for a team when their timer runs out
|
||||
* 1. Check queue - pick first item if available
|
||||
* 2. If queue empty, pick highest EV participant not drafted
|
||||
*/
|
||||
export async function autoPickForTeam(seasonId: string, teamId: string) {
|
||||
// Check queue first
|
||||
const queue = await getTeamQueue(teamId);
|
||||
|
||||
if (queue.length > 0) {
|
||||
// Pick first item from queue
|
||||
const firstInQueue = queue[0];
|
||||
|
||||
// Verify participant is not already drafted
|
||||
const isDrafted = await isParticipantDrafted(seasonId, firstInQueue.participantId);
|
||||
if (!isDrafted) {
|
||||
return firstInQueue.participantId;
|
||||
}
|
||||
|
||||
// If first item was drafted, try next items in queue
|
||||
for (const item of queue.slice(1)) {
|
||||
const isDrafted = await isParticipantDrafted(seasonId, item.participantId);
|
||||
if (!isDrafted) {
|
||||
return item.participantId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Queue is empty or all queued players drafted - pick highest EV available
|
||||
return await getTopAvailableParticipant(seasonId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the highest EV participant that hasn't been drafted yet
|
||||
*/
|
||||
export async function getTopAvailableParticipant(seasonId: string) {
|
||||
const db = database();
|
||||
|
||||
// Get all drafted participant IDs
|
||||
const draftedPicks = await db
|
||||
.select({ participantId: schema.draftPicks.participantId })
|
||||
.from(schema.draftPicks)
|
||||
.where(eq(schema.draftPicks.seasonId, seasonId));
|
||||
|
||||
const draftedIds = draftedPicks.map((p: { participantId: string }) => p.participantId);
|
||||
|
||||
// Get all participants from season sports
|
||||
const seasonSportsData = await db
|
||||
.select({ sportsSeasonId: schema.seasonSports.sportsSeasonId })
|
||||
.from(schema.seasonSports)
|
||||
.where(eq(schema.seasonSports.seasonId, seasonId));
|
||||
|
||||
const sportsSeasonIds = seasonSportsData.map((s: { sportsSeasonId: string }) => s.sportsSeasonId);
|
||||
|
||||
if (sportsSeasonIds.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get top available participant by EV
|
||||
let query = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]))
|
||||
.orderBy(desc(schema.participants.expectedValue), schema.participants.name);
|
||||
|
||||
// Filter out drafted participants if any exist
|
||||
if (draftedIds.length > 0) {
|
||||
query = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]),
|
||||
notInArray(schema.participants.id, draftedIds)
|
||||
)
|
||||
)
|
||||
.orderBy(desc(schema.participants.expectedValue), schema.participants.name);
|
||||
}
|
||||
|
||||
// Handle multiple sports seasons
|
||||
if (sportsSeasonIds.length > 1) {
|
||||
// For simplicity, we'll query all and sort in memory
|
||||
// In production, might want to optimize this
|
||||
const allParticipants = [];
|
||||
|
||||
for (const sportsSeasonId of sportsSeasonIds) {
|
||||
let participantQuery = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (draftedIds.length > 0) {
|
||||
participantQuery = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
notInArray(schema.participants.id, draftedIds)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const seasonParticipants = await participantQuery;
|
||||
allParticipants.push(...seasonParticipants);
|
||||
}
|
||||
|
||||
// Sort by EV desc, then name
|
||||
allParticipants.sort((a, b) => {
|
||||
if (b.expectedValue !== a.expectedValue) {
|
||||
return b.expectedValue - a.expectedValue;
|
||||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
return allParticipants[0]?.id || null;
|
||||
}
|
||||
|
||||
const [topParticipant] = await query;
|
||||
return topParticipant?.id || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the current pick based on draft order and round
|
||||
*/
|
||||
export function calculatePickInfo(
|
||||
pickNumber: number,
|
||||
teamCount: number
|
||||
): { round: number; pickInRound: number; teamIndex: number } {
|
||||
const round = Math.ceil(pickNumber / teamCount);
|
||||
const pickInRound = ((pickNumber - 1) % teamCount) + 1;
|
||||
|
||||
// Snake draft: odd rounds go forward, even rounds go backward
|
||||
const isOddRound = round % 2 === 1;
|
||||
const teamIndex = isOddRound ? pickInRound - 1 : teamCount - pickInRound;
|
||||
|
||||
return { round, pickInRound, teamIndex };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the team ID for a given pick number based on draft order
|
||||
*/
|
||||
export function getTeamForPick(
|
||||
pickNumber: number,
|
||||
draftOrder: { teamId: string; draftOrder: number }[]
|
||||
): string | null {
|
||||
const sortedOrder = [...draftOrder].sort((a, b) => a.draftOrder - b.draftOrder);
|
||||
const teamCount = sortedOrder.length;
|
||||
|
||||
if (teamCount === 0) return null;
|
||||
|
||||
const { teamIndex } = calculatePickInfo(pickNumber, teamCount);
|
||||
return sortedOrder[teamIndex]?.teamId || null;
|
||||
}
|
||||
|
|
@ -12,3 +12,7 @@ export * from "./season-template-sport";
|
|||
export * from "./season-sport";
|
||||
export * from "./participant-result";
|
||||
export * from "./draft-slot";
|
||||
export * from "./draft-pick";
|
||||
export * from "./draft-queue";
|
||||
export * from "./draft-timer";
|
||||
export * from "./draft-utils";
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@ export const scoringTypeEnum = pgEnum("scoring_type", [
|
|||
"majors",
|
||||
]);
|
||||
|
||||
export const pickedByTypeEnum = pgEnum("picked_by_type", [
|
||||
"owner",
|
||||
"commissioner",
|
||||
"auto",
|
||||
]);
|
||||
|
||||
export const leagues = pgTable("leagues", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
|
|
@ -70,6 +76,11 @@ export const seasons = pgTable("seasons", {
|
|||
draftRounds: integer("draft_rounds").notNull().default(20),
|
||||
flexSpots: integer("flex_spots").notNull().default(0),
|
||||
draftDateTime: timestamp("draft_date_time"),
|
||||
draftInitialTime: integer("draft_initial_time").notNull().default(120), // seconds
|
||||
draftIncrementTime: integer("draft_increment_time").notNull().default(30), // seconds
|
||||
currentPickNumber: integer("current_pick_number").default(1),
|
||||
draftStartedAt: timestamp("draft_started_at"),
|
||||
draftPaused: boolean("draft_paused").notNull().default(false),
|
||||
inviteCode: varchar("invite_code", { length: 20 }).notNull().unique(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
|
|
@ -100,6 +111,54 @@ export const draftSlots = pgTable("draft_slots", {
|
|||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const draftPicks = pgTable("draft_picks", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
seasonId: uuid("season_id")
|
||||
.notNull()
|
||||
.references(() => seasons.id, { onDelete: "cascade" }),
|
||||
teamId: uuid("team_id")
|
||||
.notNull()
|
||||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
pickNumber: integer("pick_number").notNull(),
|
||||
round: integer("round").notNull(),
|
||||
pickInRound: integer("pick_in_round").notNull(),
|
||||
pickedByUserId: varchar("picked_by_user_id", { length: 255 }).notNull(), // Clerk user ID
|
||||
pickedByType: pickedByTypeEnum("picked_by_type").notNull(),
|
||||
timeUsed: integer("time_used").notNull().default(0), // seconds
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const draftQueue = pgTable("draft_queue", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
seasonId: uuid("season_id")
|
||||
.notNull()
|
||||
.references(() => seasons.id, { onDelete: "cascade" }),
|
||||
teamId: uuid("team_id")
|
||||
.notNull()
|
||||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
queuePosition: integer("queue_position").notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const draftTimers = pgTable("draft_timers", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
seasonId: uuid("season_id")
|
||||
.notNull()
|
||||
.references(() => seasons.id, { onDelete: "cascade" }),
|
||||
teamId: uuid("team_id")
|
||||
.notNull()
|
||||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
timeRemaining: integer("time_remaining").notNull(), // seconds
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const commissioners = pgTable("commissioners", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
leagueId: uuid("league_id")
|
||||
|
|
|
|||
85
drizzle/0017_calm_zarda.sql
Normal file
85
drizzle/0017_calm_zarda.sql
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
CREATE TYPE "public"."picked_by_type" AS ENUM('owner', 'commissioner', 'auto');--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "draft_picks" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"season_id" uuid NOT NULL,
|
||||
"team_id" uuid NOT NULL,
|
||||
"participant_id" uuid NOT NULL,
|
||||
"pick_number" integer NOT NULL,
|
||||
"round" integer NOT NULL,
|
||||
"pick_in_round" integer NOT NULL,
|
||||
"picked_by_user_id" varchar(255) NOT NULL,
|
||||
"picked_by_type" "picked_by_type" NOT NULL,
|
||||
"time_used" integer DEFAULT 0 NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "draft_queue" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"season_id" uuid NOT NULL,
|
||||
"team_id" uuid NOT NULL,
|
||||
"participant_id" uuid NOT NULL,
|
||||
"queue_position" integer NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "draft_timers" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"season_id" uuid NOT NULL,
|
||||
"team_id" uuid NOT NULL,
|
||||
"time_remaining" integer NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "seasons" ADD COLUMN "draft_initial_time" integer DEFAULT 120 NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "seasons" ADD COLUMN "draft_increment_time" integer DEFAULT 30 NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "seasons" ADD COLUMN "current_pick_number" integer DEFAULT 1;--> statement-breakpoint
|
||||
ALTER TABLE "seasons" ADD COLUMN "draft_started_at" timestamp;--> statement-breakpoint
|
||||
ALTER TABLE "seasons" ADD COLUMN "draft_paused" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_picks" ADD CONSTRAINT "draft_picks_season_id_seasons_id_fk" FOREIGN KEY ("season_id") REFERENCES "public"."seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_picks" ADD CONSTRAINT "draft_picks_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_picks" ADD CONSTRAINT "draft_picks_participant_id_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_queue" ADD CONSTRAINT "draft_queue_season_id_seasons_id_fk" FOREIGN KEY ("season_id") REFERENCES "public"."seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_queue" ADD CONSTRAINT "draft_queue_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_queue" ADD CONSTRAINT "draft_queue_participant_id_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_timers" ADD CONSTRAINT "draft_timers_season_id_seasons_id_fk" FOREIGN KEY ("season_id") REFERENCES "public"."seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "draft_timers" ADD CONSTRAINT "draft_timers_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
1394
drizzle/meta/0017_snapshot.json
Normal file
1394
drizzle/meta/0017_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -120,6 +120,13 @@
|
|||
"when": 1760590495868,
|
||||
"tag": "0016_majestic_roulette",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1760599350154,
|
||||
"tag": "0017_calm_zarda",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue