* Add MLS sport simulator (mls_bracket)
Adds Major League Soccer as a draftable sport with a full-season Monte Carlo
simulator. Models both preseason regular-season projection (34 games across
Eastern and Western conferences) and the MLS Cup Playoffs bracket, including
the Wild Card (single game + PKs), Round 1 best-of-3 series, Conference
Semis/Finals (single game), and MLS Cup.
P1–P8 mapping: MLS Cup winner, finalist, Conference Finals losers, Conference
Semifinals losers. Conference assignment reads from regularSeasonStandings.conference
or falls back to the region simulator input ("Eastern"/"Western").
Admin inputs: projectedTablePoints (primary, max 102 for 34×3), with derivation
chain to sourceElo via existing input-policy; sourceOdds as alternative.
No hardcoded team data — all inputs are admin-managed per season.
- database/schema.ts: add mls_bracket to simulatorTypeEnum
- drizzle/0104_chief_boom_boom.sql: migration for the new enum value
- mls-simulator.ts: MLSSimulator + exported pure helpers for testability
- registry.ts / manifest.ts / simulator-config.ts: register mls_bracket
- mls-simulator.test.ts: 38 unit tests covering all helpers and sync checks
https://claude.ai/code/session_015wkBJ3SYGcMGjsddKKGkwa
* Fix MLS simulator: config loading, sourceOdds fallback, normalization
Three issues found in code review comparing against EPL and NFL simulators:
1. Load simulator config from DB via getSportsSeasonSimulatorConfig so
admins can override iterations, seasonGames, parityFactor, drawRates
per season without code changes. Previously all constants were hardcoded.
2. Add sourceOdds → convertFuturesToElo fallback when no sourceElo is
present. EPL and NFL both do this; MLS was throwing immediately instead
of attempting the odds conversion that the manifest declares as optional.
3. Call normalizeSimulationResultColumns before returning results, matching
EPL's local normalization pattern for consistency (runner also normalizes
globally, but EPL calls it locally too).
https://claude.ai/code/session_015wkBJ3SYGcMGjsddKKGkwa
* Polish MLS simulator: configNumber zero, logger warning, Map lookup
Three small fixes from secondary code review:
1. configNumber: allow value >= 0 (not just > 0) so admins can
legitimately set baseDrawRate or drawDecay to 0 without the value
being silently discarded and replaced with the default.
2. Add logger.warn when a participant is excluded from simulation due
to a missing Elo rating, matching the NLL bracket-aware pattern.
Gives admins a visible signal instead of a silent exclusion.
3. getBySeeds: build a Map once instead of calling Array.find() per
seed. Eliminates 4M linear scans across 50k iterations for a 9-
element array — trivially fast either way, but Map is the right tool.
https://claude.ai/code/session_015wkBJ3SYGcMGjsddKKGkwa
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs: plan NLL preseason simulator
* Add NLL Season + Playoffs Monte Carlo simulator
14-team regular season (18 games) projects top-8 via Elo + decaying
projectedWins prior (adjusts for games already played). Playoff bracket:
QF single-game (1v8, 2v7, 3v6, 4v5), SF and Finals best-of-3. Three
runtime modes: bracket-aware → known-seed → regular-season projection.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Commissioners can add Brackt to any league. Each team drafts one manager
from their own league; at season end, that manager's final overall fantasy
ranking earns placement points. Resolution fires automatically when all
other sports finalize.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add projected-wins input mode to admin Elo Ratings page
Admins can now enter projected season win totals instead of raw Elo
numbers on the Elo Ratings page. Wins are auto-converted to Elo using
the inverse formula and stored as sourceElo, keeping the rest of the
simulation pipeline unchanged.
- Add `projectedWinsToElo` / `eloToProjectedWins` to probability-engine
- Add `simulator-config.ts` centralising per-sport season length, parity
factor, and average opponent Elo (AFL, NFL, NBA, NHL, MLB, WNBA)
- Admin Elo Ratings page: toggle between Elo and Projected Wins input
modes; bulk import parses wins format; existing sourceElo back-fills
the wins field on load
- AFL simulator now reads sourceElo from participantExpectedValues first,
falling back to hardcoded TEAMS_DATA then 1400
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix lint errors in simulator-config tests and probability-engine
- Replace non-null assertions (`!`) with optional chaining (`?.`) in simulator-config tests
- Remove redundant type annotations on default parameters in probability-engine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>