Commit graph

3 commits

Author SHA1 Message Date
Chris Parsons
880b7faa6b Fix TypeScript errors: cast response.json() to EspnStandingsResponse
Some checks failed
🚀 Deploy / 🧪 Test (pull_request) Failing after 2m39s
🚀 Deploy / ʦ TypeScript (pull_request) Successful in 1m19s
🚀 Deploy / 🔍 Lint (pull_request) Successful in 51s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 19:54:23 -07:00
Chris Parsons
e353c17a0b Fix MLB standings 406 error and refactor ESPN adapter shared code
Some checks failed
🚀 Deploy / 🧪 Test (pull_request) Successful in 2m28s
🚀 Deploy / ʦ TypeScript (pull_request) Failing after 1m9s
🚀 Deploy / 🔍 Lint (pull_request) Successful in 46s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
- Switch MLB standings from deprecated statsapi.mlb.com to ESPN API
  (same source as NBA, WNBA, MLS — no auth required)
- Extract shared espn.ts utility: EspnStat/Team/Entry/Group/Response
  interfaces, statsMap(), flattenEspnStandings(), parseConferenceRank(),
  sortByWinLoss(); removes 4× duplication across adapters
- Fix parseConferenceRank falsy-zero bug (|| undefined → isNaN guard)
- Add stable alphabetical tiebreaker to MLB, NBA, WNBA sort comparators
- Fix winPct silent-zero: fall back to wins/(wins+losses) if ESPN omits stat
- Pre-build statsMap once per entry before sorting in all adapters
- Fix WNBA parseEntry to accept pre-computed sm instead of rebuilding it
- Restore and update gamesBack tests (ESPN returns numeric 0 for leaders,
  not the old API's "-" string)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 18:18:15 -07:00
Chris Parsons
766ba948e1
Add MLS standings sync and fix simulator conference resolution (#423)
* Add MLS standings sync and fix simulator conference resolution

- New MlsStandingsAdapter using ESPN's free soccer API (no key required),
  returning Eastern/Western conference data, W/D/L/GF/GA/GD/PTS, conference
  rank, and home/away records; registered under mls_bracket
- Display route now shows soccer table columns and a 9-team playoff cutoff
  line for mls_bracket (top 9 per conference qualify for MLS Cup Playoffs)
- MLS simulator gains a third conference fallback: reads externalId="Eastern"
  or "Western" on the participant, mirroring the LLWS pool-assignment pattern
  so admins can bootstrap conference data before the first standings sync
- 9 unit tests covering stat mapping, conference normalization, rank ordering,
  and error paths

https://claude.ai/code/session_01WhzXHpv6taXdHzhgvnv83u

* Address code review feedback on MLS standings + simulator

1. Update mls-simulator.ts module comment to document the new step-3
   externalId fallback in the conference resolution order
2. Tighten normalizeConference to exact-match "Eastern"/"Western
   Conference" instead of broad substring, preventing false matches
   on names like "Northeast"
3. Pre-parse statsMap for each entry before the sort so it isn't
   rebuilt O(n log n) times during comparison
4. Document the externalId name-matching tradeoff on
   parseConferenceFromExternalId
5. Try ESPN's gamesPlayed stat before falling back to wins+losses+ties
   sum; export parseConferenceFromExternalId for direct testing
6. Add tests: normalizeConference passthrough, winPct=0 at preseason,
   and parseConferenceFromExternalId (case-insensitivity, null/undefined,
   numeric ESPN IDs, unrecognized strings)

https://claude.ai/code/session_01WhzXHpv6taXdHzhgvnv83u

* Fix lint: replace != null with !== null && !== undefined

oxlint enforces eqeqeq; the five != null checks in mls.ts were flagged.

https://claude.ai/code/session_01WhzXHpv6taXdHzhgvnv83u

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-14 15:39:40 -07:00