Skip to content

Add opt-in beta historical game insights - #58

Merged
avatarneil merged 6 commits into
mainfrom
t3code/add-ridiculous-game-stats
Sep 20, 2026
Merged

avatarneil merged 6 commits into
mainfrom
t3code/add-ridiculous-game-stats

Conversation

@avatarneil

@avatarneil avatarneil commented Sep 20, 2026 •

Copy link
Copy Markdown
Owner

Signed-in users can opt into Ridiculous stats (BETA) in the new Settings page. The preference defaults to off and follows the account across devices. Once enabled, game stats offer a “Generate ridiculous stat” button that finds real, unnecessarily specific historical comparisons without an LLM. It covers 20 team metrics across scoring, passing, rushing, turnovers, sacks, penalties, kicking, and punting, with every claim triggered by a measured total from the selected game. Football-context comparisons take priority, with first-since claims ahead of records and ties; pregame and unsupported cases show an honest empty state.

  • Add an authenticated /settings page and /api/settings endpoint with an account-owned preference. Hide insights while signed out, opted out, or waiting for settings; preserve the saved preference if a change fails. Label both the setting and insight card BETA.
  • Enforce sign-in and opt-in on the insight API before loading game/history data. Use private, uncached responses for settings and insights; reject malformed preferences, owner mismatches, and cross-origin mutations.
  • Add a Postgres archive, validated nflverse imports from 1999 onward, atomic/idempotent season refreshes, and an authenticated daily cron.
  • Compare the current game with overall team history, the exact opponent, or opponent nickname categories plus month, weekday, and home/away/neutral location. Preserve historical names and franchise relocations.
  • Find the latest equal-or-more extreme performance and require at least five intervening qualifying games within a complete comparison set of at least ten games for a first-since claim. Include rare low totals only once the selected game is final. Name its opponent, current total, and the previous occurrence in the claim.
  • Require at least ten earlier games, continuous season coverage, and complete measurements for each comparison. Keep regular season and postseason separate, exclude future games, and label live snapshots “so far.”
  • Limit all letter-count categories (odd, even, and long nicknames) to one trailing result per game, preserving a supported result when it is the only one available. Equivalent cohorts prefer football-context labels.
  • Keep each generated insight at its labeled snapshot time while the live box score polls. Fetch a fresh insight only on request, retaining the previous snapshot through slow or failed requests. Single-result games can refresh explicitly.
  • Include paginated receipts with every comparison game, its value, date, and ESPN link. Restore stat/receipt state through the URL, including schedule-game reloads.

Validation

  • Full CI passed on the updated branch, including all Chromium and Firefox shards. The PR is rebased onto the compact-header update and has no conflicts.
  • Production build, TypeScript, lint, and formatting checks passed. Lint reports only the seven existing warnings in unrelated files.
  • Unit and storage tests passed against isolated Postgres, including migration retries, atomic corrections, rollback, source validation, ties, missing data, temporal boundaries, and cron authentication.
  • All 37 unit/storage tests and three deployment tests passed. Regression coverage includes current-value dependence, missing/ordinary totals, pregame/live exclusions, recent equal performances, rare lows, and first-since ordering.
  • 34 focused Playwright checks passed in Chromium and Firefox, including mobile (390px), laptop (1194px), and wide (2560px) layouts, retries, pagination, reloads, first-since labels, game-switch races, stable content and card height during live polling, slow/failed insight requests, single-result refreshes, settings persistence, opt-in/opt-out, failed saves, signed-out API denial, sign-out, and guest auth resilience.
  • Imported the full 1999–2026 archive locally. Compared 20 team box scores against ESPN with no differences in overlapping metrics. Generation took roughly 30–75 ms in the sampled games; a real browser request completed in 265 ms with 4× CPU throttling, 1.6 Mbps download, and 150 ms simulated latency.
  • Verified the real API and browser flow against the local archive; the new card and receipts had no axe accessibility violations.

Live-game coverage

Read explicit ESPN team totals for passing/rushing touchdowns, field goals, punts, and punt yards in addition to the main team box score. Missing totals remain unknown. First-since comparisons allow recent occurrences instead of requiring a three-season gap.

