2.1.0
What's Changed
A performance + robustness release addressing an 11-item code audit. No user-facing pick/leaderboard behaviour changes.
Performance
- Score sync preloads games and pick-existence in bulk instead of two queries per game — a full season went from ~1,800 queries to a couple.
- Live ESPN polling (every 5 minutes) now bulk-loads the scoreboard's games in one query rather than one lookup per game.
- Profile stat cards compute each scope's rank and player total in memory from a single load per scope, instead of a separate count query per scope.
- Public stats resolve all followed-team logos in one query and count scored picks once (previously the same count ran twice).
- Admin stats resolve the top contested games' teams in a single batched query.
Changed
- Score sync now runs in the background. Clicking "Sync Scores" dispatches a queued job and returns immediately; the admin UI polls for completion and shows the result. Previously the multi-week fetch ran synchronously and could exceed PHP's execution limit on a full season, leaving scores half-synced. (For true async, configure a real queue driver — redis/database — in
config.php.) - Test-data seeding bulk-inserts picks in chunks instead of one row at a time, so seeding a full fake season no longer times out on shared hosting.
Fixed
- Confidence values are now ignored when confidence mode is disabled and range-checked only when enabled.
- Logo conversion/save failures are written to the log instead of failing silently, so missing team logos can be diagnosed.
Internal
- Removed redundant service-container bindings in favour of automatic injection.