diff --git a/app/services/simulations/mls-simulator.ts b/app/services/simulations/mls-simulator.ts index 3904d38..b159855 100644 --- a/app/services/simulations/mls-simulator.ts +++ b/app/services/simulations/mls-simulator.ts @@ -46,6 +46,7 @@ import { getParticipantSimulatorInputs, getSportsSeasonSimulatorConfig } from "~ import { simulateEloSoccerMatch, simulateSimpleSoccerGoals } from "./soccer-helpers"; import type { EloSoccerMatchOptions } from "./soccer-helpers"; import { normalizeSimulationResultColumns } from "./simulation-probabilities"; +import { logger } from "~/lib/logger"; // ─── Default constants (overridable via season simulator config) ─────────────── @@ -62,7 +63,7 @@ const MLS_PLAYOFF_TEAMS_PER_CONF = 9; function configNumber(config: Record | undefined, key: string, fallback: number): number { const value = config?.[key]; - return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : fallback; + return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback; } // ─── Public types ───────────────────────────────────────────────────────────── @@ -205,8 +206,9 @@ function getBySeeds( seeds: MlsConferenceSeed[], ...seedNums: number[] ): MlsConferenceSeed[] { + const byNum = new Map(seeds.map((s) => [s.seed, s])); return seedNums.map((n) => { - const entry = seeds.find((s) => s.seed === n); + const entry = byNum.get(n); if (!entry) throw new Error(`MLS playoff seed ${n} not found in conference bracket.`); return entry; }); @@ -397,7 +399,13 @@ export class MLSSimulator implements Simulator { const teamsWithElo = participants.flatMap((p): MlsTeamEntry[] => { const elo = eloMap.get(p.id); const conf = conferenceMap.get(p.id); - if (elo === undefined || conf === undefined) return []; + if (elo === undefined || conf === undefined) { + logger.warn( + `MLSSimulator: no Elo rating for participant "${p.name}" (${p.id}). ` + + `They will be excluded from simulation. Enter sourceElo or projectedTablePoints via Admin → Elo Ratings.` + ); + return []; + } const standing = standingsMap.get(p.id); const wins = standing?.wins ?? 0; const draws = standing?.ties ?? 0;