Merge branch 'phase-1a-rename' into canonical-layer-pr1
This commit is contained in:
commit
75f9b402ad
78 changed files with 6047 additions and 598 deletions
|
|
@ -8,7 +8,7 @@ vi.mock("~/models/draft-pick", () => ({
|
|||
isParticipantDrafted: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
getParticipantsForSeasonWithSports: vi.fn(),
|
||||
}));
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ import {
|
|||
getTeamDraftPicksWithSports,
|
||||
isParticipantDrafted,
|
||||
} from "~/models/draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/participant";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/season-participant";
|
||||
import { getSeasonSportsSimple } from "~/models/season-sport";
|
||||
import { getTeamQueue, getAllQueuesForSeason } from "~/models/draft-queue";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
|
|
@ -49,7 +49,7 @@ const ALL_TEAM_IDS = [TEAM_ID, "team-2"];
|
|||
function makeMockDb(overrides: Record<string, unknown> = {}) {
|
||||
const mockDb: Record<string, unknown> = {
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
},
|
||||
|
|
@ -71,7 +71,7 @@ function makeMockDb(overrides: Record<string, unknown> = {}) {
|
|||
// 3. select().from().where().orderBy() → top participant → [{id, ...}]
|
||||
function makeMockDbWithEvParticipant(participantId: string) {
|
||||
return {
|
||||
query: { participants: { findMany: vi.fn().mockResolvedValue([]) } },
|
||||
query: { seasonParticipants: { findMany: vi.fn().mockResolvedValue([]) } },
|
||||
select: vi.fn().mockReturnThis(),
|
||||
from: vi.fn().mockReturnThis(),
|
||||
innerJoin: vi.fn().mockReturnThis(),
|
||||
|
|
@ -148,7 +148,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
|
||||
const mockDb = makeMockDb({
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-1",
|
||||
|
|
@ -188,7 +188,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
const mockWhere = vi.fn().mockResolvedValue(undefined);
|
||||
const mockDb = makeMockDb({
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-1",
|
||||
|
|
@ -233,7 +233,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
const mockWhere = vi.fn().mockResolvedValue(undefined);
|
||||
const mockDb = makeMockDb({
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-snooker",
|
||||
|
|
@ -280,7 +280,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
// 4. select().from(participants).where().orderBy() — participant query (chain)
|
||||
const mockDb = {
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-snooker",
|
||||
|
|
@ -330,7 +330,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
|
||||
const mockDb = makeMockDb({
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-1",
|
||||
|
|
@ -373,7 +373,7 @@ describe("autoPickForTeam – queueOnly constraint (AC2 & AC3)", () => {
|
|||
|
||||
const mockDb = makeMockDb({
|
||||
query: {
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "p-1",
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ function makeDb(opts: MakeDbOpts = {}) {
|
|||
scoringEvents: {
|
||||
findMany: vi.fn().mockResolvedValue(scoringEvents),
|
||||
},
|
||||
participantQualifyingTotals: {
|
||||
seasonParticipantQualifyingTotals: {
|
||||
findMany: vi.fn().mockResolvedValue(qualifyingTotals),
|
||||
},
|
||||
},
|
||||
|
|
@ -220,6 +220,6 @@ describe("getDraftedParticipantsWithPoints", () => {
|
|||
|
||||
await getDraftedParticipantsWithPoints("team-1", "season-1", db);
|
||||
|
||||
expect(db.query.participantQualifyingTotals.findMany).not.toHaveBeenCalled();
|
||||
expect(db.query.seasonParticipantQualifyingTotals.findMany).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ vi.mock("~/models/draft-pick", () => ({
|
|||
isParticipantDrafted: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
getParticipantsForSeasonWithSports: vi.fn(),
|
||||
}));
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ vi.mock("~/lib/draft-eligibility", () => ({
|
|||
vi.mock("~/database/context");
|
||||
|
||||
import { getDraftPicksWithSports, getTeamDraftPicksWithSports, isParticipantDrafted } from "~/models/draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/participant";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/season-participant";
|
||||
import { getSeasonSportsSimple } from "~/models/season-sport";
|
||||
import { getTeamQueue, getAllQueuesForSeason } from "~/models/draft-queue";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
|
|
@ -127,7 +127,7 @@ function makeMockDb(seasonOverrides: Record<string, unknown> = {}) {
|
|||
draftPicks: { findFirst: vi.fn().mockResolvedValue(null) },
|
||||
seasons: { findFirst: vi.fn().mockResolvedValue(makeSeason(seasonOverrides)) },
|
||||
draftSlots: { findMany: vi.fn().mockResolvedValue(mockDraftSlots) },
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
// findMany: used by autoPickForTeam queue path
|
||||
findMany: vi.fn().mockResolvedValue([mockParticipantForQueue]),
|
||||
// findFirst: used by executeAutoPick to fetch full participant details
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ vi.mock("~/database/context", () => ({
|
|||
}));
|
||||
|
||||
vi.mock("~/database/schema", () => ({
|
||||
participants: { id: "id" },
|
||||
participantExpectedValues: {
|
||||
seasonParticipants: { id: "id" },
|
||||
seasonParticipantExpectedValues: {
|
||||
participantId: "participantId",
|
||||
sportsSeasonId: "sportsSeasonId",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ function makeDb(existingResult?: { id: string; isPartialScore: boolean }) {
|
|||
insert: vi.fn().mockReturnValue({ values: insertValues }),
|
||||
update: vi.fn().mockReturnValue({ set: updateSet }),
|
||||
query: {
|
||||
participantResults: { findFirst },
|
||||
seasonParticipantResults: { findFirst },
|
||||
seasonSports: {
|
||||
findMany: vi.fn().mockResolvedValue([]), // empty → standings loop exits immediately
|
||||
},
|
||||
|
|
@ -430,10 +430,10 @@ describe("processPlayoffEvent - NBA Play-In Round 1 loserAdvances fix", () => {
|
|||
playoffMatches: {
|
||||
findMany: vi.fn().mockResolvedValue(matches),
|
||||
},
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
participantResults: {
|
||||
seasonParticipantResults: {
|
||||
findFirst: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
seasons: {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ vi.mock("~/database/context", () => ({
|
|||
|
||||
vi.mock("~/database/schema", () => ({
|
||||
sportsSeasons: { id: "ss.id", sportId: "ss.sport_id" },
|
||||
participants: { sportsSeasonId: "p.sports_season_id" },
|
||||
seasonParticipants: { sportsSeasonId: "p.sports_season_id" },
|
||||
scoringEvents: { sportsSeasonId: "se.sports_season_id" },
|
||||
participantExpectedValues: { sportsSeasonId: "pev.sports_season_id" },
|
||||
seasonParticipantExpectedValues: { sportsSeasonId: "pev.sports_season_id" },
|
||||
}));
|
||||
|
||||
vi.mock("drizzle-orm", () => ({
|
||||
|
|
@ -91,16 +91,16 @@ function makeMockDb({
|
|||
const db: any = {
|
||||
query: {
|
||||
sportsSeasons: { findFirst: vi.fn().mockResolvedValue(ss) },
|
||||
participants: { findMany: vi.fn().mockResolvedValue(participants) },
|
||||
seasonParticipants: { findMany: vi.fn().mockResolvedValue(participants) },
|
||||
scoringEvents: { findMany: vi.fn().mockResolvedValue(scoringEvents) },
|
||||
participantExpectedValues: { findMany: vi.fn().mockResolvedValue(sourceEvRows) },
|
||||
seasonParticipantExpectedValues: { findMany: vi.fn().mockResolvedValue(sourceEvRows) },
|
||||
},
|
||||
insert: vi.fn().mockImplementation((table: object) => {
|
||||
let key: string;
|
||||
let returnRows: object[];
|
||||
if (table === schema.sportsSeasons) {
|
||||
key = "sportsSeasons"; returnRows = [insertedSeason];
|
||||
} else if (table === schema.participants) {
|
||||
} else if (table === schema.seasonParticipants) {
|
||||
key = "participants"; returnRows = newParticipantRows;
|
||||
} else if (table === schema.scoringEvents) {
|
||||
key = "scoringEvents"; returnRows = [];
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ function makeDb(opts: MakeDbOpts = {}) {
|
|||
teamScoreEvents: {
|
||||
findMany: vi.fn().mockResolvedValue(scoreEventRows),
|
||||
},
|
||||
participants: {
|
||||
seasonParticipants: {
|
||||
findMany: vi.fn().mockResolvedValue(participantRows),
|
||||
},
|
||||
},
|
||||
|
|
@ -268,7 +268,7 @@ describe("getRecentTeamScoreEvents", () => {
|
|||
it("does not query participants when rows array is empty", async () => {
|
||||
const { db } = makeDb({ scoreEventRows: [] });
|
||||
await getRecentTeamScoreEvents("season-1", 10, db);
|
||||
expect(db.query.participants.findMany).not.toHaveBeenCalled();
|
||||
expect(db.query.seasonParticipants.findMany).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns mapped entries with resolved participant names", async () => {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
|
||||
import { database } from "~/database/context";
|
||||
import { cs2MajorStageResults, participants } from "~/database/schema";
|
||||
import { cs2MajorStageResults, seasonParticipants } from "~/database/schema";
|
||||
import { eq, and, sql } from "drizzle-orm";
|
||||
|
||||
export interface Cs2StageResult {
|
||||
|
|
@ -56,12 +56,12 @@ export async function getCs2StageResultsForEvent(
|
|||
finalPlacement: cs2MajorStageResults.finalPlacement,
|
||||
createdAt: cs2MajorStageResults.createdAt,
|
||||
updatedAt: cs2MajorStageResults.updatedAt,
|
||||
participantName: participants.name,
|
||||
participantName: seasonParticipants.name,
|
||||
})
|
||||
.from(cs2MajorStageResults)
|
||||
.innerJoin(participants, eq(cs2MajorStageResults.participantId, participants.id))
|
||||
.innerJoin(seasonParticipants, eq(cs2MajorStageResults.participantId, seasonParticipants.id))
|
||||
.where(eq(cs2MajorStageResults.scoringEventId, scoringEventId))
|
||||
.orderBy(cs2MajorStageResults.stageEntry, participants.name);
|
||||
.orderBy(cs2MajorStageResults.stageEntry, seasonParticipants.name);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ export async function clearCs2StageAssignments(
|
|||
|
||||
/**
|
||||
* Mark teams as eliminated from a specific stage.
|
||||
* Records stageEliminated and stageEliminatedWins for the specified participants.
|
||||
* Records stageEliminated and stageEliminatedWins for the specified seasonParticipants.
|
||||
* Teams NOT in eliminatedEntries that are in this stage are implicitly considered
|
||||
* to have advanced (stageEliminated remains null).
|
||||
*/
|
||||
|
|
@ -166,7 +166,7 @@ export async function markCs2StageEliminations(
|
|||
}
|
||||
|
||||
/**
|
||||
* Set final placements for all participants in a CS2 Major event.
|
||||
* Set final placements for all seasonParticipants in a CS2 Major event.
|
||||
* Called after the Champions Stage is complete.
|
||||
* placements: Map from participantId to final placement (1–32)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -78,14 +78,14 @@ export async function getDraftedParticipantsBySportsSeason(
|
|||
|
||||
const results = await db
|
||||
.select({
|
||||
sportsSeasonId: schema.participants.sportsSeasonId,
|
||||
participantId: schema.participants.id,
|
||||
participantName: schema.participants.name,
|
||||
sportsSeasonId: schema.seasonParticipants.sportsSeasonId,
|
||||
participantId: schema.seasonParticipants.id,
|
||||
participantName: schema.seasonParticipants.name,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(
|
||||
schema.participants,
|
||||
eq(schema.draftPicks.participantId, schema.participants.id)
|
||||
schema.seasonParticipants,
|
||||
eq(schema.draftPicks.participantId, schema.seasonParticipants.id)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
|
|
@ -182,10 +182,10 @@ export async function getDraftedParticipantsWithPoints(
|
|||
// Batch-fetch QP totals for qualifying_points participants
|
||||
const qpMap = new Map<string, number>(); // participantId → totalQP
|
||||
if (qpParticipantIds.size > 0 && qpSeasonIds.size > 0) {
|
||||
const totals = await db.query.participantQualifyingTotals.findMany({
|
||||
const totals = await db.query.seasonParticipantQualifyingTotals.findMany({
|
||||
where: and(
|
||||
inArray(schema.participantQualifyingTotals.participantId, [...qpParticipantIds]),
|
||||
inArray(schema.participantQualifyingTotals.sportsSeasonId, [...qpSeasonIds])
|
||||
inArray(schema.seasonParticipantQualifyingTotals.participantId, [...qpParticipantIds]),
|
||||
inArray(schema.seasonParticipantQualifyingTotals.sportsSeasonId, [...qpSeasonIds])
|
||||
),
|
||||
columns: { participantId: true, totalQualifyingPoints: true },
|
||||
});
|
||||
|
|
@ -245,19 +245,19 @@ export async function getDraftPicksWithSports(seasonId: string, providedDb?: Ret
|
|||
id: schema.draftPicks.id,
|
||||
teamId: schema.draftPicks.teamId,
|
||||
pickNumber: schema.draftPicks.pickNumber,
|
||||
participantId: schema.participants.id,
|
||||
participantName: schema.participants.name,
|
||||
participantId: schema.seasonParticipants.id,
|
||||
participantName: schema.seasonParticipants.name,
|
||||
sportId: schema.sports.id,
|
||||
sportName: schema.sports.name,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(
|
||||
schema.participants,
|
||||
eq(schema.draftPicks.participantId, schema.participants.id)
|
||||
schema.seasonParticipants,
|
||||
eq(schema.draftPicks.participantId, schema.seasonParticipants.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sportsSeasons,
|
||||
eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sports,
|
||||
|
|
@ -289,19 +289,19 @@ export async function getTeamDraftPicksWithSports(teamId: string, seasonId: stri
|
|||
id: schema.draftPicks.id,
|
||||
teamId: schema.draftPicks.teamId,
|
||||
pickNumber: schema.draftPicks.pickNumber,
|
||||
participantId: schema.participants.id,
|
||||
participantName: schema.participants.name,
|
||||
participantId: schema.seasonParticipants.id,
|
||||
participantName: schema.seasonParticipants.name,
|
||||
sportId: schema.sports.id,
|
||||
sportName: schema.sports.name,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(
|
||||
schema.participants,
|
||||
eq(schema.draftPicks.participantId, schema.participants.id)
|
||||
schema.seasonParticipants,
|
||||
eq(schema.draftPicks.participantId, schema.seasonParticipants.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sportsSeasons,
|
||||
eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sports,
|
||||
|
|
@ -338,13 +338,13 @@ export async function getDraftPicksForSeason(seasonId: string) {
|
|||
pickInRound: schema.draftPicks.pickInRound,
|
||||
timeUsed: schema.draftPicks.timeUsed,
|
||||
team: schema.teams,
|
||||
participant: schema.participants,
|
||||
participant: schema.seasonParticipants,
|
||||
sport: schema.sports,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(schema.teams, eq(schema.draftPicks.teamId, schema.teams.id))
|
||||
.innerJoin(schema.participants, eq(schema.draftPicks.participantId, schema.participants.id))
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.innerJoin(schema.seasonParticipants, eq(schema.draftPicks.participantId, schema.seasonParticipants.id))
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.innerJoin(schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id))
|
||||
.where(eq(schema.draftPicks.seasonId, seasonId))
|
||||
.orderBy(asc(schema.draftPicks.pickNumber));
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { logger } from "~/lib/logger";
|
|||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import { getTeamQueue, getAllQueuesForSeason } from "./draft-queue";
|
||||
import { isParticipantDrafted, getDraftPicksWithSports, getTeamDraftPicksWithSports } from "./draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "./participant";
|
||||
import { getParticipantsForSeasonWithSports } from "./season-participant";
|
||||
import { getSeasonSportsSimple } from "./season-sport";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
import { getSocketIO, scheduleDraftRoomClosure } from "../../server/socket";
|
||||
|
|
@ -118,8 +118,8 @@ export async function autoPickForTeam(
|
|||
|
||||
// Get participant details for queue items to check eligibility
|
||||
const queueParticipantIds = queue.map((item) => item.participantId);
|
||||
const queueParticipants = await db.query.participants.findMany({
|
||||
where: inArray(schema.participants.id, queueParticipantIds),
|
||||
const queueParticipants = await db.query.seasonParticipants.findMany({
|
||||
where: inArray(schema.seasonParticipants.id, queueParticipantIds),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
@ -264,17 +264,17 @@ export async function getTopAvailableParticipant(
|
|||
for (const sportsSeasonId of sportsSeasonIds) {
|
||||
let participantQuery = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (draftedIds.length > 0) {
|
||||
participantQuery = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.from(schema.seasonParticipants)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
notInArray(schema.participants.id, draftedIds)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
notInArray(schema.seasonParticipants.id, draftedIds)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -299,21 +299,21 @@ export async function getTopAvailableParticipant(
|
|||
// Single sport season
|
||||
let query = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]))
|
||||
.orderBy(desc(schema.participants.vorpValue), schema.participants.name);
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds[0]))
|
||||
.orderBy(desc(schema.seasonParticipants.vorpValue), schema.seasonParticipants.name);
|
||||
|
||||
if (draftedIds.length > 0) {
|
||||
query = db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.from(schema.seasonParticipants)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonIds[0]),
|
||||
notInArray(schema.participants.id, draftedIds)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds[0]),
|
||||
notInArray(schema.seasonParticipants.id, draftedIds)
|
||||
)
|
||||
)
|
||||
.orderBy(desc(schema.participants.vorpValue), schema.participants.name);
|
||||
.orderBy(desc(schema.seasonParticipants.vorpValue), schema.seasonParticipants.name);
|
||||
}
|
||||
|
||||
const [topParticipant] = await query;
|
||||
|
|
@ -471,7 +471,7 @@ export async function executeAutoPick(params: {
|
|||
success: boolean;
|
||||
error?: string;
|
||||
pick?: InferSelectModel<typeof schema.draftPicks>;
|
||||
participant?: InferSelectModel<typeof schema.participants> & {
|
||||
participant?: InferSelectModel<typeof schema.seasonParticipants> & {
|
||||
sportsSeason: InferSelectModel<typeof schema.sportsSeasons> & {
|
||||
sport: InferSelectModel<typeof schema.sports>;
|
||||
};
|
||||
|
|
@ -581,8 +581,8 @@ export async function executeAutoPick(params: {
|
|||
}
|
||||
|
||||
// Get participant details
|
||||
const participantToPick = await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, participantId),
|
||||
const participantToPick = await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, participantId),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export async function createEventResult(
|
|||
.insert(schema.eventResults)
|
||||
.values({
|
||||
scoringEventId: data.scoringEventId,
|
||||
participantId: data.participantId,
|
||||
seasonParticipantId: data.participantId,
|
||||
placement: data.placement,
|
||||
qualifyingPointsAwarded: data.qualifyingPointsAwarded?.toString(),
|
||||
eliminated: data.eliminated,
|
||||
|
|
@ -57,7 +57,7 @@ export async function createEventResultsBulk(
|
|||
.values(
|
||||
results.map((r) => ({
|
||||
scoringEventId: r.scoringEventId,
|
||||
participantId: r.participantId,
|
||||
seasonParticipantId: r.participantId,
|
||||
placement: r.placement,
|
||||
qualifyingPointsAwarded: r.qualifyingPointsAwarded?.toString(),
|
||||
eliminated: r.eliminated,
|
||||
|
|
@ -81,7 +81,7 @@ export async function getEventResultById(
|
|||
return await db.query.eventResults.findFirst({
|
||||
where: eq(schema.eventResults.id, resultId),
|
||||
with: {
|
||||
participant: {
|
||||
seasonParticipant: {
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
@ -108,7 +108,7 @@ export async function getEventResults(
|
|||
where: eq(schema.eventResults.scoringEventId, eventId),
|
||||
orderBy: schema.eventResults.placement,
|
||||
with: {
|
||||
participant: {
|
||||
seasonParticipant: {
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
@ -131,7 +131,7 @@ export async function getParticipantEventResults(
|
|||
const db = providedDb || database();
|
||||
|
||||
return await db.query.eventResults.findMany({
|
||||
where: eq(schema.eventResults.participantId, participantId),
|
||||
where: eq(schema.eventResults.seasonParticipantId, participantId),
|
||||
with: {
|
||||
scoringEvent: true,
|
||||
},
|
||||
|
|
@ -203,7 +203,7 @@ export async function hasParticipantResult(
|
|||
const result = await db.query.eventResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.eventResults.scoringEventId, eventId),
|
||||
eq(schema.eventResults.participantId, participantId)
|
||||
eq(schema.eventResults.seasonParticipantId, participantId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -226,10 +226,10 @@ export async function getEventResultsForParticipants(
|
|||
return await db.query.eventResults.findMany({
|
||||
where: and(
|
||||
eq(schema.eventResults.scoringEventId, eventId),
|
||||
inArray(schema.eventResults.participantId, participantIds)
|
||||
inArray(schema.eventResults.seasonParticipantId, participantIds)
|
||||
),
|
||||
with: {
|
||||
participant: {
|
||||
seasonParticipant: {
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { database } from "~/database/context";
|
||||
import { participantGolfSkills, participants } from "~/database/schema";
|
||||
import { participantGolfSkills, seasonParticipants } from "~/database/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
export interface GolfSkillsRecord {
|
||||
|
|
@ -40,7 +40,7 @@ export interface GolfSkillsInput {
|
|||
|
||||
/**
|
||||
* Get all golf skill records for a sports season, joined with participant names.
|
||||
* Returns one record per participant (participants with no record are excluded).
|
||||
* Returns one record per participant (seasonParticipants with no record are excluded).
|
||||
*/
|
||||
export async function getGolfSkillsForSeason(
|
||||
sportsSeasonId: string
|
||||
|
|
@ -58,12 +58,12 @@ export async function getGolfSkillsForSeason(
|
|||
openChampionshipOdds: participantGolfSkills.openChampionshipOdds,
|
||||
pgaChampionshipOdds: participantGolfSkills.pgaChampionshipOdds,
|
||||
updatedAt: participantGolfSkills.updatedAt,
|
||||
participantName: participants.name,
|
||||
participantName: seasonParticipants.name,
|
||||
})
|
||||
.from(participantGolfSkills)
|
||||
.innerJoin(participants, eq(participantGolfSkills.participantId, participants.id))
|
||||
.innerJoin(seasonParticipants, eq(participantGolfSkills.participantId, seasonParticipants.id))
|
||||
.where(eq(participantGolfSkills.sportsSeasonId, sportsSeasonId))
|
||||
.orderBy(participants.name);
|
||||
.orderBy(seasonParticipants.name);
|
||||
|
||||
return rows.map((r) => ({
|
||||
...r,
|
||||
|
|
@ -94,7 +94,7 @@ export async function getGolfSkillsMap(
|
|||
}
|
||||
|
||||
/**
|
||||
* Upsert golf skill ratings for a batch of participants.
|
||||
* Upsert golf skill ratings for a batch of seasonParticipants.
|
||||
* Uses INSERT … ON CONFLICT DO UPDATE so all columns are overwritten atomically.
|
||||
*/
|
||||
export async function batchUpsertGolfSkills(
|
||||
|
|
|
|||
|
|
@ -334,8 +334,8 @@ export async function getUpcomingGroupStageMatchesForParticipants(
|
|||
const allParticipantIds = [
|
||||
...new Set(rows.flatMap((r) => [r.participant1Id, r.participant2Id])),
|
||||
];
|
||||
const participantRows = await db.query.participants.findMany({
|
||||
where: inArray(schema.participants.id, allParticipantIds),
|
||||
const participantRows = await db.query.seasonParticipants.findMany({
|
||||
where: inArray(schema.seasonParticipants.id, allParticipantIds),
|
||||
});
|
||||
const participantMap = new Map(participantRows.map((p) => [p.id, p]));
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export * from "./team";
|
|||
export * from "./commissioner";
|
||||
export * from "./sport";
|
||||
export * from "./sports-season";
|
||||
export * from "./participant";
|
||||
export * from "./season-participant";
|
||||
export * from "./season-template";
|
||||
export * from "./season-template-sport";
|
||||
export * from "./season-sport";
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* Model for Participant Expected Values
|
||||
*
|
||||
* Manages probability distributions and calculated EVs for participants
|
||||
* Manages probability distributions and calculated EVs for seasonParticipants
|
||||
* in sports seasons.
|
||||
*/
|
||||
|
||||
import { database } from "~/database/context";
|
||||
import { participantExpectedValues, participants } from "~/database/schema";
|
||||
import { seasonParticipantExpectedValues, seasonParticipants } from "~/database/schema";
|
||||
import { eq, and, count, sql } from "drizzle-orm";
|
||||
import type { ProbabilityDistribution, ScoringRules } from "~/services/ev-calculator";
|
||||
import { calculateEV, normalizeProbabilities, calculateReplacementLevel, calculateVORP } from "~/services/ev-calculator";
|
||||
|
|
@ -53,9 +53,9 @@ export interface UpdateProbabilityInput {
|
|||
* Recalculate and persist VORP for every participant in a sports season.
|
||||
*
|
||||
* VORP = participant EV − replacement level EV
|
||||
* Replacement level = average EV of participants ranked 12th–14th in this season.
|
||||
* Replacement level = average EV of seasonParticipants ranked 12th–14th in this season.
|
||||
*
|
||||
* Call this after any operation that changes EVs for participants in the season.
|
||||
* Call this after any operation that changes EVs for seasonParticipants in the season.
|
||||
*/
|
||||
export async function syncVorpForSeason(sportsSeasonId: string): Promise<void> {
|
||||
const db = database();
|
||||
|
|
@ -72,12 +72,12 @@ export async function syncVorpForSeason(sportsSeasonId: string): Promise<void> {
|
|||
|
||||
const now = new Date();
|
||||
|
||||
// Build a single CASE expression to update all participants in one query
|
||||
// Build a single CASE expression to update all seasonParticipants in one query
|
||||
// instead of N individual UPDATE statements.
|
||||
const vorpCaseExpr = sql`CASE ${sql.join(
|
||||
sorted.map((ev) => {
|
||||
const vorp = calculateVORP(parseFloat(ev.expectedValue), replacementLevel);
|
||||
return sql`WHEN ${participants.id} = ${ev.participantId} THEN ${vorp.toFixed(4)}::numeric`;
|
||||
return sql`WHEN ${seasonParticipants.id} = ${ev.participantId} THEN ${vorp.toFixed(4)}::numeric`;
|
||||
}),
|
||||
sql` `
|
||||
)} END`;
|
||||
|
|
@ -85,9 +85,9 @@ export async function syncVorpForSeason(sportsSeasonId: string): Promise<void> {
|
|||
const ids = sorted.map((ev) => ev.participantId);
|
||||
|
||||
await db
|
||||
.update(participants)
|
||||
.update(seasonParticipants)
|
||||
.set({ vorpValue: vorpCaseExpr, updatedAt: now })
|
||||
.where(sql`${participants.id} = ANY(${sql`ARRAY[${sql.join(ids.map((id) => sql`${id}`), sql`, `)}]::uuid[]`})`);
|
||||
.where(sql`${seasonParticipants.id} = ANY(${sql`ARRAY[${sql.join(ids.map((id) => sql`${id}`), sql`, `)}]::uuid[]`})`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,11 +118,11 @@ export async function upsertParticipantEV(
|
|||
// Check if record exists
|
||||
const existing = await db
|
||||
.select()
|
||||
.from(participantExpectedValues)
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(
|
||||
and(
|
||||
eq(participantExpectedValues.participantId, participantId),
|
||||
eq(participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
|
@ -134,7 +134,7 @@ export async function upsertParticipantEV(
|
|||
if (existing.length > 0) {
|
||||
// Update existing
|
||||
const updated = await db
|
||||
.update(participantExpectedValues)
|
||||
.update(seasonParticipantExpectedValues)
|
||||
.set({
|
||||
probFirst: probabilities.probFirst.toString(),
|
||||
probSecond: probabilities.probSecond.toString(),
|
||||
|
|
@ -150,14 +150,14 @@ export async function upsertParticipantEV(
|
|||
calculatedAt: now,
|
||||
updatedAt: now,
|
||||
})
|
||||
.where(eq(participantExpectedValues.id, existing[0].id))
|
||||
.where(eq(seasonParticipantExpectedValues.id, existing[0].id))
|
||||
.returning();
|
||||
|
||||
result = updated[0];
|
||||
} else {
|
||||
// Create new
|
||||
const created = await db
|
||||
.insert(participantExpectedValues)
|
||||
.insert(seasonParticipantExpectedValues)
|
||||
.values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
|
|
@ -180,13 +180,13 @@ export async function upsertParticipantEV(
|
|||
result = created[0];
|
||||
}
|
||||
|
||||
// Sync calculated EV to participants table for draft room ranking
|
||||
// Sync calculated EV to seasonParticipants table for draft room ranking
|
||||
await db
|
||||
.update(participants)
|
||||
.update(seasonParticipants)
|
||||
.set({ expectedValue: expectedValue.toString(), updatedAt: now })
|
||||
.where(eq(participants.id, participantId));
|
||||
.where(eq(seasonParticipants.id, participantId));
|
||||
|
||||
// Recalculate VORP for all participants in this season (replacement level may have shifted)
|
||||
// Recalculate VORP for all seasonParticipants in this season (replacement level may have shifted)
|
||||
await syncVorpForSeason(sportsSeasonId);
|
||||
|
||||
return result;
|
||||
|
|
@ -209,7 +209,7 @@ export async function upsertParticipantEVWithNormalization(
|
|||
|
||||
export async function countAllParticipantEVs(): Promise<number> {
|
||||
const db = database();
|
||||
const result = await db.select({ value: count() }).from(participantExpectedValues);
|
||||
const result = await db.select({ value: count() }).from(seasonParticipantExpectedValues);
|
||||
return result[0].value;
|
||||
}
|
||||
|
||||
|
|
@ -223,11 +223,11 @@ export async function getParticipantEV(
|
|||
const db = database();
|
||||
const result = await db
|
||||
.select()
|
||||
.from(participantExpectedValues)
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(
|
||||
and(
|
||||
eq(participantExpectedValues.participantId, participantId),
|
||||
eq(participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
|
@ -244,8 +244,8 @@ export async function getAllParticipantEVsForSeason(
|
|||
const db = database();
|
||||
return db
|
||||
.select()
|
||||
.from(participantExpectedValues)
|
||||
.where(eq(participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -257,21 +257,21 @@ export async function deleteParticipantEV(
|
|||
): Promise<void> {
|
||||
const db = database();
|
||||
await db
|
||||
.delete(participantExpectedValues)
|
||||
.delete(seasonParticipantExpectedValues)
|
||||
.where(
|
||||
and(
|
||||
eq(participantExpectedValues.participantId, participantId),
|
||||
eq(participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
)
|
||||
);
|
||||
|
||||
// Reset this participant's EV and VORP to 0 (no longer ranked)
|
||||
await db
|
||||
.update(participants)
|
||||
.update(seasonParticipants)
|
||||
.set({ expectedValue: "0", vorpValue: "0", updatedAt: new Date() })
|
||||
.where(eq(participants.id, participantId));
|
||||
.where(eq(seasonParticipants.id, participantId));
|
||||
|
||||
// Recalculate VORP for remaining participants — replacement level may have shifted
|
||||
// Recalculate VORP for remaining seasonParticipants — replacement level may have shifted
|
||||
await syncVorpForSeason(sportsSeasonId);
|
||||
}
|
||||
|
||||
|
|
@ -301,12 +301,12 @@ export async function batchUpsertParticipantEVs(
|
|||
const expectedValue = calculateEV(probabilities, scoringRules);
|
||||
|
||||
const existing = await tx
|
||||
.select({ id: participantExpectedValues.id })
|
||||
.from(participantExpectedValues)
|
||||
.select({ id: seasonParticipantExpectedValues.id })
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(
|
||||
and(
|
||||
eq(participantExpectedValues.participantId, participantId),
|
||||
eq(participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
|
@ -330,24 +330,24 @@ export async function batchUpsertParticipantEVs(
|
|||
|
||||
if (existing.length > 0) {
|
||||
const [updated] = await tx
|
||||
.update(participantExpectedValues)
|
||||
.update(seasonParticipantExpectedValues)
|
||||
// Only overwrite sourceOdds if explicitly provided; preserve existing value otherwise
|
||||
.set(sourceOdds !== undefined ? { ...baseValues, sourceOdds } : baseValues)
|
||||
.where(eq(participantExpectedValues.id, existing[0].id))
|
||||
.where(eq(seasonParticipantExpectedValues.id, existing[0].id))
|
||||
.returning();
|
||||
result = updated;
|
||||
} else {
|
||||
const [created] = await tx
|
||||
.insert(participantExpectedValues)
|
||||
.insert(seasonParticipantExpectedValues)
|
||||
.values({ participantId, sportsSeasonId, ...baseValues, sourceOdds: sourceOdds ?? null })
|
||||
.returning();
|
||||
result = created;
|
||||
}
|
||||
|
||||
await tx
|
||||
.update(participants)
|
||||
.update(seasonParticipants)
|
||||
.set({ expectedValue: expectedValue.toString(), updatedAt: now })
|
||||
.where(eq(participants.id, participantId));
|
||||
.where(eq(seasonParticipants.id, participantId));
|
||||
|
||||
results.push(result);
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ export async function batchUpsertParticipantEVs(
|
|||
}
|
||||
|
||||
/**
|
||||
* Save American odds for a batch of participants without touching probabilities or EV.
|
||||
* Save American odds for a batch of seasonParticipants without touching probabilities or EV.
|
||||
* Used by the futures-odds admin page to persist odds before running the full simulation.
|
||||
*/
|
||||
export async function batchSaveSourceOdds(
|
||||
|
|
@ -374,24 +374,24 @@ export async function batchSaveSourceOdds(
|
|||
|
||||
for (const { participantId, sportsSeasonId, sourceOdds } of inputs) {
|
||||
const existing = await tx
|
||||
.select({ id: participantExpectedValues.id })
|
||||
.from(participantExpectedValues)
|
||||
.select({ id: seasonParticipantExpectedValues.id })
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(
|
||||
and(
|
||||
eq(participantExpectedValues.participantId, participantId),
|
||||
eq(participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
||||
if (existing.length > 0) {
|
||||
await tx
|
||||
.update(participantExpectedValues)
|
||||
.update(seasonParticipantExpectedValues)
|
||||
.set({ sourceOdds, updatedAt: now })
|
||||
.where(eq(participantExpectedValues.id, existing[0].id));
|
||||
.where(eq(seasonParticipantExpectedValues.id, existing[0].id));
|
||||
} else {
|
||||
// Insert a stub record — probabilities/EV will be filled in by the simulator
|
||||
await tx.insert(participantExpectedValues).values({
|
||||
await tx.insert(seasonParticipantExpectedValues).values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
probFirst: "0",
|
||||
|
|
@ -414,7 +414,7 @@ export async function batchSaveSourceOdds(
|
|||
}
|
||||
|
||||
/**
|
||||
* Persist raw Elo ratings (and optional world rankings) for a batch of participants.
|
||||
* Persist raw Elo ratings (and optional world rankings) for a batch of seasonParticipants.
|
||||
* Used by Elo-based simulators like snooker_bracket and darts_bracket.
|
||||
* Creates stub records if none exist; does not touch probabilities or EV.
|
||||
* Uses INSERT ... ON CONFLICT DO UPDATE to avoid N+1 queries.
|
||||
|
|
@ -427,7 +427,7 @@ export async function batchSaveSourceElos(
|
|||
const now = new Date();
|
||||
|
||||
await db
|
||||
.insert(participantExpectedValues)
|
||||
.insert(seasonParticipantExpectedValues)
|
||||
.values(
|
||||
inputs.map(({ participantId, sportsSeasonId, sourceElo, worldRanking }) => ({
|
||||
participantId,
|
||||
|
|
@ -449,7 +449,7 @@ export async function batchSaveSourceElos(
|
|||
}))
|
||||
)
|
||||
.onConflictDoUpdate({
|
||||
target: [participantExpectedValues.participantId, participantExpectedValues.sportsSeasonId],
|
||||
target: [seasonParticipantExpectedValues.participantId, seasonParticipantExpectedValues.sportsSeasonId],
|
||||
set: {
|
||||
sourceElo: sql`excluded.source_elo`,
|
||||
worldRanking: sql`excluded.world_ranking`,
|
||||
|
|
@ -499,26 +499,26 @@ export async function recalculateEV(
|
|||
const db = database();
|
||||
const now = new Date();
|
||||
const updated = await db
|
||||
.update(participantExpectedValues)
|
||||
.update(seasonParticipantExpectedValues)
|
||||
.set({
|
||||
expectedValue: newEV.toString(),
|
||||
calculatedAt: now,
|
||||
updatedAt: now,
|
||||
})
|
||||
.where(eq(participantExpectedValues.id, existing.id))
|
||||
.where(eq(seasonParticipantExpectedValues.id, existing.id))
|
||||
.returning();
|
||||
|
||||
// Sync recalculated EV to participants table
|
||||
// Sync recalculated EV to seasonParticipants table
|
||||
await db
|
||||
.update(participants)
|
||||
.update(seasonParticipants)
|
||||
.set({ expectedValue: newEV.toString(), updatedAt: now })
|
||||
.where(eq(participants.id, participantId));
|
||||
.where(eq(seasonParticipants.id, participantId));
|
||||
|
||||
return updated[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate EVs for all participants in a sports season
|
||||
* Recalculate EVs for all seasonParticipants in a sports season
|
||||
* Used when scoring rules change
|
||||
*/
|
||||
export async function recalculateAllEVsForSeason(
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@ import { eq, and } from "drizzle-orm";
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
|
||||
export type ParticipantResult = typeof schema.participantResults.$inferSelect;
|
||||
export type ParticipantResult = typeof schema.seasonParticipantResults.$inferSelect;
|
||||
export type ParticipantResultWithParticipant = ParticipantResult & {
|
||||
participant: { id: string; name: string } | null;
|
||||
};
|
||||
export type NewParticipantResult = typeof schema.participantResults.$inferInsert;
|
||||
export type NewParticipantResult = typeof schema.seasonParticipantResults.$inferInsert;
|
||||
|
||||
export async function createParticipantResult(
|
||||
data: NewParticipantResult
|
||||
): Promise<ParticipantResult> {
|
||||
const db = database();
|
||||
const [result] = await db
|
||||
.insert(schema.participantResults)
|
||||
.insert(schema.seasonParticipantResults)
|
||||
.values(data)
|
||||
.returning();
|
||||
return result;
|
||||
|
|
@ -24,7 +24,7 @@ export async function createManyParticipantResults(
|
|||
): Promise<ParticipantResult[]> {
|
||||
const db = database();
|
||||
return await db
|
||||
.insert(schema.participantResults)
|
||||
.insert(schema.seasonParticipantResults)
|
||||
.values(data)
|
||||
.returning();
|
||||
}
|
||||
|
|
@ -33,8 +33,8 @@ export async function findParticipantResultById(
|
|||
id: string
|
||||
): Promise<ParticipantResult | undefined> {
|
||||
const db = database();
|
||||
return await db.query.participantResults.findFirst({
|
||||
where: eq(schema.participantResults.id, id),
|
||||
return await db.query.seasonParticipantResults.findFirst({
|
||||
where: eq(schema.seasonParticipantResults.id, id),
|
||||
with: {
|
||||
participant: true,
|
||||
sportsSeason: {
|
||||
|
|
@ -50,8 +50,8 @@ export async function findParticipantResultByParticipantId(
|
|||
participantId: string
|
||||
): Promise<ParticipantResult | undefined> {
|
||||
const db = database();
|
||||
return await db.query.participantResults.findFirst({
|
||||
where: eq(schema.participantResults.participantId, participantId),
|
||||
return await db.query.seasonParticipantResults.findFirst({
|
||||
where: eq(schema.seasonParticipantResults.participantId, participantId),
|
||||
with: {
|
||||
participant: true,
|
||||
sportsSeason: {
|
||||
|
|
@ -67,8 +67,8 @@ export async function findParticipantResultsBySportsSeasonId(
|
|||
sportsSeasonId: string
|
||||
): Promise<ParticipantResultWithParticipant[]> {
|
||||
const db = database();
|
||||
return await db.query.participantResults.findMany({
|
||||
where: eq(schema.participantResults.sportsSeasonId, sportsSeasonId),
|
||||
return await db.query.seasonParticipantResults.findMany({
|
||||
where: eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId),
|
||||
orderBy: (results, { asc }) => [asc(results.finalPosition)],
|
||||
with: {
|
||||
participant: true,
|
||||
|
|
@ -82,16 +82,16 @@ export async function updateParticipantResult(
|
|||
): Promise<ParticipantResult> {
|
||||
const db = database();
|
||||
const [result] = await db
|
||||
.update(schema.participantResults)
|
||||
.update(schema.seasonParticipantResults)
|
||||
.set({ ...data, updatedAt: new Date() })
|
||||
.where(eq(schema.participantResults.id, id))
|
||||
.where(eq(schema.seasonParticipantResults.id, id))
|
||||
.returning();
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function deleteParticipantResult(id: string): Promise<void> {
|
||||
const db = database();
|
||||
await db.delete(schema.participantResults).where(eq(schema.participantResults.id, id));
|
||||
await db.delete(schema.seasonParticipantResults).where(eq(schema.seasonParticipantResults.id, id));
|
||||
}
|
||||
|
||||
export async function deleteParticipantResultsBySportsSeasonId(
|
||||
|
|
@ -99,8 +99,8 @@ export async function deleteParticipantResultsBySportsSeasonId(
|
|||
): Promise<void> {
|
||||
const db = database();
|
||||
await db
|
||||
.delete(schema.participantResults)
|
||||
.where(eq(schema.participantResults.sportsSeasonId, sportsSeasonId));
|
||||
.delete(schema.seasonParticipantResults)
|
||||
.where(eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,10 +117,10 @@ export async function setParticipantResult(
|
|||
const db = database();
|
||||
|
||||
// Check if result already exists
|
||||
const existing = await db.query.participantResults.findFirst({
|
||||
const existing = await db.query.seasonParticipantResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantResults.participantId, participantId),
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.participantId, participantId),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -144,16 +144,16 @@ export async function getOrCreateParticipantQPTotal(
|
|||
) {
|
||||
const db = providedDb || database();
|
||||
|
||||
let total = await db.query.participantQualifyingTotals.findFirst({
|
||||
let total = await db.query.seasonParticipantQualifyingTotals.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantQualifyingTotals.participantId, participantId),
|
||||
eq(schema.participantQualifyingTotals.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantQualifyingTotals.participantId, participantId),
|
||||
eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
if (!total) {
|
||||
const [created] = await db
|
||||
.insert(schema.participantQualifyingTotals)
|
||||
.insert(schema.seasonParticipantQualifyingTotals)
|
||||
.values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
|
|
@ -184,12 +184,12 @@ export async function addQualifyingPoints(
|
|||
|
||||
// Update with new points (do NOT increment eventsScored here)
|
||||
const [updated] = await db
|
||||
.update(schema.participantQualifyingTotals)
|
||||
.update(schema.seasonParticipantQualifyingTotals)
|
||||
.set({
|
||||
totalQualifyingPoints: (parseFloat(total.totalQualifyingPoints) + pointsToAdd).toString(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(schema.participantQualifyingTotals.id, total.id))
|
||||
.where(eq(schema.seasonParticipantQualifyingTotals.id, total.id))
|
||||
.returning();
|
||||
|
||||
return updated;
|
||||
|
|
@ -208,7 +208,7 @@ export async function recalculateParticipantQP(
|
|||
|
||||
// Get all event results for this participant in this sports season
|
||||
const eventResults = await db.query.eventResults.findMany({
|
||||
where: eq(schema.eventResults.participantId, participantId),
|
||||
where: eq(schema.eventResults.seasonParticipantId, participantId),
|
||||
with: {
|
||||
scoringEvent: true,
|
||||
},
|
||||
|
|
@ -238,13 +238,13 @@ export async function recalculateParticipantQP(
|
|||
|
||||
// Update with recalculated values
|
||||
await db
|
||||
.update(schema.participantQualifyingTotals)
|
||||
.update(schema.seasonParticipantQualifyingTotals)
|
||||
.set({
|
||||
totalQualifyingPoints: totalQP.toString(),
|
||||
eventsScored,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(schema.participantQualifyingTotals.id, total.id));
|
||||
.where(eq(schema.seasonParticipantQualifyingTotals.id, total.id));
|
||||
|
||||
return { totalQP, eventsScored };
|
||||
}
|
||||
|
|
@ -271,9 +271,9 @@ export async function getQPStandings(
|
|||
) {
|
||||
const db = providedDb || database();
|
||||
|
||||
return await db.query.participantQualifyingTotals.findMany({
|
||||
where: eq(schema.participantQualifyingTotals.sportsSeasonId, sportsSeasonId),
|
||||
orderBy: [desc(sql`CAST(${schema.participantQualifyingTotals.totalQualifyingPoints} AS DECIMAL)`)],
|
||||
return await db.query.seasonParticipantQualifyingTotals.findMany({
|
||||
where: eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId),
|
||||
orderBy: [desc(sql`CAST(${schema.seasonParticipantQualifyingTotals.totalQualifyingPoints} AS DECIMAL)`)],
|
||||
with: {
|
||||
participant: true,
|
||||
},
|
||||
|
|
@ -325,9 +325,9 @@ export async function updateFinalRankings(
|
|||
// Update all rankings
|
||||
for (const update of updates) {
|
||||
await db
|
||||
.update(schema.participantQualifyingTotals)
|
||||
.update(schema.seasonParticipantQualifyingTotals)
|
||||
.set({ finalRanking: update.finalRanking, updatedAt: new Date() })
|
||||
.where(eq(schema.participantQualifyingTotals.id, update.id));
|
||||
.where(eq(schema.seasonParticipantQualifyingTotals.id, update.id));
|
||||
}
|
||||
|
||||
return updates;
|
||||
|
|
@ -343,6 +343,6 @@ export async function resetQualifyingPoints(
|
|||
const db = providedDb || database();
|
||||
|
||||
await db
|
||||
.delete(schema.participantQualifyingTotals)
|
||||
.where(eq(schema.participantQualifyingTotals.sportsSeasonId, sportsSeasonId));
|
||||
.delete(schema.seasonParticipantQualifyingTotals)
|
||||
.where(eq(schema.seasonParticipantQualifyingTotals.sportsSeasonId, sportsSeasonId));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ export async function processPlayoffEvent(
|
|||
|
||||
// PHASE 5.3: Handle teams that didn't make the playoffs
|
||||
// Get all participants in the sports season
|
||||
const allParticipants = await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, event.sportsSeasonId),
|
||||
const allParticipants = await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, event.sportsSeasonId),
|
||||
});
|
||||
|
||||
// Get all participant IDs that are in ANY playoff match (winners or losers)
|
||||
|
|
@ -222,10 +222,10 @@ export async function processPlayoffEvent(
|
|||
for (const participant of allParticipants) {
|
||||
if (!participantsInBracket.has(participant.id)) {
|
||||
// Check if they already have a result (don't overwrite)
|
||||
const existingResult = await db.query.participantResults.findFirst({
|
||||
const existingResult = await db.query.seasonParticipantResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantResults.participantId, participant.id),
|
||||
eq(schema.participantResults.sportsSeasonId, event.sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.participantId, participant.id),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, event.sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -506,10 +506,10 @@ async function upsertParticipantResult(
|
|||
db: ReturnType<typeof database>,
|
||||
isPartialScore = false
|
||||
): Promise<number | null> {
|
||||
const existing = await db.query.participantResults.findFirst({
|
||||
const existing = await db.query.seasonParticipantResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantResults.participantId, participantId),
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.participantId, participantId),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -520,16 +520,16 @@ async function upsertParticipantResult(
|
|||
if (!existing.isPartialScore && isPartialScore) return null;
|
||||
|
||||
await db
|
||||
.update(schema.participantResults)
|
||||
.update(schema.seasonParticipantResults)
|
||||
.set({
|
||||
finalPosition,
|
||||
isPartialScore,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(schema.participantResults.id, existing.id));
|
||||
.where(eq(schema.seasonParticipantResults.id, existing.id));
|
||||
return existing.finalPosition ?? 0;
|
||||
} else {
|
||||
await db.insert(schema.participantResults).values({
|
||||
await db.insert(schema.seasonParticipantResults).values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
finalPosition,
|
||||
|
|
@ -651,7 +651,7 @@ export async function processQualifyingEvent(
|
|||
|
||||
// Recalculate totals for all participants from scratch
|
||||
// This is the source of truth - sums all their event_results
|
||||
const participantIds = new Set(results.map(r => r.participantId));
|
||||
const participantIds = new Set(results.map(r => r.seasonParticipantId));
|
||||
for (const participantId of participantIds) {
|
||||
await recalculateParticipantQP(participantId, event.sportsSeasonId, db);
|
||||
}
|
||||
|
|
@ -752,10 +752,10 @@ export async function finalizeQualifyingPoints(
|
|||
if (currentPlacement <= standings.length) {
|
||||
for (let i = currentPlacement - 1; i < standings.length; i++) {
|
||||
const standing = standings[i];
|
||||
const hasResult = await db.query.participantResults.findFirst({
|
||||
const hasResult = await db.query.seasonParticipantResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantResults.participantId, standing.participantId),
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.participantId, standing.participantId),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -1388,11 +1388,11 @@ export async function recalculateAffectedLeagues(
|
|||
.filter((id): id is string => id !== null);
|
||||
const finalizedLoserIds = new Set<string>();
|
||||
if (loserParticipantIds.length > 0) {
|
||||
const loserResults = await db.query.participantResults.findMany({
|
||||
const loserResults = await db.query.seasonParticipantResults.findMany({
|
||||
where: and(
|
||||
inArray(schema.participantResults.participantId, loserParticipantIds),
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.participantResults.isPartialScore, false)
|
||||
inArray(schema.seasonParticipantResults.participantId, loserParticipantIds),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.seasonParticipantResults.isPartialScore, false)
|
||||
),
|
||||
});
|
||||
for (const r of loserResults) finalizedLoserIds.add(r.participantId);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ export async function getScoringEventsForSportsSeason(
|
|||
with: {
|
||||
eventResults: {
|
||||
with: {
|
||||
participant: true,
|
||||
seasonParticipant: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -224,7 +224,7 @@ export async function deleteScoringEvent(
|
|||
const results = await db.query.eventResults.findMany({
|
||||
where: eq(schema.eventResults.scoringEventId, eventId),
|
||||
});
|
||||
affectedParticipantIds = results.map((r) => r.participantId);
|
||||
affectedParticipantIds = results.map((r) => r.seasonParticipantId);
|
||||
wasQPProcessed = results.some(
|
||||
(r) => r.qualifyingPointsAwarded && parseFloat(r.qualifyingPointsAwarded) > 0
|
||||
);
|
||||
|
|
@ -233,8 +233,8 @@ export async function deleteScoringEvent(
|
|||
await db.transaction(async (tx) => {
|
||||
if (event.eventType === "playoff_game") {
|
||||
await tx
|
||||
.delete(schema.participantResults)
|
||||
.where(eq(schema.participantResults.sportsSeasonId, event.sportsSeasonId));
|
||||
.delete(schema.seasonParticipantResults)
|
||||
.where(eq(schema.seasonParticipantResults.sportsSeasonId, event.sportsSeasonId));
|
||||
}
|
||||
// Cascades: playoffMatches, eventResults, tournamentGroups/Members
|
||||
await tx.delete(schema.scoringEvents).where(eq(schema.scoringEvents.id, eventId));
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ import { eq, inArray, count, and, sql, asc, desc } from "drizzle-orm";
|
|||
import { database } from "~/database/context";
|
||||
import * as schema from "~/database/schema";
|
||||
|
||||
export type Participant = typeof schema.participants.$inferSelect;
|
||||
export type NewParticipant = typeof schema.participants.$inferInsert;
|
||||
export type Participant = typeof schema.seasonParticipants.$inferSelect;
|
||||
export type NewParticipant = typeof schema.seasonParticipants.$inferInsert;
|
||||
|
||||
export async function createParticipant(data: NewParticipant): Promise<Participant> {
|
||||
const db = database();
|
||||
const [participant] = await db
|
||||
.insert(schema.participants)
|
||||
.insert(schema.seasonParticipants)
|
||||
.values(data)
|
||||
.returning();
|
||||
return participant;
|
||||
|
|
@ -17,15 +17,15 @@ export async function createParticipant(data: NewParticipant): Promise<Participa
|
|||
export async function createManyParticipants(data: NewParticipant[]): Promise<Participant[]> {
|
||||
const db = database();
|
||||
return await db
|
||||
.insert(schema.participants)
|
||||
.insert(schema.seasonParticipants)
|
||||
.values(data)
|
||||
.returning();
|
||||
}
|
||||
|
||||
export async function findParticipantById(id: string): Promise<Participant | undefined> {
|
||||
const db = database();
|
||||
return await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, id),
|
||||
return await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, id),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
@ -43,11 +43,11 @@ export async function findParticipantByName(
|
|||
const db = database();
|
||||
const results = await db
|
||||
.select()
|
||||
.from(schema.participants)
|
||||
.from(schema.seasonParticipants)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
sql`lower(${schema.participants.name}) = lower(${name})`
|
||||
eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
sql`lower(${schema.seasonParticipants.name}) = lower(${name})`
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
|
@ -56,8 +56,8 @@ export async function findParticipantByName(
|
|||
|
||||
export async function findParticipantsBySportsSeasonId(sportsSeasonId: string): Promise<Participant[]> {
|
||||
const db = database();
|
||||
return await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
return await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
orderBy: (participants, { asc: orderAsc }) => [orderAsc(participants.name)],
|
||||
});
|
||||
}
|
||||
|
|
@ -66,8 +66,8 @@ export async function findParticipantsByExternalId(
|
|||
externalId: string
|
||||
): Promise<Participant[]> {
|
||||
const db = database();
|
||||
return await db.query.participants.findMany({
|
||||
where: eq(schema.participants.externalId, externalId),
|
||||
return await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.externalId, externalId),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
@ -84,22 +84,22 @@ export async function updateParticipant(
|
|||
): Promise<Participant> {
|
||||
const db = database();
|
||||
const [participant] = await db
|
||||
.update(schema.participants)
|
||||
.update(schema.seasonParticipants)
|
||||
.set({ ...data, updatedAt: new Date() })
|
||||
.where(eq(schema.participants.id, id))
|
||||
.where(eq(schema.seasonParticipants.id, id))
|
||||
.returning();
|
||||
return participant;
|
||||
}
|
||||
|
||||
export async function countAllParticipants(): Promise<number> {
|
||||
const db = database();
|
||||
const result = await db.select({ value: count() }).from(schema.participants);
|
||||
const result = await db.select({ value: count() }).from(schema.seasonParticipants);
|
||||
return result[0].value;
|
||||
}
|
||||
|
||||
export async function deleteParticipant(id: string): Promise<void> {
|
||||
const db = database();
|
||||
await db.delete(schema.participants).where(eq(schema.participants.id, id));
|
||||
await db.delete(schema.seasonParticipants).where(eq(schema.seasonParticipants.id, id));
|
||||
}
|
||||
|
||||
export async function copyParticipantsFromSeason(
|
||||
|
|
@ -146,17 +146,17 @@ export async function getParticipantsForSeasonWithSports(seasonId: string, provi
|
|||
// Get all participants for these sports seasons with sport info
|
||||
const participants = await db
|
||||
.select({
|
||||
id: schema.participants.id,
|
||||
name: schema.participants.name,
|
||||
id: schema.seasonParticipants.id,
|
||||
name: schema.seasonParticipants.name,
|
||||
sport: {
|
||||
id: schema.sports.id,
|
||||
name: schema.sports.name,
|
||||
},
|
||||
})
|
||||
.from(schema.participants)
|
||||
.from(schema.seasonParticipants)
|
||||
.innerJoin(
|
||||
schema.sportsSeasons,
|
||||
eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sports,
|
||||
|
|
@ -164,8 +164,8 @@ export async function getParticipantsForSeasonWithSports(seasonId: string, provi
|
|||
)
|
||||
.where(
|
||||
sportsSeasonIds.length === 1
|
||||
? eq(schema.participants.sportsSeasonId, sportsSeasonIds[0])
|
||||
: inArray(schema.participants.sportsSeasonId, sportsSeasonIds)
|
||||
? eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds[0])
|
||||
: inArray(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds)
|
||||
);
|
||||
|
||||
return participants;
|
||||
|
|
@ -183,18 +183,18 @@ export async function getDraftParticipants(seasonId: string) {
|
|||
|
||||
return await db
|
||||
.select({
|
||||
id: schema.participants.id,
|
||||
name: schema.participants.name,
|
||||
vorpValue: schema.participants.vorpValue,
|
||||
id: schema.seasonParticipants.id,
|
||||
name: schema.seasonParticipants.name,
|
||||
vorpValue: schema.seasonParticipants.vorpValue,
|
||||
sport: schema.sports,
|
||||
})
|
||||
.from(schema.participants)
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.from(schema.seasonParticipants)
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.innerJoin(schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id))
|
||||
.where(
|
||||
sportsSeasonIds.length === 1
|
||||
? eq(schema.participants.sportsSeasonId, sportsSeasonIds[0])
|
||||
: inArray(schema.participants.sportsSeasonId, sportsSeasonIds)
|
||||
? eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds[0])
|
||||
: inArray(schema.seasonParticipants.sportsSeasonId, sportsSeasonIds)
|
||||
)
|
||||
.orderBy(desc(schema.participants.vorpValue), asc(schema.participants.name));
|
||||
.orderBy(desc(schema.seasonParticipants.vorpValue), asc(schema.seasonParticipants.name));
|
||||
}
|
||||
|
|
@ -211,8 +211,8 @@ export async function cloneSportsSeason(
|
|||
};
|
||||
|
||||
// Read all source data before writing anything
|
||||
const sourceParticipants = await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, sourceId),
|
||||
const sourceParticipants = await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, sourceId),
|
||||
});
|
||||
|
||||
const sourceEvents = await db.query.scoringEvents.findMany({
|
||||
|
|
@ -225,8 +225,8 @@ export async function cloneSportsSeason(
|
|||
: null;
|
||||
|
||||
// Read source futures odds and Elo ratings
|
||||
const sourceEvRows = await db.query.participantExpectedValues.findMany({
|
||||
where: eq(schema.participantExpectedValues.sportsSeasonId, sourceId),
|
||||
const sourceEvRows = await db.query.seasonParticipantExpectedValues.findMany({
|
||||
where: eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sourceId),
|
||||
});
|
||||
|
||||
// Build lookup: (externalId ?? name) → source EV, only for rows that have
|
||||
|
|
@ -251,7 +251,7 @@ export async function cloneSportsSeason(
|
|||
const newParticipants =
|
||||
sourceParticipants.length > 0
|
||||
? await tx
|
||||
.insert(schema.participants)
|
||||
.insert(schema.seasonParticipants)
|
||||
.values(
|
||||
sourceParticipants.map((p: typeof sourceParticipants[number]) => ({
|
||||
sportsSeasonId: newSeason.id,
|
||||
|
|
@ -288,7 +288,7 @@ export async function cloneSportsSeason(
|
|||
.filter((r): r is NonNullable<typeof r> => r !== null);
|
||||
|
||||
if (evRows.length > 0) {
|
||||
await tx.insert(schema.participantExpectedValues).values(evRows);
|
||||
await tx.insert(schema.seasonParticipantExpectedValues).values(evRows);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { database } from "~/database/context";
|
||||
import { participantSurfaceElos, participants } from "~/database/schema";
|
||||
import { seasonParticipantSurfaceElos, seasonParticipants } from "~/database/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
export type CourtSurface = "hard" | "clay" | "grass";
|
||||
|
|
@ -38,7 +38,7 @@ export interface SurfaceEloInput {
|
|||
|
||||
/**
|
||||
* Get all surface Elo records for a sports season, joined with participant names.
|
||||
* Returns one record per participant (participants with no Elo record are excluded).
|
||||
* Returns one record per participant (seasonParticipants with no Elo record are excluded).
|
||||
*/
|
||||
export async function getSurfaceElosForSeason(
|
||||
sportsSeasonId: string
|
||||
|
|
@ -46,26 +46,26 @@ export async function getSurfaceElosForSeason(
|
|||
const db = database();
|
||||
const rows = await db
|
||||
.select({
|
||||
id: participantSurfaceElos.id,
|
||||
participantId: participantSurfaceElos.participantId,
|
||||
sportsSeasonId: participantSurfaceElos.sportsSeasonId,
|
||||
worldRanking: participantSurfaceElos.worldRanking,
|
||||
eloHard: participantSurfaceElos.eloHard,
|
||||
eloClay: participantSurfaceElos.eloClay,
|
||||
eloGrass: participantSurfaceElos.eloGrass,
|
||||
updatedAt: participantSurfaceElos.updatedAt,
|
||||
participantName: participants.name,
|
||||
id: seasonParticipantSurfaceElos.id,
|
||||
participantId: seasonParticipantSurfaceElos.participantId,
|
||||
sportsSeasonId: seasonParticipantSurfaceElos.sportsSeasonId,
|
||||
worldRanking: seasonParticipantSurfaceElos.worldRanking,
|
||||
eloHard: seasonParticipantSurfaceElos.eloHard,
|
||||
eloClay: seasonParticipantSurfaceElos.eloClay,
|
||||
eloGrass: seasonParticipantSurfaceElos.eloGrass,
|
||||
updatedAt: seasonParticipantSurfaceElos.updatedAt,
|
||||
participantName: seasonParticipants.name,
|
||||
})
|
||||
.from(participantSurfaceElos)
|
||||
.innerJoin(participants, eq(participantSurfaceElos.participantId, participants.id))
|
||||
.where(eq(participantSurfaceElos.sportsSeasonId, sportsSeasonId))
|
||||
.orderBy(participants.name);
|
||||
.from(seasonParticipantSurfaceElos)
|
||||
.innerJoin(seasonParticipants, eq(seasonParticipantSurfaceElos.participantId, seasonParticipants.id))
|
||||
.where(eq(seasonParticipantSurfaceElos.sportsSeasonId, sportsSeasonId))
|
||||
.orderBy(seasonParticipants.name);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsert surface Elo ratings for a batch of participants.
|
||||
* Upsert surface Elo ratings for a batch of seasonParticipants.
|
||||
* Uses INSERT ... ON CONFLICT DO UPDATE so all three surface columns are
|
||||
* overwritten atomically — the admin always submits all three values.
|
||||
*/
|
||||
|
|
@ -77,7 +77,7 @@ export async function batchUpsertSurfaceElos(
|
|||
const now = new Date();
|
||||
|
||||
await db
|
||||
.insert(participantSurfaceElos)
|
||||
.insert(seasonParticipantSurfaceElos)
|
||||
.values(
|
||||
inputs.map(({ participantId, sportsSeasonId, worldRanking, eloHard, eloClay, eloGrass }) => ({
|
||||
participantId,
|
||||
|
|
@ -90,7 +90,7 @@ export async function batchUpsertSurfaceElos(
|
|||
}))
|
||||
)
|
||||
.onConflictDoUpdate({
|
||||
target: [participantSurfaceElos.participantId, participantSurfaceElos.sportsSeasonId],
|
||||
target: [seasonParticipantSurfaceElos.participantId, seasonParticipantSurfaceElos.sportsSeasonId],
|
||||
set: {
|
||||
worldRanking: sql`excluded.world_ranking`,
|
||||
eloHard: sql`excluded.elo_hard`,
|
||||
|
|
@ -111,14 +111,14 @@ export async function getSurfaceEloMap(
|
|||
const db = database();
|
||||
const rows = await db
|
||||
.select({
|
||||
participantId: participantSurfaceElos.participantId,
|
||||
worldRanking: participantSurfaceElos.worldRanking,
|
||||
eloHard: participantSurfaceElos.eloHard,
|
||||
eloClay: participantSurfaceElos.eloClay,
|
||||
eloGrass: participantSurfaceElos.eloGrass,
|
||||
participantId: seasonParticipantSurfaceElos.participantId,
|
||||
worldRanking: seasonParticipantSurfaceElos.worldRanking,
|
||||
eloHard: seasonParticipantSurfaceElos.eloHard,
|
||||
eloClay: seasonParticipantSurfaceElos.eloClay,
|
||||
eloGrass: seasonParticipantSurfaceElos.eloGrass,
|
||||
})
|
||||
.from(participantSurfaceElos)
|
||||
.where(eq(participantSurfaceElos.sportsSeasonId, sportsSeasonId));
|
||||
.from(seasonParticipantSurfaceElos)
|
||||
.where(eq(seasonParticipantSurfaceElos.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
return new Map(rows.map((r) => [r.participantId, {
|
||||
worldRanking: r.worldRanking,
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ export async function getRecentTeamScoreEvents(
|
|||
|
||||
const participantNameById = new Map<string, string>();
|
||||
if (allParticipantIds.length > 0) {
|
||||
const participantRows = await db.query.participants.findMany({
|
||||
where: inArray(schema.participants.id, allParticipantIds),
|
||||
const participantRows = await db.query.seasonParticipants.findMany({
|
||||
where: inArray(schema.seasonParticipants.id, allParticipantIds),
|
||||
columns: { id: true, name: true },
|
||||
});
|
||||
for (const p of participantRows) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { logger } from "~/lib/logger";
|
|||
import { findAllSports } from "~/models/sport";
|
||||
import { findAllSportsSeasons } from "~/models/sports-season";
|
||||
import { findAllSeasonTemplates } from "~/models/season-template";
|
||||
import { countAllParticipants } from "~/models/participant";
|
||||
import { countAllParticipants } from "~/models/season-participant";
|
||||
import { countAllParticipantEVs } from "~/models/participant-expected-value";
|
||||
import { importSportsDataFromJSON } from "~/utils/sports-data-sync.server";
|
||||
import { Button } from "~/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from './+types/admin.sports-seasons.$id.elo-ratings';
|
|||
|
||||
import { logger } from '~/lib/logger';
|
||||
import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/participant';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/season-participant';
|
||||
import {
|
||||
getAllParticipantEVsForSeason,
|
||||
batchSaveSourceElos,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId.bracket";
|
||||
|
||||
import { findSportsSeasonById } from "~/models/sports-season";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/season-participant";
|
||||
import { getScoringEventById, updateScoringEvent } from "~/models/scoring-event";
|
||||
import {
|
||||
findPlayoffMatchesByEventId,
|
||||
|
|
@ -595,9 +595,9 @@ export async function action({ request, params }: Route.ActionArgs) {
|
|||
// the "never un-finalize" guard in upsertParticipantResult.
|
||||
const db = database();
|
||||
await db
|
||||
.delete(schema.participantResults)
|
||||
.delete(schema.seasonParticipantResults)
|
||||
.where(
|
||||
eq(schema.participantResults.sportsSeasonId, event.sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, event.sportsSeasonId)
|
||||
);
|
||||
|
||||
// Replay each completed match in bracket order (earlier rounds first).
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from './+types/admin.sports-seasons.$id.events.$eventId.cs
|
|||
|
||||
import { findSportsSeasonById } from '~/models/sports-season';
|
||||
import { getScoringEventById } from '~/models/scoring-event';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/participant';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/season-participant';
|
||||
import {
|
||||
getCs2StageResultsForEvent,
|
||||
upsertCs2StageAssignments,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId";
|
||||
import { logger } from "~/lib/logger";
|
||||
import { findSportsSeasonById } from "~/models/sports-season";
|
||||
import { findParticipantsBySportsSeasonId, createParticipant } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId, createParticipant } from "~/models/season-participant";
|
||||
import {
|
||||
getScoringEventById,
|
||||
completeScoringEvent,
|
||||
|
|
@ -134,7 +134,7 @@ export async function action({ request, params }: Route.ActionArgs) {
|
|||
// This marks them as "competed, earned nothing" so simulations skip this event.
|
||||
const allParticipants = await findParticipantsBySportsSeasonId(params.id);
|
||||
const existingResults = await getEventResults(params.eventId);
|
||||
const existingIds = new Set(existingResults.map((r) => r.participantId));
|
||||
const existingIds = new Set(existingResults.map((r) => r.seasonParticipantId));
|
||||
const missingIds = findParticipantsWithoutResults(
|
||||
allParticipants.map((p) => p.id),
|
||||
existingIds
|
||||
|
|
@ -373,7 +373,7 @@ export async function action({ request, params }: Route.ActionArgs) {
|
|||
|
||||
try {
|
||||
const existingResults = await getEventResults(params.eventId);
|
||||
const existingIds = new Set(existingResults.map((r) => r.participantId));
|
||||
const existingIds = new Set(existingResults.map((r) => r.seasonParticipantId));
|
||||
const newResults = filterNewResults(incoming, existingIds);
|
||||
|
||||
if (newResults.length > 0) {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ export default function EventResults({
|
|||
|
||||
// Create a map of participants with results for easy lookup
|
||||
const participantResultsMap = new Map(
|
||||
results.map((r: { participant: { id: string } }) => [r.participant.id, r])
|
||||
results.map((r: { seasonParticipant: { id: string } }) => [r.seasonParticipant.id, r])
|
||||
);
|
||||
|
||||
// Get participants without results
|
||||
|
|
@ -419,7 +419,7 @@ export default function EventResults({
|
|||
participants={participants}
|
||||
sportsSeasonId={sportsSeason.id}
|
||||
existingResultParticipantIds={
|
||||
new Set(results.map((r: { participant: { id: string } }) => r.participant.id))
|
||||
new Set(results.map((r: { seasonParticipant: { id: string } }) => r.seasonParticipant.id))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -576,7 +576,7 @@ export default function EventResults({
|
|||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{result.participant.name}</TableCell>
|
||||
<TableCell>{result.seasonParticipant.name}</TableCell>
|
||||
{event.isQualifyingEvent && event.isComplete && (
|
||||
<TableCell className="text-right">
|
||||
{result.qualifyingPointsAwarded ? (
|
||||
|
|
@ -620,7 +620,7 @@ export default function EventResults({
|
|||
variant="ghost"
|
||||
className="h-8 w-8 p-0 text-destructive hover:text-destructive"
|
||||
onClick={(e) => {
|
||||
if (!confirm(`Delete result for ${result.participant.name}?`)) {
|
||||
if (!confirm(`Delete result for ${result.seasonParticipant.name}?`)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { Route } from "./+types/admin.sports-seasons.$id.expected-values";
|
||||
import { logger } from "~/lib/logger";
|
||||
import { findSportsSeasonById } from "~/models/sports-season";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/season-participant";
|
||||
import {
|
||||
batchUpsertParticipantEVs,
|
||||
getAllParticipantEVsForSeason
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from './+types/admin.sports-seasons.$id.futures-odds';
|
|||
|
||||
import { logger } from '~/lib/logger';
|
||||
import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/participant';
|
||||
import { findParticipantsBySportsSeasonId } from '~/models/season-participant';
|
||||
import { getAllParticipantEVsForSeason, batchSaveSourceOdds, batchUpsertParticipantEVs } from '~/models/participant-expected-value';
|
||||
import { batchUpsertParticipantEvSnapshots } from '~/models/ev-snapshot';
|
||||
import { getSimulator, type SimulatorType } from '~/services/simulations/registry';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from './+types/admin.sports-seasons.$id.golf-skills';
|
|||
|
||||
import { logger } from '~/lib/logger';
|
||||
import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season';
|
||||
import { findParticipantsBySportsSeasonId, findParticipantByName, createParticipant } from '~/models/participant';
|
||||
import { findParticipantsBySportsSeasonId, findParticipantByName, createParticipant } from '~/models/season-participant';
|
||||
import { batchUpsertParticipantEVs } from '~/models/participant-expected-value';
|
||||
import { batchUpsertParticipantEvSnapshots } from '~/models/ev-snapshot';
|
||||
import { getGolfSkillsForSeason, batchUpsertGolfSkills } from '~/models/golf-skills';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
createParticipant,
|
||||
deleteParticipant,
|
||||
updateParticipant,
|
||||
} from "~/models/participant";
|
||||
} from "~/models/season-participant";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Input } from "~/components/ui/input";
|
||||
import { Label } from "~/components/ui/label";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from "./+types/admin.sports-seasons.$id.regular-standings"
|
|||
|
||||
import { logger } from "~/lib/logger";
|
||||
import { findSportsSeasonById } from "~/models/sports-season";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/season-participant";
|
||||
import { getRegularSeasonStandings, upsertManualStanding } from "~/models/regular-season-standings";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Input } from "~/components/ui/input";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import type { Route } from "./+types/admin.sports-seasons.$id.simulate";
|
|||
import { findSportsSeasonById, updateSportsSeason } from "~/models/sports-season";
|
||||
import { batchUpsertParticipantEVs } from "~/models/participant-expected-value";
|
||||
import { batchUpsertParticipantEvSnapshots } from "~/models/ev-snapshot";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/season-participant";
|
||||
import { getSimulator, type SimulatorType } from "~/services/simulations/registry";
|
||||
import { calculateEV } from "~/services/ev-calculator";
|
||||
import { DEFAULT_SCORING_RULES } from "~/lib/scoring-types";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from "./+types/admin.sports-seasons.$id.standings";
|
|||
|
||||
import { logger } from "~/lib/logger";
|
||||
import { findSportsSeasonById } from "~/models/sports-season";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId } from "~/models/season-participant";
|
||||
import { getSeasonResults, upsertSeasonResultsBulk } from "~/models/participant-season-result";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Input } from "~/components/ui/input";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { Route } from './+types/admin.sports-seasons.$id.surface-elo';
|
|||
|
||||
import { logger } from '~/lib/logger';
|
||||
import { findSportsSeasonById, updateSportsSeason } from '~/models/sports-season';
|
||||
import { findParticipantsBySportsSeasonId, findParticipantByName, createParticipant } from '~/models/participant';
|
||||
import { findParticipantsBySportsSeasonId, findParticipantByName, createParticipant } from '~/models/season-participant';
|
||||
import {
|
||||
batchUpsertParticipantEVs,
|
||||
} from '~/models/participant-expected-value';
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
getPendingStandingsMappings,
|
||||
deletePendingStandingsMapping,
|
||||
} from "~/models/pending-standings-mappings";
|
||||
import { findParticipantsBySportsSeasonId, updateParticipant } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId, updateParticipant } from "~/models/season-participant";
|
||||
import { getLastSyncedAt, upsertRegularSeasonStandings } from "~/models/regular-season-standings";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Input } from "~/components/ui/input";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
findParticipantsBySportsSeasonId: vi.fn(),
|
||||
findParticipantByName: vi.fn(),
|
||||
createParticipant: vi.fn(),
|
||||
|
|
@ -19,7 +19,7 @@ vi.mock("~/lib/logger", () => ({
|
|||
import {
|
||||
findParticipantByName,
|
||||
updateParticipant,
|
||||
} from "~/models/participant";
|
||||
} from "~/models/season-participant";
|
||||
import { action } from "~/routes/admin.sports-seasons.$id.participants";
|
||||
|
||||
const mockParams = { id: "season-1" };
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ vi.mock("~/models/draft-pick", () => ({
|
|||
getDraftPicksWithSports: vi.fn(),
|
||||
getTeamDraftPicksWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
getParticipantsForSeasonWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/season-sport", () => ({
|
||||
|
|
@ -138,7 +138,7 @@ describe("draft.force-manual-pick action", () => {
|
|||
vi.mocked(getDraftPicksWithSports).mockResolvedValue([]);
|
||||
vi.mocked(getTeamDraftPicksWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/participant");
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/season-participant");
|
||||
vi.mocked(getParticipantsForSeasonWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getSeasonSportsSimple } = await import("~/models/season-sport");
|
||||
|
|
@ -159,7 +159,7 @@ describe("draft.force-manual-pick action", () => {
|
|||
seasons: { findFirst: vi.fn() },
|
||||
commissioners: { findFirst: vi.fn() },
|
||||
draftPicks: { findFirst: vi.fn() },
|
||||
participants: { findFirst: vi.fn() },
|
||||
seasonParticipants: { findFirst: vi.fn() },
|
||||
draftSlots: { findMany: vi.fn() },
|
||||
draftTimers: { findFirst: vi.fn() },
|
||||
},
|
||||
|
|
@ -178,7 +178,7 @@ describe("draft.force-manual-pick action", () => {
|
|||
userId: COMMISSIONER_ID,
|
||||
});
|
||||
mockDb.query.draftPicks.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.participants.findFirst.mockResolvedValue(mockParticipant);
|
||||
mockDb.query.seasonParticipants.findFirst.mockResolvedValue(mockParticipant);
|
||||
mockDb.query.draftSlots.findMany.mockResolvedValue(mockDraftSlots);
|
||||
mockDb.query.draftTimers.findFirst.mockResolvedValue({
|
||||
id: "timer-1",
|
||||
|
|
@ -277,7 +277,7 @@ describe("draft.force-manual-pick action", () => {
|
|||
});
|
||||
|
||||
it("returns 404 when the participant does not exist", async () => {
|
||||
mockDb.query.participants.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.seasonParticipants.findFirst.mockResolvedValue(null);
|
||||
|
||||
const response = await action({ request: defaultPickRequest(), params: {}, context: ctx });
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ vi.mock("~/models/draft-pick", () => ({
|
|||
getDraftPicksWithSports: vi.fn(),
|
||||
getTeamDraftPicksWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
getParticipantsForSeasonWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/season-sport", () => ({
|
||||
|
|
@ -141,7 +141,7 @@ describe("draft.force-manual-pick action — timer mode behavior", () => {
|
|||
vi.mocked(getDraftPicksWithSports).mockResolvedValue([]);
|
||||
vi.mocked(getTeamDraftPicksWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/participant");
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/season-participant");
|
||||
vi.mocked(getParticipantsForSeasonWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getSeasonSportsSimple } = await import("~/models/season-sport");
|
||||
|
|
@ -163,7 +163,7 @@ describe("draft.force-manual-pick action — timer mode behavior", () => {
|
|||
findFirst: vi.fn().mockResolvedValue({ id: "c-1", userId: COMMISSIONER_ID }),
|
||||
},
|
||||
draftPicks: { findFirst: vi.fn().mockResolvedValue(null) },
|
||||
participants: { findFirst: vi.fn().mockResolvedValue(mockParticipant) },
|
||||
seasonParticipants: { findFirst: vi.fn().mockResolvedValue(mockParticipant) },
|
||||
draftSlots: { findMany: vi.fn().mockResolvedValue(mockDraftSlots) },
|
||||
draftTimers: {
|
||||
findFirst: vi.fn().mockResolvedValue({ id: "timer-1", seasonId: SEASON_ID, teamId: TEAM_ID, timeRemaining: 75 }),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ vi.mock("~/models/draft-pick", () => ({
|
|||
getDraftPicksWithSports: vi.fn(),
|
||||
getTeamDraftPicksWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/participant", () => ({
|
||||
vi.mock("~/models/season-participant", () => ({
|
||||
getParticipantsForSeasonWithSports: vi.fn(),
|
||||
}));
|
||||
vi.mock("~/models/season-sport", () => ({
|
||||
|
|
@ -138,7 +138,7 @@ describe("draft.make-pick action — timer mode behavior", () => {
|
|||
vi.mocked(getDraftPicksWithSports).mockResolvedValue([]);
|
||||
vi.mocked(getTeamDraftPicksWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/participant");
|
||||
const { getParticipantsForSeasonWithSports } = await import("~/models/season-participant");
|
||||
vi.mocked(getParticipantsForSeasonWithSports).mockResolvedValue([]);
|
||||
|
||||
const { getSeasonSportsSimple } = await import("~/models/season-sport");
|
||||
|
|
@ -158,7 +158,7 @@ describe("draft.make-pick action — timer mode behavior", () => {
|
|||
seasons: { findFirst: vi.fn() },
|
||||
commissioners: { findFirst: vi.fn().mockResolvedValue(null) },
|
||||
draftPicks: { findFirst: vi.fn().mockResolvedValue(null) },
|
||||
participants: { findFirst: vi.fn().mockResolvedValue(mockParticipant) },
|
||||
seasonParticipants: { findFirst: vi.fn().mockResolvedValue(mockParticipant) },
|
||||
draftSlots: { findMany: vi.fn().mockResolvedValue(mockDraftSlots) },
|
||||
draftTimers: { findFirst: vi.fn().mockResolvedValue({ id: "timer-1", timeRemaining: 75 }) },
|
||||
draftQueue: { findMany: vi.fn().mockResolvedValue([]) },
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { eq, and, sql } from "drizzle-orm";
|
|||
import { isUserAdmin } from "~/models/user";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
import { getDraftPicksWithSports, getTeamDraftPicksWithSports } from "~/models/draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/participant";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/season-participant";
|
||||
import { getSeasonSportsSimple } from "~/models/season-sport";
|
||||
import { calculatePickInfo, checkAndTriggerNextAutodraft } from "~/models/draft-utils";
|
||||
import { logCommissionerAction } from "~/models/audit-log";
|
||||
|
|
@ -87,8 +87,8 @@ export async function action(args: ActionFunctionArgs) {
|
|||
}
|
||||
|
||||
// Get participant details
|
||||
const participant = await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, participantId),
|
||||
const participant = await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, participantId),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { eq, and, sql } from "drizzle-orm";
|
|||
import { isUserAdmin } from "~/models/user";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
import { getDraftPicksWithSports, getTeamDraftPicksWithSports } from "~/models/draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/participant";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/season-participant";
|
||||
import { getSeasonSportsSimple } from "~/models/season-sport";
|
||||
import { calculatePickInfo, checkAndTriggerNextAutodraft, pruneIneligibleQueueItems } from "~/models/draft-utils";
|
||||
import { getSocketIO, scheduleDraftRoomClosure } from "../../../server/socket";
|
||||
|
|
@ -96,8 +96,8 @@ export async function action(args: ActionFunctionArgs) {
|
|||
}
|
||||
|
||||
// Get participant details
|
||||
const participant = await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, participantId),
|
||||
const participant = await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, participantId),
|
||||
with: {
|
||||
sportsSeason: {
|
||||
with: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { eq, and } from "drizzle-orm";
|
|||
import { isCommissioner } from "~/models/commissioner";
|
||||
import { calculateDraftEligibility } from "~/lib/draft-eligibility";
|
||||
import { getDraftPicksWithSports, getTeamDraftPicksWithSports } from "~/models/draft-pick";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/participant";
|
||||
import { getParticipantsForSeasonWithSports } from "~/models/season-participant";
|
||||
import { getSeasonSportsSimple } from "~/models/season-sport";
|
||||
import { logCommissionerAction } from "~/models/audit-log";
|
||||
import { getSocketIO } from "../../../server/socket";
|
||||
|
|
@ -78,8 +78,8 @@ export async function action(args: ActionFunctionArgs) {
|
|||
}
|
||||
}
|
||||
|
||||
const participant = await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, participantId),
|
||||
const participant = await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, participantId),
|
||||
with: {
|
||||
sportsSeason: { with: { sport: true } },
|
||||
},
|
||||
|
|
@ -128,8 +128,8 @@ export async function action(args: ActionFunctionArgs) {
|
|||
}
|
||||
|
||||
// Fetch old participant name for the audit log (before overwriting the pick)
|
||||
const oldParticipant = await db.query.participants.findFirst({
|
||||
where: eq(schema.participants.id, oldParticipantId),
|
||||
const oldParticipant = await db.query.seasonParticipants.findFirst({
|
||||
where: eq(schema.seasonParticipants.id, oldParticipantId),
|
||||
});
|
||||
|
||||
// Update the pick in-place
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ export async function loader({ params }: LoaderFunctionArgs) {
|
|||
round: schema.draftPicks.round,
|
||||
teamName: schema.teams.name,
|
||||
teamOwnerId: schema.teams.ownerId,
|
||||
participantName: schema.participants.name,
|
||||
participantName: schema.seasonParticipants.name,
|
||||
sport: schema.sports.name,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(schema.teams, eq(schema.draftPicks.teamId, schema.teams.id))
|
||||
.innerJoin(schema.participants, eq(schema.draftPicks.participantId, schema.participants.id))
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.innerJoin(schema.seasonParticipants, eq(schema.draftPicks.participantId, schema.seasonParticipants.id))
|
||||
.innerJoin(schema.sportsSeasons, eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id))
|
||||
.innerJoin(schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id))
|
||||
.where(eq(schema.draftPicks.seasonId, seasonId))
|
||||
.orderBy(schema.draftPicks.pickNumber);
|
||||
|
|
|
|||
|
|
@ -76,19 +76,19 @@ export async function loader(args: Route.LoaderArgs) {
|
|||
round: schema.draftPicks.round,
|
||||
pickInRound: schema.draftPicks.pickInRound,
|
||||
team: schema.teams,
|
||||
participant: schema.participants,
|
||||
participant: schema.seasonParticipants,
|
||||
sport: schema.sports,
|
||||
scoringPattern: schema.sportsSeasons.scoringPattern,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(schema.teams, eq(schema.draftPicks.teamId, schema.teams.id))
|
||||
.innerJoin(
|
||||
schema.participants,
|
||||
eq(schema.draftPicks.participantId, schema.participants.id)
|
||||
schema.seasonParticipants,
|
||||
eq(schema.draftPicks.participantId, schema.seasonParticipants.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sportsSeasons,
|
||||
eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
)
|
||||
.innerJoin(schema.sports, eq(schema.sportsSeasons.sportId, schema.sports.id))
|
||||
.where(eq(schema.draftPicks.seasonId, seasonId))
|
||||
|
|
@ -104,13 +104,13 @@ export async function loader(args: Route.LoaderArgs) {
|
|||
|
||||
const results = await db
|
||||
.select({
|
||||
participantId: schema.participantResults.participantId,
|
||||
sportsSeasonId: schema.participantResults.sportsSeasonId,
|
||||
finalPosition: schema.participantResults.finalPosition,
|
||||
isPartialScore: schema.participantResults.isPartialScore,
|
||||
participantId: schema.seasonParticipantResults.participantId,
|
||||
sportsSeasonId: schema.seasonParticipantResults.sportsSeasonId,
|
||||
finalPosition: schema.seasonParticipantResults.finalPosition,
|
||||
isPartialScore: schema.seasonParticipantResults.isPartialScore,
|
||||
})
|
||||
.from(schema.participantResults)
|
||||
.where(inArray(schema.participantResults.participantId, participantIds));
|
||||
.from(schema.seasonParticipantResults)
|
||||
.where(inArray(schema.seasonParticipantResults.participantId, participantIds));
|
||||
|
||||
const resultByParticipant = new Map(results.map((r) => [r.participantId, r]));
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { getTeamWatchlist } from "~/models/watchlist";
|
|||
import { findSeasonWithTeamsAndLeague } from "~/models/season";
|
||||
import { findDraftSlotsBySeasonId } from "~/models/draft-slot";
|
||||
import { getDraftPicksForSeason } from "~/models/draft-pick";
|
||||
import { getDraftParticipants } from "~/models/participant";
|
||||
import { getDraftParticipants } from "~/models/season-participant";
|
||||
import { getSeasonTimers } from "~/models/draft-timer";
|
||||
import { getSeasonAutodraftSettings } from "~/models/autodraft-settings";
|
||||
import { hasCommissionerRecord } from "~/models/commissioner";
|
||||
|
|
|
|||
|
|
@ -233,15 +233,15 @@ export async function loader(args: Route.LoaderArgs) {
|
|||
|
||||
// Fetch group-stage losers and all participant results for bracket scoring
|
||||
const [eliminatedResults, allResults] = await Promise.all([
|
||||
db.query.participantResults.findMany({
|
||||
db.query.seasonParticipantResults.findMany({
|
||||
where: and(
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.participantResults.finalPosition, 0)
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.seasonParticipantResults.finalPosition, 0)
|
||||
),
|
||||
with: { participant: true },
|
||||
}),
|
||||
db.query.participantResults.findMany({
|
||||
where: eq(schema.participantResults.sportsSeasonId, sportsSeasonId),
|
||||
db.query.seasonParticipantResults.findMany({
|
||||
where: eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId),
|
||||
}),
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -252,8 +252,8 @@ export async function previewProbabilityUpdate(
|
|||
const results = await findParticipantResultsBySportsSeasonId(sportsSeasonId);
|
||||
|
||||
// Get all existing EVs with participant names
|
||||
const existingEVs = await db.query.participantExpectedValues.findMany({
|
||||
where: eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId),
|
||||
const existingEVs = await db.query.seasonParticipantExpectedValues.findMany({
|
||||
where: eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId),
|
||||
with: {
|
||||
participant: true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ import { database } from "~/database/context";
|
|||
|
||||
const mockDb = {
|
||||
query: {
|
||||
participants: { findMany: vi.fn() },
|
||||
seasonParticipants: { findMany: vi.fn() },
|
||||
scoringEvents: { findFirst: vi.fn() },
|
||||
tournamentGroups: { findMany: vi.fn() },
|
||||
playoffMatches: { findMany: vi.fn() },
|
||||
|
|
@ -98,7 +98,7 @@ const mockDb = {
|
|||
|
||||
beforeEach(() => {
|
||||
vi.mocked(database).mockReturnValue(mockDb as never);
|
||||
mockDb.query.participants.findMany.mockReset();
|
||||
mockDb.query.seasonParticipants.findMany.mockReset();
|
||||
mockDb.query.scoringEvents.findFirst.mockReset();
|
||||
mockDb.query.tournamentGroups.findMany.mockReset();
|
||||
mockDb.query.playoffMatches.findMany.mockReset();
|
||||
|
|
@ -109,7 +109,7 @@ beforeEach(() => {
|
|||
|
||||
describe("WorldCupSimulator", () => {
|
||||
it("throws when no participants are found", async () => {
|
||||
mockDb.query.participants.findMany.mockResolvedValue([]);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue([]);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
@ -120,7 +120,7 @@ describe("WorldCupSimulator", () => {
|
|||
|
||||
it("returns one result per participant", async () => {
|
||||
const participants = makeParticipants(48);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
@ -136,7 +136,7 @@ describe("WorldCupSimulator", () => {
|
|||
|
||||
it("column sums for champion, runner-up, 3rd, 4th are each ≈1.0", async () => {
|
||||
const participants = makeParticipants(48);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
@ -157,7 +157,7 @@ describe("WorldCupSimulator", () => {
|
|||
|
||||
it("probabilities are all non-negative", async () => {
|
||||
const participants = makeParticipants(48);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
@ -178,7 +178,7 @@ describe("WorldCupSimulator", () => {
|
|||
it("SF losers land in 3rd or 4th, never 1st or 2nd", async () => {
|
||||
// Set up 8 participants (small bracket, 2 groups of 4)
|
||||
const participants = makeParticipants(8);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
@ -200,7 +200,7 @@ describe("WorldCupSimulator", () => {
|
|||
|
||||
it("a team with pre-completed group stage result is fixed in simulation", async () => {
|
||||
const participants = makeParticipants(48);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue({ id: "event-1" });
|
||||
|
||||
// One group fully complete: p0 wins everything, p3 loses everything
|
||||
|
|
@ -254,7 +254,7 @@ describe("WorldCupSimulator", () => {
|
|||
|
||||
it("probFifth through probEighth are equal for each participant (QF losers split evenly)", async () => {
|
||||
const participants = makeParticipants(48);
|
||||
mockDb.query.participants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue(participants);
|
||||
mockDb.query.scoringEvents.findFirst.mockResolvedValue(null);
|
||||
mockDb.query.tournamentGroups.findMany.mockResolvedValue([]);
|
||||
mockDb.query.playoffMatches.findMany.mockResolvedValue([]);
|
||||
|
|
|
|||
|
|
@ -198,16 +198,16 @@ export class AFLSimulator implements Simulator {
|
|||
// 1. Load participants, DB Elo, and standings in parallel.
|
||||
const [participantRows, evRows, standings] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
getRegularSeasonStandings(sportsSeasonId),
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ export class AutoRacingSimulator implements Simulator {
|
|||
const db = database();
|
||||
|
||||
// 1. Load all participants for this sports season
|
||||
const participants = await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
const participants = await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
});
|
||||
|
||||
if (participants.length === 0) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
|
||||
import { database } from "~/database/context";
|
||||
import { participantExpectedValues } from "~/database/schema";
|
||||
import { seasonParticipantExpectedValues } from "~/database/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { simulateBracket } from "~/services/bracket-simulator";
|
||||
import { convertFuturesToElo } from "~/services/probability-engine";
|
||||
|
|
@ -24,12 +24,12 @@ export class BracketSimulator implements Simulator {
|
|||
// Load all participants with their current EVs (which hold probability distributions)
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: participantExpectedValues.participantId,
|
||||
probFirst: participantExpectedValues.probFirst,
|
||||
sourceOdds: participantExpectedValues.sourceOdds,
|
||||
participantId: seasonParticipantExpectedValues.participantId,
|
||||
probFirst: seasonParticipantExpectedValues.probFirst,
|
||||
sourceOdds: seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(participantExpectedValues)
|
||||
.where(eq(participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(seasonParticipantExpectedValues)
|
||||
.where(eq(seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (evRows.length === 0) {
|
||||
throw new Error(
|
||||
|
|
|
|||
|
|
@ -433,9 +433,9 @@ export class CSMajorSimulator implements Simulator {
|
|||
|
||||
// 1. Load all participants for this sports season.
|
||||
const allParticipants = await db
|
||||
.select({ id: schema.participants.id })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const participantIds = allParticipants.map((p) => p.id);
|
||||
|
||||
|
|
@ -446,12 +446,12 @@ export class CSMajorSimulator implements Simulator {
|
|||
// 2. Load Elo ratings and world rankings from participantExpectedValues.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
worldRanking: schema.participantExpectedValues.worldRanking,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
worldRanking: schema.seasonParticipantExpectedValues.worldRanking,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const eloMap = new Map<string, { elo: number; rank: number }>();
|
||||
for (const row of evRows) {
|
||||
|
|
@ -508,7 +508,7 @@ export class CSMajorSimulator implements Simulator {
|
|||
if (completedEventIds.length > 0) {
|
||||
const actualResults = await db
|
||||
.select({
|
||||
participantId: schema.eventResults.participantId,
|
||||
participantId: schema.eventResults.seasonParticipantId,
|
||||
qualifyingPointsAwarded: schema.eventResults.qualifyingPointsAwarded,
|
||||
})
|
||||
.from(schema.eventResults)
|
||||
|
|
|
|||
|
|
@ -220,12 +220,12 @@ export class DartsSimulator implements Simulator {
|
|||
// 3. Load Elo ratings and world rankings.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
worldRanking: schema.participantExpectedValues.worldRanking,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
worldRanking: schema.seasonParticipantExpectedValues.worldRanking,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const eloMap = new Map<string, number>();
|
||||
const rankingMap = new Map<string, number>();
|
||||
|
|
@ -452,9 +452,9 @@ export class DartsSimulator implements Simulator {
|
|||
db: ReturnType<typeof database>
|
||||
): Promise<SimulationResult[]> {
|
||||
const allParticipants = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (allParticipants.length < 2) {
|
||||
throw new Error(
|
||||
|
|
|
|||
|
|
@ -185,9 +185,9 @@ export class GolfSimulator implements Simulator {
|
|||
// Load participants, skills, QP config, and scoring events in parallel.
|
||||
const [allParticipants, skillsMap, qpConfigRows, events] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
getGolfSkillsMap(sportsSeasonId),
|
||||
getQPConfig(sportsSeasonId),
|
||||
db.query.scoringEvents.findMany({
|
||||
|
|
@ -226,7 +226,7 @@ export class GolfSimulator implements Simulator {
|
|||
if (completedEventIds.length > 0) {
|
||||
const actualResults = await db
|
||||
.select({
|
||||
participantId: schema.eventResults.participantId,
|
||||
participantId: schema.eventResults.seasonParticipantId,
|
||||
qualifyingPointsAwarded: schema.eventResults.qualifyingPointsAwarded,
|
||||
})
|
||||
.from(schema.eventResults)
|
||||
|
|
|
|||
|
|
@ -264,9 +264,9 @@ export class LLWSSimulator implements Simulator {
|
|||
|
||||
// 1. Load all participants.
|
||||
const participants = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name, externalId: schema.participants.externalId })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name, externalId: schema.seasonParticipants.externalId })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (participants.length !== US_TEAM_COUNT + INTL_TEAM_COUNT) {
|
||||
throw new Error(
|
||||
|
|
@ -278,11 +278,11 @@ export class LLWSSimulator implements Simulator {
|
|||
// 2. Load championship futures odds.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const rawOddsMap = new Map<string, number>();
|
||||
for (const row of evRows) {
|
||||
|
|
|
|||
|
|
@ -409,9 +409,9 @@ export class MLBSimulator implements Simulator {
|
|||
|
||||
// 1. Load all participants for this sports season.
|
||||
const participantRows = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (participantRows.length === 0) {
|
||||
throw new Error(
|
||||
|
|
@ -452,12 +452,12 @@ export class MLBSimulator implements Simulator {
|
|||
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const participantIdSet = new Set(participantIds);
|
||||
const oddsRows = evRows.filter(
|
||||
|
|
|
|||
|
|
@ -312,16 +312,16 @@ export class NBASimulator implements Simulator {
|
|||
// Load participant names and sourceElo values in parallel.
|
||||
const [participantRows, evRows] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
]);
|
||||
|
||||
const nameById = new Map(participantRows.map((r) => [r.id, r.name]));
|
||||
|
|
@ -472,17 +472,17 @@ export class NBASimulator implements Simulator {
|
|||
|
||||
const [participantRows, standings, evRows] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
getRegularSeasonStandings(sportsSeasonId),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
]);
|
||||
|
||||
if (participantRows.length === 0) {
|
||||
|
|
|
|||
|
|
@ -214,9 +214,9 @@ export class NCAAFootballSimulator implements Simulator {
|
|||
|
||||
// 1. Load all participants for this sports season.
|
||||
const participants = await db
|
||||
.select({ id: schema.participants.id })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (participants.length < BRACKET_SIZE) {
|
||||
throw new Error(
|
||||
|
|
@ -228,12 +228,12 @@ export class NCAAFootballSimulator implements Simulator {
|
|||
// 2. Load Elo/FPI ratings and optional futures odds in a single query.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
// Build Elo and raw odds maps in a single pass.
|
||||
const eloFromDb = new Map<string, number>();
|
||||
|
|
|
|||
|
|
@ -494,9 +494,9 @@ export class NCAAMSimulator implements Simulator {
|
|||
|
||||
// 6. Load participant names from DB; build net rating lookup by ID.
|
||||
const participantRows = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(inArray(schema.participants.id, participantIds));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(inArray(schema.seasonParticipants.id, participantIds));
|
||||
|
||||
if (participantRows.length < participantIds.length) {
|
||||
const foundIds = new Set(participantRows.map((r) => r.id));
|
||||
|
|
|
|||
|
|
@ -457,9 +457,9 @@ export class NCAAWSimulator implements Simulator {
|
|||
|
||||
// 6. Load participant names from DB; build Barthag lookup by ID.
|
||||
const participantRows = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(inArray(schema.participants.id, participantIds));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(inArray(schema.seasonParticipants.id, participantIds));
|
||||
|
||||
if (participantRows.length < participantIds.length) {
|
||||
const foundIds = new Set(participantRows.map((r) => r.id));
|
||||
|
|
|
|||
|
|
@ -296,8 +296,8 @@ export class NFLSimulator implements Simulator {
|
|||
const db = database();
|
||||
|
||||
// Load participants
|
||||
const participants = await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
const participants = await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
});
|
||||
|
||||
if (participants.length === 0) {
|
||||
|
|
@ -307,12 +307,12 @@ export class NFLSimulator implements Simulator {
|
|||
// Load EV rows (sourceElo + sourceOdds)
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
// Build Elo map: prefer sourceElo, fall back to converting sourceOdds
|
||||
const eloMap = new Map<string, number>();
|
||||
|
|
|
|||
|
|
@ -278,18 +278,18 @@ export class NHLSimulator implements Simulator {
|
|||
// 1. Load participants, standings, and sourceElo values in parallel.
|
||||
const [participantRows, standings, evRows] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
getRegularSeasonStandings(sportsSeasonId),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
]);
|
||||
|
||||
if (participantRows.length === 0) {
|
||||
|
|
@ -620,17 +620,17 @@ export class NHLSimulator implements Simulator {
|
|||
// Load all participants and EV data in parallel.
|
||||
const [participantRows, evRows] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
]);
|
||||
|
||||
const allParticipantIds = participantRows.map((r) => r.id);
|
||||
|
|
|
|||
|
|
@ -251,11 +251,11 @@ export class SnookerSimulator implements Simulator {
|
|||
// 3. Load Elo ratings from participantExpectedValues.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
// Build Elo map; fall back to 1500 for any participant with no stored rating.
|
||||
const eloMap = new Map<string, number>();
|
||||
|
|
@ -453,9 +453,9 @@ export class SnookerSimulator implements Simulator {
|
|||
db: ReturnType<typeof database>
|
||||
): Promise<SimulationResult[]> {
|
||||
const allParticipants = await db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (allParticipants.length < 17) {
|
||||
throw new Error(
|
||||
|
|
|
|||
|
|
@ -262,9 +262,9 @@ export class TennisSimulator implements Simulator {
|
|||
|
||||
// 1. Load all participants for this sports season.
|
||||
const allParticipants = await db
|
||||
.select({ id: schema.participants.id })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId));
|
||||
.select({ id: schema.seasonParticipants.id })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
if (allParticipants.length < 128) {
|
||||
throw new Error(
|
||||
|
|
@ -306,7 +306,7 @@ export class TennisSimulator implements Simulator {
|
|||
if (completedEventIds.length > 0) {
|
||||
const actualResults = await db
|
||||
.select({
|
||||
participantId: schema.eventResults.participantId,
|
||||
participantId: schema.eventResults.seasonParticipantId,
|
||||
qualifyingPointsAwarded: schema.eventResults.qualifyingPointsAwarded,
|
||||
})
|
||||
.from(schema.eventResults)
|
||||
|
|
|
|||
|
|
@ -147,11 +147,11 @@ export class UCLSimulator implements Simulator {
|
|||
// 5. Load futures odds from participantExpectedValues.
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const evMap = new Map(evRows.map((r) => [r.participantId, r]));
|
||||
|
||||
|
|
|
|||
|
|
@ -159,18 +159,18 @@ export class WNBASimulator implements Simulator {
|
|||
// 1. Load participants, standings, and futures odds in parallel.
|
||||
const [participantRows, standings, evRows] = await Promise.all([
|
||||
db
|
||||
.select({ id: schema.participants.id, name: schema.participants.name })
|
||||
.from(schema.participants)
|
||||
.where(eq(schema.participants.sportsSeasonId, sportsSeasonId)),
|
||||
.select({ id: schema.seasonParticipants.id, name: schema.seasonParticipants.name })
|
||||
.from(schema.seasonParticipants)
|
||||
.where(eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId)),
|
||||
getRegularSeasonStandings(sportsSeasonId),
|
||||
db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)),
|
||||
]);
|
||||
|
||||
if (participantRows.length === 0) {
|
||||
|
|
|
|||
|
|
@ -313,8 +313,8 @@ export class WorldCupSimulator implements Simulator {
|
|||
const db = database();
|
||||
|
||||
// 1. Load all participants for this season
|
||||
const participantRows = await db.query.participants.findMany({
|
||||
where: eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
const participantRows = await db.query.seasonParticipants.findMany({
|
||||
where: eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
});
|
||||
|
||||
if (participantRows.length === 0) {
|
||||
|
|
@ -327,12 +327,12 @@ export class WorldCupSimulator implements Simulator {
|
|||
// 2. Load stored ratings (sourceElo from Elo page, sourceOdds from futures page)
|
||||
const evRows = await db
|
||||
.select({
|
||||
participantId: schema.participantExpectedValues.participantId,
|
||||
sourceOdds: schema.participantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.participantExpectedValues.sourceElo,
|
||||
participantId: schema.seasonParticipantExpectedValues.participantId,
|
||||
sourceOdds: schema.seasonParticipantExpectedValues.sourceOdds,
|
||||
sourceElo: schema.seasonParticipantExpectedValues.sourceElo,
|
||||
})
|
||||
.from(schema.participantExpectedValues)
|
||||
.where(eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
.from(schema.seasonParticipantExpectedValues)
|
||||
.where(eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId));
|
||||
|
||||
const evMap = new Map(evRows.map((r) => [r.participantId, r]));
|
||||
const participantSet = new Set(participantIds);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { database } from "~/database/context";
|
||||
import { eq } from "drizzle-orm";
|
||||
import * as schema from "~/database/schema";
|
||||
import { findParticipantsBySportsSeasonId, updateParticipant } from "~/models/participant";
|
||||
import { findParticipantsBySportsSeasonId, updateParticipant } from "~/models/season-participant";
|
||||
import { upsertRegularSeasonStandings } from "~/models/regular-season-standings";
|
||||
import { upsertPendingStandingsMappings } from "~/models/pending-standings-mappings";
|
||||
import { findMatchingTeamName } from "~/lib/normalize-team-name";
|
||||
|
|
|
|||
|
|
@ -115,16 +115,16 @@ export async function exportSportsDataToJSON(): Promise<ExportData> {
|
|||
with: { sport: true },
|
||||
orderBy: (s, { desc, asc }) => [desc(s.year), asc(s.name)],
|
||||
}),
|
||||
db.query.participants.findMany({
|
||||
db.query.seasonParticipants.findMany({
|
||||
with: { sportsSeason: { with: { sport: true } } },
|
||||
orderBy: (p, { asc }) => [asc(p.name)],
|
||||
}),
|
||||
db.query.participantExpectedValues.findMany({
|
||||
db.query.seasonParticipantExpectedValues.findMany({
|
||||
with: {
|
||||
participant: { with: { sportsSeason: { with: { sport: true } } } },
|
||||
},
|
||||
}),
|
||||
db.query.participantResults.findMany({
|
||||
db.query.seasonParticipantResults.findMany({
|
||||
with: {
|
||||
participant: { with: { sportsSeason: { with: { sport: true } } } },
|
||||
},
|
||||
|
|
@ -238,7 +238,7 @@ export async function importSportsDataFromJSON(
|
|||
// automatically removed when participants is deleted.
|
||||
await tx.delete(schema.seasonTemplateSports);
|
||||
await tx.delete(schema.seasonTemplates);
|
||||
await tx.delete(schema.participants); // cascades to EVs + results
|
||||
await tx.delete(schema.seasonParticipants); // cascades to EVs + results
|
||||
await tx.delete(schema.seasonSports);
|
||||
await tx.delete(schema.sportsSeasons);
|
||||
await tx.delete(schema.sports);
|
||||
|
|
@ -358,28 +358,28 @@ export async function importSportsDataFromJSON(
|
|||
continue;
|
||||
}
|
||||
|
||||
const existing = await tx.query.participants.findFirst({
|
||||
const existing = await tx.query.seasonParticipants.findFirst({
|
||||
where: and(
|
||||
eq(schema.participants.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.participants.name, participant.name)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, sportsSeasonId),
|
||||
eq(schema.seasonParticipants.name, participant.name)
|
||||
),
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
// Update all mutable fields (fixes: merge mode was silently skipping)
|
||||
await tx
|
||||
.update(schema.participants)
|
||||
.update(schema.seasonParticipants)
|
||||
.set({
|
||||
shortName: participant.shortName,
|
||||
externalId: participant.externalId,
|
||||
expectedValue: String(participant.expectedValue ?? 0),
|
||||
})
|
||||
.where(eq(schema.participants.id, existing.id));
|
||||
.where(eq(schema.seasonParticipants.id, existing.id));
|
||||
participantIdMap.set(`${sportsSeasonId}:${participant.name}`, existing.id);
|
||||
updated++;
|
||||
} else {
|
||||
const [created_] = await tx
|
||||
.insert(schema.participants)
|
||||
.insert(schema.seasonParticipants)
|
||||
.values({
|
||||
sportsSeasonId,
|
||||
name: participant.name,
|
||||
|
|
@ -413,10 +413,10 @@ export async function importSportsDataFromJSON(
|
|||
continue;
|
||||
}
|
||||
|
||||
const existingEV = await tx.query.participantExpectedValues.findFirst({
|
||||
const existingEV = await tx.query.seasonParticipantExpectedValues.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantExpectedValues.participantId, participantId),
|
||||
eq(schema.participantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantExpectedValues.participantId, participantId),
|
||||
eq(schema.seasonParticipantExpectedValues.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -446,25 +446,25 @@ export async function importSportsDataFromJSON(
|
|||
if (existingEV) {
|
||||
if (mode === "merge") {
|
||||
await tx
|
||||
.update(schema.participantExpectedValues)
|
||||
.update(schema.seasonParticipantExpectedValues)
|
||||
.set({ ...evValues, updatedAt: new Date() })
|
||||
.where(eq(schema.participantExpectedValues.id, existingEV.id));
|
||||
.where(eq(schema.seasonParticipantExpectedValues.id, existingEV.id));
|
||||
await tx
|
||||
.update(schema.participants)
|
||||
.update(schema.seasonParticipants)
|
||||
.set({ expectedValue: ev.expectedValue })
|
||||
.where(eq(schema.participants.id, participantId));
|
||||
.where(eq(schema.seasonParticipants.id, participantId));
|
||||
updated++;
|
||||
}
|
||||
} else {
|
||||
await tx.insert(schema.participantExpectedValues).values({
|
||||
await tx.insert(schema.seasonParticipantExpectedValues).values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
...evValues,
|
||||
});
|
||||
await tx
|
||||
.update(schema.participants)
|
||||
.update(schema.seasonParticipants)
|
||||
.set({ expectedValue: ev.expectedValue })
|
||||
.where(eq(schema.participants.id, participantId));
|
||||
.where(eq(schema.seasonParticipants.id, participantId));
|
||||
created++;
|
||||
}
|
||||
}
|
||||
|
|
@ -489,10 +489,10 @@ export async function importSportsDataFromJSON(
|
|||
continue;
|
||||
}
|
||||
|
||||
const existingResult = await tx.query.participantResults.findFirst({
|
||||
const existingResult = await tx.query.seasonParticipantResults.findFirst({
|
||||
where: and(
|
||||
eq(schema.participantResults.participantId, participantId),
|
||||
eq(schema.participantResults.sportsSeasonId, sportsSeasonId)
|
||||
eq(schema.seasonParticipantResults.participantId, participantId),
|
||||
eq(schema.seasonParticipantResults.sportsSeasonId, sportsSeasonId)
|
||||
),
|
||||
});
|
||||
|
||||
|
|
@ -505,13 +505,13 @@ export async function importSportsDataFromJSON(
|
|||
if (existingResult) {
|
||||
if (mode === "merge") {
|
||||
await tx
|
||||
.update(schema.participantResults)
|
||||
.update(schema.seasonParticipantResults)
|
||||
.set({ ...resultValues, updatedAt: new Date() })
|
||||
.where(eq(schema.participantResults.id, existingResult.id));
|
||||
.where(eq(schema.seasonParticipantResults.id, existingResult.id));
|
||||
updated++;
|
||||
}
|
||||
} else {
|
||||
await tx.insert(schema.participantResults).values({
|
||||
await tx.insert(schema.seasonParticipantResults).values({
|
||||
participantId,
|
||||
sportsSeasonId,
|
||||
...resultValues,
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ export const draftPicks = pgTable("draft_picks", {
|
|||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
pickNumber: integer("pick_number").notNull(),
|
||||
round: integer("round").notNull(),
|
||||
pickInRound: integer("pick_in_round").notNull(),
|
||||
|
|
@ -272,7 +272,7 @@ export const draftQueue = pgTable("draft_queue", {
|
|||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
queuePosition: integer("queue_position").notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
|
|
@ -288,7 +288,7 @@ export const watchlist = pgTable("watchlist", {
|
|||
.references(() => teams.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
}, (t) => ({
|
||||
uniqueWatch: uniqueIndex("watchlist_season_team_participant_unique").on(t.seasonId, t.teamId, t.participantId),
|
||||
|
|
@ -373,7 +373,7 @@ export const sportsSeasons = pgTable("sports_seasons", {
|
|||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const participants = pgTable("participants", {
|
||||
export const seasonParticipants = pgTable("season_participants", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
|
|
@ -411,11 +411,11 @@ export const seasonSports = pgTable("season_sports", {
|
|||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export const participantResults = pgTable("participant_results", {
|
||||
export const seasonParticipantResults = pgTable("season_participant_results", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -460,9 +460,9 @@ export const eventResults = pgTable("event_results", {
|
|||
scoringEventId: uuid("scoring_event_id")
|
||||
.notNull()
|
||||
.references(() => scoringEvents.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
seasonParticipantId: uuid("season_participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
// Placement in this specific event
|
||||
placement: integer("placement"),
|
||||
// For qualifying events: QP awarded in this event
|
||||
|
|
@ -483,10 +483,10 @@ export const playoffMatches = pgTable("playoff_matches", {
|
|||
.references(() => scoringEvents.id, { onDelete: "cascade" }),
|
||||
round: varchar("round", { length: 50 }).notNull(), // "Quarterfinals", "Semifinals", "Finals"
|
||||
matchNumber: integer("match_number").notNull(), // 1, 2, 3, 4 (for QF); 1, 2 (for SF); 1 (for F)
|
||||
participant1Id: uuid("participant1_id").references(() => participants.id, { onDelete: "set null" }),
|
||||
participant2Id: uuid("participant2_id").references(() => participants.id, { onDelete: "set null" }),
|
||||
winnerId: uuid("winner_id").references(() => participants.id, { onDelete: "set null" }),
|
||||
loserId: uuid("loser_id").references(() => participants.id, { onDelete: "set null" }),
|
||||
participant1Id: uuid("participant1_id").references(() => seasonParticipants.id, { onDelete: "set null" }),
|
||||
participant2Id: uuid("participant2_id").references(() => seasonParticipants.id, { onDelete: "set null" }),
|
||||
winnerId: uuid("winner_id").references(() => seasonParticipants.id, { onDelete: "set null" }),
|
||||
loserId: uuid("loser_id").references(() => seasonParticipants.id, { onDelete: "set null" }),
|
||||
isComplete: boolean("is_complete").notNull().default(false),
|
||||
// Optional detailed data
|
||||
participant1Score: decimal("participant1_score", { precision: 10, scale: 2 }),
|
||||
|
|
@ -510,7 +510,7 @@ export const playoffMatchGames = pgTable("playoff_match_games", {
|
|||
status: playoffMatchGameStatusEnum("status").notNull().default("scheduled"),
|
||||
participant1Score: decimal("participant1_score", { precision: 10, scale: 2 }),
|
||||
participant2Score: decimal("participant2_score", { precision: 10, scale: 2 }),
|
||||
winnerId: uuid("winner_id").references(() => participants.id, { onDelete: "set null" }),
|
||||
winnerId: uuid("winner_id").references(() => seasonParticipants.id, { onDelete: "set null" }),
|
||||
notes: text("notes"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
|
|
@ -524,7 +524,7 @@ export const playoffMatchOdds = pgTable("playoff_match_odds", {
|
|||
.references(() => playoffMatches.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
moneylineOdds: integer("moneyline_odds"), // American format e.g. -110, +150
|
||||
impliedProbability: decimal("implied_probability", { precision: 6, scale: 4 }),
|
||||
oddsSource: varchar("odds_source", { length: 100 }),
|
||||
|
|
@ -534,11 +534,11 @@ export const playoffMatchOdds = pgTable("playoff_match_odds", {
|
|||
});
|
||||
|
||||
// Aggregated participant qualifying points (for qualifying_points sports)
|
||||
export const participantQualifyingTotals = pgTable("participant_qualifying_totals", {
|
||||
export const seasonParticipantQualifyingTotals = pgTable("season_participant_qualifying_totals", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -639,11 +639,11 @@ export const teamStandingsSnapshots = pgTable("team_standings_snapshots", {
|
|||
}));
|
||||
|
||||
// Expected value tracking (sports-season-specific)
|
||||
export const participantExpectedValues = pgTable("participant_expected_values", {
|
||||
export const seasonParticipantExpectedValues = pgTable("season_participant_expected_values", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -688,7 +688,7 @@ export const tournamentGroupMembers = pgTable("tournament_group_members", {
|
|||
.references(() => tournamentGroups.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
eliminated: boolean("eliminated").notNull().default(false),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
||||
|
|
@ -701,10 +701,10 @@ export const groupStageMatches = pgTable("group_stage_matches", {
|
|||
.references(() => tournamentGroups.id, { onDelete: "cascade" }),
|
||||
participant1Id: uuid("participant1_id")
|
||||
.notNull()
|
||||
.references(() => participants.id),
|
||||
.references(() => seasonParticipants.id),
|
||||
participant2Id: uuid("participant2_id")
|
||||
.notNull()
|
||||
.references(() => participants.id),
|
||||
.references(() => seasonParticipants.id),
|
||||
participant1Score: integer("participant1_score"),
|
||||
participant2Score: integer("participant2_score"),
|
||||
isComplete: boolean("is_complete").notNull().default(false),
|
||||
|
|
@ -723,7 +723,7 @@ export const participantSeasonResults = pgTable("participant_season_results", {
|
|||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -737,7 +737,7 @@ export const participantEvSnapshots = pgTable("participant_ev_snapshots", {
|
|||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -790,20 +790,20 @@ export const sportsSeasonsRelations = relations(sportsSeasons, ({ one, many }) =
|
|||
fields: [sportsSeasons.sportId],
|
||||
references: [sports.id],
|
||||
}),
|
||||
participants: many(participants),
|
||||
participants: many(seasonParticipants),
|
||||
seasonTemplateSports: many(seasonTemplateSports),
|
||||
seasonSports: many(seasonSports),
|
||||
participantResults: many(participantResults),
|
||||
participantResults: many(seasonParticipantResults),
|
||||
regularSeasonStandings: many(regularSeasonStandings),
|
||||
pendingStandingsMappings: many(pendingStandingsMappings),
|
||||
}));
|
||||
|
||||
export const participantsRelations = relations(participants, ({ one, many }) => ({
|
||||
export const seasonParticipantsRelations = relations(seasonParticipants, ({ one, many }) => ({
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participants.sportsSeasonId],
|
||||
fields: [seasonParticipants.sportsSeasonId],
|
||||
references: [sportsSeasons.id],
|
||||
}),
|
||||
results: many(participantResults),
|
||||
results: many(seasonParticipantResults),
|
||||
regularSeasonStandings: many(regularSeasonStandings),
|
||||
}));
|
||||
|
||||
|
|
@ -847,13 +847,13 @@ export const seasonSportsRelations = relations(seasonSports, ({ one }) => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
export const participantResultsRelations = relations(participantResults, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
fields: [participantResults.participantId],
|
||||
references: [participants.id],
|
||||
export const seasonParticipantResultsRelations = relations(seasonParticipantResults, ({ one }) => ({
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [seasonParticipantResults.participantId],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantResults.sportsSeasonId],
|
||||
fields: [seasonParticipantResults.sportsSeasonId],
|
||||
references: [sportsSeasons.id],
|
||||
}),
|
||||
}));
|
||||
|
|
@ -889,9 +889,9 @@ export const draftPicksRelations = relations(draftPicks, ({ one }) => ({
|
|||
fields: [draftPicks.teamId],
|
||||
references: [teams.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [draftPicks.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -904,9 +904,9 @@ export const draftQueueRelations = relations(draftQueue, ({ one }) => ({
|
|||
fields: [draftQueue.teamId],
|
||||
references: [teams.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [draftQueue.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -919,9 +919,9 @@ export const watchlistRelations = relations(watchlist, ({ one }) => ({
|
|||
fields: [watchlist.teamId],
|
||||
references: [teams.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [watchlist.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -954,9 +954,9 @@ export const eventResultsRelations = relations(eventResults, ({ one }) => ({
|
|||
fields: [eventResults.scoringEventId],
|
||||
references: [scoringEvents.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
fields: [eventResults.participantId],
|
||||
references: [participants.id],
|
||||
seasonParticipant: one(seasonParticipants, {
|
||||
fields: [eventResults.seasonParticipantId],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -965,21 +965,21 @@ export const playoffMatchesRelations = relations(playoffMatches, ({ one, many })
|
|||
fields: [playoffMatches.scoringEventId],
|
||||
references: [scoringEvents.id],
|
||||
}),
|
||||
participant1: one(participants, {
|
||||
participant1: one(seasonParticipants, {
|
||||
fields: [playoffMatches.participant1Id],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
participant2: one(participants, {
|
||||
participant2: one(seasonParticipants, {
|
||||
fields: [playoffMatches.participant2Id],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
winner: one(participants, {
|
||||
winner: one(seasonParticipants, {
|
||||
fields: [playoffMatches.winnerId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
loser: one(participants, {
|
||||
loser: one(seasonParticipants, {
|
||||
fields: [playoffMatches.loserId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
games: many(playoffMatchGames),
|
||||
odds: many(playoffMatchOdds),
|
||||
|
|
@ -990,9 +990,9 @@ export const playoffMatchGamesRelations = relations(playoffMatchGames, ({ one })
|
|||
fields: [playoffMatchGames.playoffMatchId],
|
||||
references: [playoffMatches.id],
|
||||
}),
|
||||
winner: one(participants, {
|
||||
winner: one(seasonParticipants, {
|
||||
fields: [playoffMatchGames.winnerId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -1001,19 +1001,19 @@ export const playoffMatchOddsRelations = relations(playoffMatchOdds, ({ one }) =
|
|||
fields: [playoffMatchOdds.playoffMatchId],
|
||||
references: [playoffMatches.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [playoffMatchOdds.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const participantQualifyingTotalsRelations = relations(participantQualifyingTotals, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
fields: [participantQualifyingTotals.participantId],
|
||||
references: [participants.id],
|
||||
export const seasonParticipantQualifyingTotalsRelations = relations(seasonParticipantQualifyingTotals, ({ one }) => ({
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [seasonParticipantQualifyingTotals.participantId],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantQualifyingTotals.sportsSeasonId],
|
||||
fields: [seasonParticipantQualifyingTotals.sportsSeasonId],
|
||||
references: [sportsSeasons.id],
|
||||
}),
|
||||
}));
|
||||
|
|
@ -1058,21 +1058,21 @@ export const teamStandingsSnapshotsRelations = relations(teamStandingsSnapshots,
|
|||
}),
|
||||
}));
|
||||
|
||||
export const participantExpectedValuesRelations = relations(participantExpectedValues, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
fields: [participantExpectedValues.participantId],
|
||||
references: [participants.id],
|
||||
export const seasonParticipantExpectedValuesRelations = relations(seasonParticipantExpectedValues, ({ one }) => ({
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [seasonParticipantExpectedValues.participantId],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantExpectedValues.sportsSeasonId],
|
||||
fields: [seasonParticipantExpectedValues.sportsSeasonId],
|
||||
references: [sportsSeasons.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
export const participantSeasonResultsRelations = relations(participantSeasonResults, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [participantSeasonResults.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantSeasonResults.sportsSeasonId],
|
||||
|
|
@ -1095,9 +1095,9 @@ export const tournamentGroupMembersRelations = relations(tournamentGroupMembers,
|
|||
fields: [tournamentGroupMembers.tournamentGroupId],
|
||||
references: [tournamentGroups.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [tournamentGroupMembers.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
@ -1106,22 +1106,22 @@ export const groupStageMatchesRelations = relations(groupStageMatches, ({ one })
|
|||
fields: [groupStageMatches.tournamentGroupId],
|
||||
references: [tournamentGroups.id],
|
||||
}),
|
||||
participant1: one(participants, {
|
||||
participant1: one(seasonParticipants, {
|
||||
fields: [groupStageMatches.participant1Id],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
relationName: "groupMatchParticipant1",
|
||||
}),
|
||||
participant2: one(participants, {
|
||||
participant2: one(seasonParticipants, {
|
||||
fields: [groupStageMatches.participant2Id],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
relationName: "groupMatchParticipant2",
|
||||
}),
|
||||
}));
|
||||
|
||||
export const participantEvSnapshotsRelations = relations(participantEvSnapshots, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [participantEvSnapshots.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantEvSnapshots.sportsSeasonId],
|
||||
|
|
@ -1146,7 +1146,7 @@ export const regularSeasonStandings = pgTable("regular_season_standings", {
|
|||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -1177,9 +1177,9 @@ export const regularSeasonStandings = pgTable("regular_season_standings", {
|
|||
}));
|
||||
|
||||
export const regularSeasonStandingsRelations = relations(regularSeasonStandings, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [regularSeasonStandings.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [regularSeasonStandings.sportsSeasonId],
|
||||
|
|
@ -1216,11 +1216,11 @@ export const pendingStandingsMappingsRelations = relations(pendingStandingsMappi
|
|||
// Stores surface-specific Elo ratings for tennis (and future surface-based sports).
|
||||
// One row per (participantId, sportsSeasonId); nullable per surface.
|
||||
|
||||
export const participantSurfaceElos = pgTable("participant_surface_elos", {
|
||||
export const seasonParticipantSurfaceElos = pgTable("season_participant_surface_elos", {
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -1234,13 +1234,13 @@ export const participantSurfaceElos = pgTable("participant_surface_elos", {
|
|||
.on(t.participantId, t.sportsSeasonId),
|
||||
}));
|
||||
|
||||
export const participantSurfaceElosRelations = relations(participantSurfaceElos, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
fields: [participantSurfaceElos.participantId],
|
||||
references: [participants.id],
|
||||
export const seasonParticipantSurfaceElosRelations = relations(seasonParticipantSurfaceElos, ({ one }) => ({
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [seasonParticipantSurfaceElos.participantId],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantSurfaceElos.sportsSeasonId],
|
||||
fields: [seasonParticipantSurfaceElos.sportsSeasonId],
|
||||
references: [sportsSeasons.id],
|
||||
}),
|
||||
}));
|
||||
|
|
@ -1255,7 +1255,7 @@ export const participantGolfSkills = pgTable("participant_golf_skills", {
|
|||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
sportsSeasonId: uuid("sports_season_id")
|
||||
.notNull()
|
||||
.references(() => sportsSeasons.id, { onDelete: "cascade" }),
|
||||
|
|
@ -1275,9 +1275,9 @@ export const participantGolfSkills = pgTable("participant_golf_skills", {
|
|||
}));
|
||||
|
||||
export const participantGolfSkillsRelations = relations(participantGolfSkills, ({ one }) => ({
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [participantGolfSkills.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
sportsSeason: one(sportsSeasons, {
|
||||
fields: [participantGolfSkills.sportsSeasonId],
|
||||
|
|
@ -1302,7 +1302,7 @@ export const cs2MajorStageResults = pgTable("cs2_major_stage_results", {
|
|||
.references(() => scoringEvents.id, { onDelete: "cascade" }),
|
||||
participantId: uuid("participant_id")
|
||||
.notNull()
|
||||
.references(() => participants.id, { onDelete: "cascade" }),
|
||||
.references(() => seasonParticipants.id, { onDelete: "cascade" }),
|
||||
stageEntry: integer("stage_entry").notNull(),
|
||||
stageEliminated: integer("stage_eliminated"),
|
||||
stageEliminatedWins: integer("stage_eliminated_wins"),
|
||||
|
|
@ -1319,9 +1319,9 @@ export const cs2MajorStageResultsRelations = relations(cs2MajorStageResults, ({
|
|||
fields: [cs2MajorStageResults.scoringEventId],
|
||||
references: [scoringEvents.id],
|
||||
}),
|
||||
participant: one(participants, {
|
||||
participant: one(seasonParticipants, {
|
||||
fields: [cs2MajorStageResults.participantId],
|
||||
references: [participants.id],
|
||||
references: [seasonParticipants.id],
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
221
drizzle/0087_small_susan_delgado.sql
Normal file
221
drizzle/0087_small_susan_delgado.sql
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
ALTER TABLE "participant_expected_values" RENAME TO "season_participant_expected_values";--> statement-breakpoint
|
||||
ALTER TABLE "participant_qualifying_totals" RENAME TO "season_participant_qualifying_totals";--> statement-breakpoint
|
||||
ALTER TABLE "participant_results" RENAME TO "season_participant_results";--> statement-breakpoint
|
||||
ALTER TABLE "participant_surface_elos" RENAME TO "season_participant_surface_elos";--> statement-breakpoint
|
||||
ALTER TABLE "participants" RENAME TO "season_participants";--> statement-breakpoint
|
||||
ALTER TABLE "event_results" RENAME COLUMN "participant_id" TO "season_participant_id";--> statement-breakpoint
|
||||
ALTER TABLE "cs2_major_stage_results" DROP CONSTRAINT IF EXISTS "cs2_major_stage_results_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "draft_picks" DROP CONSTRAINT IF EXISTS "draft_picks_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "draft_queue" DROP CONSTRAINT IF EXISTS "draft_queue_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "event_results" DROP CONSTRAINT IF EXISTS "event_results_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "group_stage_matches" DROP CONSTRAINT IF EXISTS "group_stage_matches_participant1_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "group_stage_matches" DROP CONSTRAINT IF EXISTS "group_stage_matches_participant2_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "participant_ev_snapshots" DROP CONSTRAINT IF EXISTS "participant_ev_snapshots_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_expected_values" DROP CONSTRAINT IF EXISTS "participant_expected_values_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_expected_values" DROP CONSTRAINT IF EXISTS "participant_expected_values_sports_season_id_sports_seasons_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "participant_golf_skills" DROP CONSTRAINT IF EXISTS "participant_golf_skills_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_qualifying_totals" DROP CONSTRAINT IF EXISTS "participant_qualifying_totals_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_qualifying_totals" DROP CONSTRAINT IF EXISTS "participant_qualifying_totals_sports_season_id_sports_seasons_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_results" DROP CONSTRAINT IF EXISTS "participant_results_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_results" DROP CONSTRAINT IF EXISTS "participant_results_sports_season_id_sports_seasons_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "participant_season_results" DROP CONSTRAINT IF EXISTS "participant_season_results_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_surface_elos" DROP CONSTRAINT IF EXISTS "participant_surface_elos_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participant_surface_elos" DROP CONSTRAINT IF EXISTS "participant_surface_elos_sports_season_id_sports_seasons_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "season_participants" DROP CONSTRAINT IF EXISTS "participants_sports_season_id_sports_seasons_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_match_games" DROP CONSTRAINT IF EXISTS "playoff_match_games_winner_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_match_odds" DROP CONSTRAINT IF EXISTS "playoff_match_odds_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_matches" DROP CONSTRAINT IF EXISTS "playoff_matches_participant1_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_matches" DROP CONSTRAINT IF EXISTS "playoff_matches_participant2_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_matches" DROP CONSTRAINT IF EXISTS "playoff_matches_winner_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "playoff_matches" DROP CONSTRAINT IF EXISTS "playoff_matches_loser_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "regular_season_standings" DROP CONSTRAINT IF EXISTS "regular_season_standings_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "tournament_group_members" DROP CONSTRAINT IF EXISTS "tournament_group_members_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "watchlist" DROP CONSTRAINT IF EXISTS "watchlist_participant_id_participants_id_fk";
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "cs2_major_stage_results" ADD CONSTRAINT "cs2_major_stage_results_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("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_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_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_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "event_results" ADD CONSTRAINT "event_results_season_participant_id_season_participants_id_fk" FOREIGN KEY ("season_participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "group_stage_matches" ADD CONSTRAINT "group_stage_matches_participant1_id_season_participants_id_fk" FOREIGN KEY ("participant1_id") REFERENCES "public"."season_participants"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "group_stage_matches" ADD CONSTRAINT "group_stage_matches_participant2_id_season_participants_id_fk" FOREIGN KEY ("participant2_id") REFERENCES "public"."season_participants"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "participant_ev_snapshots" ADD CONSTRAINT "participant_ev_snapshots_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_expected_values" ADD CONSTRAINT "season_participant_expected_values_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_expected_values" ADD CONSTRAINT "season_participant_expected_values_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "participant_golf_skills" ADD CONSTRAINT "participant_golf_skills_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_qualifying_totals" ADD CONSTRAINT "season_participant_qualifying_totals_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_qualifying_totals" ADD CONSTRAINT "season_participant_qualifying_totals_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_results" ADD CONSTRAINT "season_participant_results_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_results" ADD CONSTRAINT "season_participant_results_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "participant_season_results" ADD CONSTRAINT "participant_season_results_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_surface_elos" ADD CONSTRAINT "season_participant_surface_elos_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participant_surface_elos" ADD CONSTRAINT "season_participant_surface_elos_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "season_participants" ADD CONSTRAINT "season_participants_sports_season_id_sports_seasons_id_fk" FOREIGN KEY ("sports_season_id") REFERENCES "public"."sports_seasons"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_match_games" ADD CONSTRAINT "playoff_match_games_winner_id_season_participants_id_fk" FOREIGN KEY ("winner_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_match_odds" ADD CONSTRAINT "playoff_match_odds_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_matches" ADD CONSTRAINT "playoff_matches_participant1_id_season_participants_id_fk" FOREIGN KEY ("participant1_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_matches" ADD CONSTRAINT "playoff_matches_participant2_id_season_participants_id_fk" FOREIGN KEY ("participant2_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_matches" ADD CONSTRAINT "playoff_matches_winner_id_season_participants_id_fk" FOREIGN KEY ("winner_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "playoff_matches" ADD CONSTRAINT "playoff_matches_loser_id_season_participants_id_fk" FOREIGN KEY ("loser_id") REFERENCES "public"."season_participants"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "regular_season_standings" ADD CONSTRAINT "regular_season_standings_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "tournament_group_members" ADD CONSTRAINT "tournament_group_members_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "watchlist" ADD CONSTRAINT "watchlist_participant_id_season_participants_id_fk" FOREIGN KEY ("participant_id") REFERENCES "public"."season_participants"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
5221
drizzle/meta/0087_snapshot.json
Normal file
5221
drizzle/meta/0087_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -610,6 +610,13 @@
|
|||
"when": 1777505810235,
|
||||
"tag": "0086_marvelous_infant_terrible",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 87,
|
||||
"version": "7",
|
||||
"when": 1777661299612,
|
||||
"tag": "0087_small_susan_delgado",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ beforeEach(() => {
|
|||
autodraftSettings: { findFirst: vi.fn() },
|
||||
draftPicks: { findMany: vi.fn(), findFirst: vi.fn() },
|
||||
draftQueue: { findMany: vi.fn() },
|
||||
participants: { findMany: vi.fn() },
|
||||
seasonParticipants: { findMany: vi.fn() },
|
||||
seasonTemplateSports: { findMany: vi.fn() },
|
||||
},
|
||||
update: vi.fn().mockReturnThis(),
|
||||
|
|
@ -146,7 +146,7 @@ describe('Timer Autodraft Integration', () => {
|
|||
|
||||
it('should fall back to highest EV when queue is empty and queueOnly is OFF', async () => {
|
||||
mockDb.query.draftQueue.findMany.mockResolvedValue([]);
|
||||
mockDb.query.participants.findMany.mockResolvedValue([
|
||||
mockDb.query.seasonParticipants.findMany.mockResolvedValue([
|
||||
{ id: 'participant-high-ev', name: 'High EV Participant', expectedValue: 1000 },
|
||||
]);
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ describe('Timer Autodraft Integration', () => {
|
|||
expect(queueItems.length).toBe(0);
|
||||
|
||||
const queueOnly = false;
|
||||
const availableParticipants = await mockDb.query.participants.findMany();
|
||||
const availableParticipants = await mockDb.query.seasonParticipants.findMany();
|
||||
const selectedParticipant = queueOnly ? null : availableParticipants[0];
|
||||
expect(selectedParticipant).not.toBeNull();
|
||||
expect(selectedParticipant?.expectedValue).toBe(1000);
|
||||
|
|
|
|||
|
|
@ -232,18 +232,18 @@ export function initializeSocketIO(httpServer: HTTPServer): SocketIOServer {
|
|||
pickInRound: schema.draftPicks.pickInRound,
|
||||
timeUsed: schema.draftPicks.timeUsed,
|
||||
team: schema.teams,
|
||||
participant: schema.participants,
|
||||
participant: schema.seasonParticipants,
|
||||
sport: schema.sports,
|
||||
})
|
||||
.from(schema.draftPicks)
|
||||
.innerJoin(schema.teams, eq(schema.draftPicks.teamId, schema.teams.id))
|
||||
.innerJoin(
|
||||
schema.participants,
|
||||
eq(schema.draftPicks.participantId, schema.participants.id)
|
||||
schema.seasonParticipants,
|
||||
eq(schema.draftPicks.participantId, schema.seasonParticipants.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sportsSeasons,
|
||||
eq(schema.participants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
eq(schema.seasonParticipants.sportsSeasonId, schema.sportsSeasons.id)
|
||||
)
|
||||
.innerJoin(
|
||||
schema.sports,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue