* fix: NBA play-in advancement writes E7/W7 to wrong participant slot
advanceNBAPlayInWinner was writing the PIR1 7v8 winner to participant1Id
of First Round M3/M7, but those slots already hold E2/W2 (seeded at
generation time). The "already filled" guard fired, silently swallowing
both the winner advancement and the loser's placement into Play-In
Round 2 — so the 7/8 loser never appeared in the second play-in game.
Fix: write the 7v8 winner to participant2Id (the correct null slot) and
update the guard, doc comment, and load-bearing comment accordingly.
Also swap the p2Override arguments in the simulator and test fixture to
match the corrected slot layout (FR M3: E2=p1, E7=p2).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: hasGroupStage check for templates without groupStage property
undefined !== null is true, so templates that omit groupStage (like
nba_20) were incorrectly treated as group-stage templates, triggering
the generate-groups action and the "Invalid template or template has
no group stage" error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the NBA_20 bracket template (20-team structure with play-in
tournament) and rewrites the NBA simulator to be bracket-aware like UCL.
- Add NBA_20 bracket template: PIR1 (4) → PIR2 (2) → First Round (8)
→ Conference Semifinals → Conference Finals → NBA Finals
- Add participantLabels (East/West 1–10) for admin bracket UI slot labels
- Add generateNBA20Bracket and advanceNBAPlayInWinner in playoff-match.ts
with custom play-in advancement logic (PIR1 winners go to two different
destinations)
- Rewrite NBASimulator with two auto-detected modes:
- Bracket-aware (preferred): reads actual bracket state, simulates only
remaining rounds forward using 50k Monte Carlo iterations
- Season-projection (fallback): existing logic for pre-playoff use
- Guard resolveGame/resolveSeries against null participants (throws with
match ID and slot info instead of silently using empty string)
- Document load-bearing First Round match ordering in generateNBA20Bracket
- Add 25 unit tests covering Elo math, team data, template structure,
and all simulator integration paths
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>