Commit graph

5 commits

Author SHA1 Message Date
Claude
a9acfba546
Fix MLB division leaders missing when ESPN returns flat standings structure
When ESPN's API returns teams directly on the conference group (no division
children), all teams got division="" so only one team globally received
divisionRank=1. Fix by resolving division from a hardcoded team-name map
as a fallback, and scoping divisionRank computation per conference+division
to prevent AL/NL teams from sharing a group.

https://claude.ai/code/session_01288dkXYwKJUfXrEhPd8rmo
2026-06-11 17:40:21 +00:00
ea84ffd915 Fix MLB division leaders showing under wildcard (#84)
Some checks are pending
🚀 Deploy / 🐳 Build (push) Blocked by required conditions
🚀 Deploy / 🚀 Deploy (push) Blocked by required conditions
🚀 Deploy / 🧪 Test (push) Successful in 2m43s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m24s
2026-06-11 00:25:18 +00:00
add196902b Fix MLB standings 406 error and refactor ESPN adapter shared code (#62)
All checks were successful
🚀 Deploy / 🧪 Test (push) Successful in 2m21s
🚀 Deploy / ʦ TypeScript (push) Successful in 1m18s
🚀 Deploy / 🔍 Lint (push) Successful in 49s
🚀 Deploy / 🐳 Build (push) Successful in 12m18s
🚀 Deploy / 🚀 Deploy (push) Successful in 12s
## Summary

- **Root cause**: `statsapi.mlb.com` returns 406 (deprecated). Switched MLB to ESPN's free standings API (`site.api.espn.com/apis/v2/sports/baseball/mlb/standings`), consistent with NBA, WNBA, and MLS.
- **Refactor**: Extracted a shared `espn.ts` utility module, eliminating 4× duplication of `statsMap()`, `flattenEspnStandings()`, ESPN interfaces, and the `playoffSeed` → conference rank logic across adapters.
- **Bug fixes** found during review and applied across all affected adapters:
  - `parseConferenceRank`: `|| undefined` falsy-zero bug replaced with `isNaN` guard
  - Sort comparators: stable alphabetical tiebreaker added to MLB, NBA, WNBA
  - `winPct`: falls back to `wins/(wins+losses)` if ESPN omits the stat (was silently 0)
  - statsMap pre-built once per entry before sorting in all adapters (was rebuilt per comparison)
  - WNBA `parseEntry`: accepts pre-computed `sm` instead of rebuilding it internally
  - MLB `gamesBack`: tests updated to reflect ESPN returns numeric `0` for division leaders (old API used `"-"` → `undefined`)

## Test plan

- [ ] All 60 standings-sync unit tests pass (`npm run test:run -- app/services/standings-sync`)
- [ ] Trigger MLB standings sync from admin panel and confirm it returns data without a 406
- [ ] Confirm NBA, WNBA, MLS syncs still work (adapters touched but behaviour unchanged)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Chris Parsons <chrisparsons1127@gmail.com>
Reviewed-on: #62
2026-06-01 03:31:18 +00:00
Chris Parsons
08e93e955a
Fix MLB streak doubling bug, hide empty standings columns, improve mobile layout (#413)
* Fix MLB streak doubling bug, hide empty standings columns, improve mobile layout

- mlb.ts: use streakCode alone (the API already returns the full string like
  "W3"); appending streakNumber was doubling the digit, causing "L33" display
- Update mlb.test.ts mocks to match real API format (streakCode "W3" not "W")
- RegularSeasonStandings: conditionally hide GB/L10/STK columns when no rows
  have data, so pre-season or stats-free sports don't show blank columns
- Mobile two-row layout: GP/PCT/GB/L10 move to a secondary sub-row (sm:hidden)
  so all data stays visible without horizontal scroll on small screens; STK and
  W/L remain on the primary row; reduce min-w from 740px to 360px

https://claude.ai/code/session_01RADi3LhYMPbRDm5no1ZpdF

* Address code review: cleanup mlb streak type, fix soccer GP on mobile, hoist showSubRow

- mlb.ts: drop redundant `?? undefined` after optional chain; document that
  streakCode is the full string (e.g. "W3") and streakNumber is unused
- RegularSeasonStandings: hoist hasSecondaryStats → showSubRow to component
  level (it only depends on a prop, not on individual row data)
- Remove non-functional `truncate`/`min-w-0` from team name cell — truncation
  requires table-layout:fixed which we don't use; team names size naturally
- Soccer GP was hidden on mobile with no sub-row to surface it; GP now shows
  inline for soccer on all viewports, hidden only for non-soccer (which has
  the secondary sub-row)
- Add comment explaining totalCols counts hidden-on-mobile columns for colSpan
- Add missing test for GB column hiding when no rows have gamesBack data

https://claude.ai/code/session_01RADi3LhYMPbRDm5no1ZpdF

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-12 08:14:34 -07:00
Chris Parsons
2e2d8db777
Add MLB playoff simulator with AL/NL division standings, fixes #121 (#225)
* Add MLB playoff simulator with AL/NL division standings, fixes #121

- New `mlb-simulator.ts`: 50k Monte Carlo sim drawing division winners
  (weighted by p_div) and 3 WC teams per league, then simulating
  WC best-of-3 → DS best-of-5 → LCS best-of-7 → World Series.
  Elo parity factor 350; blends Vegas odds 30/70 when sourceOdds available.
- New `standings-sync/mlb.ts`: adapter for free statsapi.mlb.com API,
  mapping AL/NL conferences, division ranks, streaks, home/away/L10 splits.
- New `mlb-divisions` display mode in RegularSeasonStandings: shows 1 division
  winner per division section + Wild Card section with 3-spot playoff line,
  headings read "AL/NL League" instead of "Conference".
- Refactored buildNhlSections/buildMlbSections into shared buildDivisionSections
  (divisionSpots + wcSpots params); conferenceLabel now flows through group
  objects rather than being derived from displayMode in the render.
- DB migration 0062 adds `mlb_bracket` to simulator_type enum.
- 37 new tests across simulator, adapter, and component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix flaky tennis simulator test: increase trials and lower threshold

500 trials with a ~3–5% expected win rate had enough variance to
occasionally land below the 0.03 threshold (~2% failure rate).
Bumping to 2000 trials reduces the std dev by 2x; lowering the
threshold to 0.02 keeps the assertion meaningful (still well above
random 0.78%) while eliminating the flakiness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 08:47:02 -07:00