Commit Graph

73 Commits

Author SHA1 Message Date
7784eaf9ce feat: overhaul hype score algorithm with 9 hockey-driven improvements
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 16s
- Empty net detection: pulled goalie triggers +150-250 bonus, stacks with PP
- Playoff series importance: Game 7 Cup Final = 200, elimination games scale
  by round; fallback of 100 when series data unavailable
- Period-aware score differential: 2-goal deficit penalty DECREASES in final
  2 min of P3 (goalie-pull zone), 3+ goal games get harsher penalties late
- Persistent comeback narrative: tracks max deficit, sustained bonus for 2+
  goal recoveries instead of one-shot spike (0-3 to 3-3 = 150 persistent)
- Shootout special handling: flat base 550 with no time component; ranks below
  dramatic close P3 games (skills competition, not hockey)
- Multi-man advantage: parses situationCode for 5v3/4v3, applies 1.6x PP mult
- Non-linear time priority: elapsed^1.5 curve weights final minutes more
- Matchup multiplier rebalance: P1/P2 from 2.0/1.65 to 1.5, tiebreaker not
  dominant factor
- Frontend gauge max raised from 700 to 1000 with adjusted color thresholds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 19:02:43 -04:00
6c098850f5 fix: use truthy check for intermission filter, add route test
All checks were successful
CI / Lint (push) Successful in 7s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 19s
`is True` strict identity fails if the NHL API returns an integer 1
instead of a JSON boolean. A truthy check is safe here since the
Intermission field is always False/0 for non-intermission live games.

Also adds a test that verifies intermission games are separated from
live games in the /scoreboard response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:57:00 -04:00
f652743333 feat: add intermission section separate from live games
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 7s
CI / Build & Push (push) Successful in 18s
Games in intermission now appear in their own section between Live and
Scheduled. The section is hidden when no games are in intermission,
matching the behavior of the other section headings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:50:47 -04:00
429c42e7b0 fix: scale badges and hype label at desktop breakpoints
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 8s
CI / Build & Push (push) Successful in 21s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:43:27 -04:00
8e1c455ded fix: correct NHL API situation structure for power play detection
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 22s
The NHL API nests situationDescriptions under situation.homeTeam /
situation.awayTeam, not at the top level. The old flat-structure
lookup always returned an empty list, silently breaking both the
PP indicator on the frontend and the PP bonus in the hype score.
Updated get_power_play_info, the _priority_components PP check,
and all test fixtures to match the real API shape.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:37:31 -04:00
9edc9914a3 fix: invert matchup scoring so top-ranked teams boost priority
All checks were successful
CI / Lint (push) Successful in 7s
CI / Test (push) Successful in 7s
CI / Build & Push (push) Successful in 19s
Previously league_sequence was summed raw and subtracted, meaning
rank-1 teams received the smallest penalty — directionally correct
but fragile and confusing. Now the rank is inverted (33 - sequence)
so rank 1 contributes 32 quality points and the result is added as
a bonus, making the intent explicit: better matchups = higher hype.
Also renames the breakdown field matchup → matchup_bonus.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:34:05 -04:00
cf0dec3513 fix: scale section headings with desktop breakpoints
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 8s
CI / Build & Push (push) Successful in 17s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:26:30 -04:00
58c31d6766 feat: responsive desktop scaling for game cards
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 18s
Adds two desktop breakpoints (900px, 1400px) that progressively
increase card width (290→340→400px), logo size (40→48→56px), score
font size (1.6→1.9→2.2rem), and team name size. Adds max-width on
main to keep layout centred on ultra-wide screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:23:47 -04:00
c9f5c7c929 feat: expose hype score breakdown in /scoreboard response
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 19s
Adds a "Hype Breakdown" dict to every game in the API response with
the individual components that sum to Priority: base period score,
time priority, matchup penalty, closeness bonus, power play bonus,
comeback bonus, and importance sub-components (season weight, playoff
relevance, rivalry multiplier). Achieved by extracting private
_priority_components() and _importance_components() helpers; public
function signatures and all tests unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:13:05 -04:00
3d77c7cd5a feat: PWA support with hockey puck icon
All checks were successful
CI / Lint (push) Successful in 7s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 17s
Adds full PWA compliance: web app manifest, service worker with
cache-first static / network-first scoreboard strategy, and a
generated hockey puck icon (512, 192, 180, 32px) on the app's
dark navy background. Includes all required meta tags for iOS
standalone mode and a /favicon.ico route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 19:04:33 -04:00
bf39bb6bd5 style: apply ruff formatting
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 7s
CI / Build & Push (push) Successful in 18s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 18:41:10 -04:00
47a8c34215 feat: game importance factor in hype scoring
Some checks failed
CI / Lint (push) Failing after 6s
CI / Test (push) Has been skipped
CI / Build & Push (push) Has been skipped
Adds calculate_game_importance() that boosts Priority for high-stakes
regular-season matchups based on season progress (sharp ramp after game
55), playoff bubble proximity (wildcard rank ~17-19 = max relevance),
and divisional/conference rivalry (1.4x/1.2x multipliers). Max bonus
150 pts applied to both LIVE and PRE games; playoff and FINAL games
are unaffected. Extends standings schema with division, conference,
games_played, and wildcard_sequence fields fetched from the NHL API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 18:39:55 -04:00
8945b99782 feat: power play indicator with live countdown clock
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
Shows a red pill below the team rows when a PP is active, displaying
the team on the power play and a ticking countdown. PP clock always
resyncs from the API (no local anchoring) since 2-minute penalties
are short enough that accuracy matters throughout. Removed the old
inline PP text from team rows.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:58:31 -04:00
257e2151c8 fix: smooth intermission clock by preserving local anchor across renders
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 16s
Snapshot the locally-computed clock state before each re-render and
restore it afterwards, so the API response doesn't cause a visible
jump. Only resync to the API value in the final 60 seconds, where
accuracy matters.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:55:48 -04:00
96529c4705 feat: smooth clock countdown for intermission and live play
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 17s
Store seconds + received-at timestamp on time badge. A 1s interval
decrements locally so the clock never stutters between API polls.
Drift-corrected: always computed from the anchored API value, not
accumulated ticks. Re-render on each API response reanchors to the
real value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:51:05 -04:00
e2d2c7dd97 feat: overhaul hype scoring algorithm
All checks were successful
CI / Lint (push) Successful in 6s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 15s
- Period base: playoff OT escalates indefinitely (P4=600, P5=750…),
  reg season P4=5-min OT (600), P5=shootout (700)
- Time priority range increased (max ~300 vs old ~120), calibrated
  to period length so 5-min reg season OT reads correctly
- Matchup multiplier inverted: higher period = less weight (any OT
  is exciting regardless of teams)
- Replace unconditional score_total with closeness bonus: rewards
  tight games regardless of goal volume (5-4 == 1-0 at same diff)
- Power play bonus: 30 (P1/P2) → 50/100/150 (P3 by time) → 200 (OT)
- Comeback bonus: one-time pulse (+50/75/100 by period) when trailing
  team scores to within 2 goals; keyed on team names, clears after
  firing, skips intermission

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:46:10 -04:00
62afc1001e feat: amber top border for intermission games
All checks were successful
CI / Lint (push) Successful in 7s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 15s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:10:02 -04:00
3169d1a1ff fix: resolve 4 logic bugs found in code review
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 17s
- utc_to_eastern: use zoneinfo instead of hardcoded EDT offset (-4)
  so start times are correct in both EST and EDT
- standings: fetch before truncate so a failed API call doesn't wipe
  existing standings data
- routes: call parse_games() once per request instead of three times
- scheduler: wrap run_pending() in try/except so an unhandled exception
  doesn't kill the background thread

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:06:45 -04:00
56feb0a5f2 polish: improve game card aesthetics
All checks were successful
CI / Lint (push) Successful in 19s
CI / Test (push) Successful in 8s
CI / Build & Push (push) Successful in 18s
- larger scores (1.6rem), logos (40px), and card width (290px)
- green top border accent on live game cards
- section headings reduced to small muted caps
- more breathing room in team rows
- slightly larger card radius and gap

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 14:00:18 -04:00
ed05d6adfc refactor: replace shots bar with inline SOG on team rows
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 15s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:57:00 -04:00
889f429dc6 feat: move shots bar between team rows for cleaner layout
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:53:40 -04:00
1394b21fb3 fix: use monochromatic near-white and slate gray for shots bar
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:49:52 -04:00
cb712245c2 fix: show shots bar during intermission
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:46:42 -04:00
869a7a91b7 fix: use cyan and lime for shots bar
All checks were successful
CI / Lint (push) Successful in 9s
CI / Test (push) Successful in 7s
CI / Build & Push (push) Successful in 13s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:44:59 -04:00
66fff68e6a fix: use sky blue and pink for shots bar to improve contrast
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 11s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:42:41 -04:00
bada8c0b7b fix: use perceptually balanced colors for shots bar
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 13s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:40:59 -04:00
9ad563ed3f feat: add shots on goal bar to live game cards, clean up gitignore
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 13s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:19:59 -04:00
dd5ac945bd refactor: rename functions across codebase for clarity
All checks were successful
CI / Lint (push) Successful in 7s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
2026-03-29 10:21:01 -04:00
a4dc7dff52 refactor: flatten app/scoreboard/ subpackage and rename files for clarity
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 6s
CI / Build & Push (push) Successful in 16s
2026-03-29 10:16:35 -04:00
da277e41a4 fix: center game boxes on page
All checks were successful
CI / Lint (push) Successful in 4s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
2026-03-29 09:48:47 -04:00
d1d711828c fix: center and resize page title and section headings
All checks were successful
CI / Lint (push) Successful in 5s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 16s
2026-03-29 09:45:18 -04:00
10d7cb9b02 refactor: rewrite UI with clean layout, fetch API, and proper card structure
All checks were successful
CI / Lint (push) Successful in 4s
CI / Test (push) Successful in 5s
CI / Build & Push (push) Successful in 14s
2026-03-29 09:41:34 -04:00
3994943757 good luck
Some checks failed
CI / Lint (push) Successful in 58s
CI / Test (push) Successful in 8s
CI / Build & Push (push) Failing after 1m33s
2026-03-29 09:20:21 -04:00
8913b40a8c hotfix: correct for dst 2024-03-11 12:37:19 -04:00
daabae1e49 fix: add shootout indicator 2024-02-25 01:17:04 -05:00
a1352869ad fix: adjust game score calculation 2024-02-22 23:04:49 -05:00
f059d4228b fix: raise gauge ceiling to 700 2024-02-22 23:04:38 -05:00
65369896cc fix: record sizes are now consistent 2024-02-22 02:16:12 -05:00
20ffd05df1 fix: correct date crossover time 2024-02-22 02:08:56 -05:00
5d65533ff5 fix: drop leading zero for scheduled games 2024-02-22 02:06:15 -05:00
960ff6e5ac fix: change date crossover to 3:00 am ETC 2024-02-22 02:00:39 -05:00
360188114e fix: adjust scoreboard time 2024-02-22 01:56:46 -05:00
94f9cced2e game priority: double differential adjustment at 5 minutes left in third 2024-02-22 01:17:13 -05:00
3edb84c333 fix: change scale to 650 instead of 600 2024-02-22 01:16:31 -05:00
6ec9a7aef1 fix: lower weight of total score 2024-02-22 00:14:39 -05:00
dfb86f6fd5 changes hype meter scale to 600 instead of 700 2024-02-22 00:14:14 -05:00
e5824cefc5 fix: sort games in intermission by time left 2024-02-22 00:11:22 -05:00
8c5de8602f feat: add matchup adjustment scaling. Earlier the period, the heavier we way the matchup strength 2024-02-21 23:52:06 -05:00
4da3c2dfdd fix: live game adjustments 2024-02-21 23:42:41 -05:00
07ff5ac055 feat: Push the games that are in intermission to the bottom, but retain their sort 2024-02-21 18:40:21 -05:00