Replayed the same five saved live snapshots against the same archive: all five now produce supported comparisons, versus two previously. This compares identical game states, so live scoring changes do not affect the result.

Matchup Previous comparisons Updated comparisons
Denver–Jacksonville 2 7
Chargers–Raiders 0 5
Dallas–Washington 0 1
Arizona–Seattle 0 5
San Francisco–Miami 8 14

Letter-count comparisons now appear at most once, after other supported results. All five saved snapshots still produce insights, with no letter-count comparisons leading. Generation took 15–33 ms in these snapshots. Added regression tests for same-season first-since claims, the five-game minimum, actual ESPN live totals, reordered columns, missing values, and pregame exclusion.

Preview verification and production setup

The PR preview is seeded and verified as of September 20, 2026. Its database is separate from production. Sign in and enable Settings → Ridiculous stats (BETA) to try the insights; the default remains off for everyone.

  • Loaded 28 seasons (1999–2026): 15,096 team-game rows across 7,548 games, including 14,548 completed team box scores. Scheduled games and missing measurements remain null.

  • Verified the deployed API returns real facts and complete supporting receipts. The sample Steelers–Dolphins game leads with a first-since claim tied to Pittsburgh’s 28 points in that game, with all intervening qualifying games in the receipts.

  • Verified generation, receipt display, pagination, and another-stat selection in Chromium against the deployed preview and real archive. The preview account-bracket count is unchanged.

  • Verified all five live games on the updated preview lead with football-context insights. Left a real Denver–Jacksonville insight and its receipts open through a box-score poll: no extra insight request, text replacement, or card-height change. Explicitly requesting another insight still fetches successfully.

  • Verified the deployed settings flow with two isolated temporary Clerk development accounts: default-off, keyboard-accessible opt-in, reload persistence, independent account preferences, real insight generation, BETA badges, opt-out denial, and private/no-store API responses. Invalid preference bodies and owner mismatches are rejected. No axe violations in the settings panel. Test users and preference rows were removed after verification.

The deployment migration creates account_settings with a false default; existing users remain opted out without a backfill.

Remaining production setup:

  1. Set a random CRON_SECRET of at least 32 characters in Vercel’s Production environment before deploying this change. The daily 10:00 UTC cron backfills missing seasons on its first run, then refreshes the latest two for corrections. Vercel cron does not run on previews.
  2. To populate production immediately after deployment, run bun run stats:import with its database environment. Otherwise the first scheduled cron populates it. The command is resumable; --dry-run validates without connecting to a database, and --from 2003 --to 2025 explicitly refreshes older seasons.

Preseason is outside the archive. The README documents source attribution, category definitions, import behavior, and operational setup.

@vercel

vercel Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nfl-playoff-bracket Ready Ready Preview Sep 20, 2026 11:15pm UTC

Request Review

@avatarneil avatarneil changed the title t3code/add ridiculous game stats Add ridiculous historical game stats across 20 metrics Sep 20, 2026
@avatarneil
avatarneil force-pushed the t3code/add-ridiculous-game-stats branch from bb9e361 to 26e6875 Compare September 20, 2026 19:07
@avatarneil
avatarneil force-pushed the t3code/add-ridiculous-game-stats branch from 26e6875 to 2c8ceae Compare September 20, 2026 19:07
@avatarneil avatarneil changed the title Add ridiculous historical game stats across 20 metrics Add game-specific historical stats across 20 metrics Sep 20, 2026
@avatarneil avatarneil changed the title Add game-specific historical stats across 20 metrics Add opt-in beta historical game insights Sep 20, 2026
Store historical team games with resumable nflverse imports and daily corrections. Generate verified comparisons across 20 metrics with live snapshots and inspectable receipts.

Add an additive archive migration. Seed preview databases with stats:import and configure CRON_SECRET before enabling production imports.
@avatarneil
avatarneil force-pushed the t3code/add-ridiculous-game-stats branch from 3d8ed78 to cfb08aa Compare September 20, 2026 23:14
@avatarneil
avatarneil merged commit 283a88d into main Sep 20, 2026
10 checks passed
@avatarneil
avatarneil deleted the t3code/add-ridiculous-game-stats branch September 20, 2026 23:42

This branch was successfully deployed

1 active deployment
Preview — cfb08aad Deployed Sep 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant