Commit Graph

5 Commits

Author SHA1 Message Date
NilsBriggen 03b0fa734e Web Push: goal, kickoff and full-time alerts for a followed team
Fully progressive: without VAPID keys in the environment the API says
404, the bell never renders, and the service worker addition (a push
handler via workbox importScripts — no SW strategy change) is inert.
With keys: a bell on each team page requests permission, subscribes
(one team per device) and the server diffs fixture states on every
broadcast to push Kickoff / Goal / Full time to that team's followers.
Dead endpoints (404/410) self-clean. Round-trip verified locally with
dev VAPID keys; disabled mode verified too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 08:21:55 +02:00
NilsBriggen 45c0a978fc v2 Phase 3: rigorous backtest + Methodology page
- scripts/buildBacktest.ts: honest walk-forward validation — params fit on
  pre-2018 internationals, tested out-of-sample on 7,988 matches (2018-2026)
  predicting each game from prior data only. Proper scoring (Brier/log-loss/RPS/
  accuracy) vs uniform / base-rate / Elo-only baselines + a calibration analysis
  (reliability bins + ECE). Results: 60% accuracy, RPS 0.171 (beats all
  baselines), ECE 0.01 (excellent calibration).
- Methodology page (/methodology): plain-language model walkthrough, the backtest
  scorecard, a custom-SVG reliability diagram, and honest limits. Transparency is
  the differentiator — no market odds, no overclaiming.
- ReliabilityDiagram component; 'Model' nav entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 16:12:40 +02:00
NilsBriggen 7f4838d032 v2 Phase 2: match previews + team profiles
- buildPreviewData.ts: precomputes from 150y of results → h2h.json (825 WC-team
  pairings, full records + recent meetings) + scorers.json (top-10 all-time
  scorers per team). Committed goalscorers.csv.
- server/src/preview.ts: assembles MatchPreview / TeamProfile from three layers —
  historical (h2h, scorers), DB enrichment (ESPN form/lineups/venue), live model
  (W/D/L, xG, odds, Elo). /api/preview/:num + /api/team/:name.
- Client: rich /match/:num page (model expectation, recent form chips, H2H record
  + recent meetings, lineups-or-key-players) and /team/:name profile (Elo, odds,
  standing, fixtures, all-time scorers). Match cards now link to previews;
  cross-linking between matches and teams.
- Verified: Mexico-SA preview (81% W, 2-0, form, H2H 2-1-1, Borgetti 37) and
  Argentina profile (Messi 63) render; 22 tests pass; build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 15:34:54 +02:00
NilsBriggen 9c7605391c Phase 4: polish + deploy-ready — mobile nav, README, Docker validation
- Mobile bottom tab bar (icon tabs) with the top nav hidden on small screens;
  content padding so it never overlaps
- data: scripts run via bun (not tsx/node) so the oven/bun build image needs no
  node — fixes the Dockerfile data:build step
- README: features, data sources, dev/test/build/deploy, env vars
- Validated the production Docker image end-to-end: build succeeds (378MB),
  container serves /healthz, /api/snapshot (104 fixtures), /api/predictions
  (20k sims), the SPA with deep-link fallback, and the story dataset

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:39:58 +02:00
NilsBriggen 4e4e75a1d8 Phase 0: scaffold cup26 — Vite+React+Fastify TS PWA, broadcast theme, app shell
Mirrors the TTRPG stack (strict TS, Tailwind 4, vite-plugin-pwa, esbuild server
bundle, multi-stage Dockerfile, Traefik compose). Floodlit-pitch design tokens,
UI primitives (Button/Card/Badge), TanStack Router shell with Live/Groups/
Bracket/Predict/Story routes (placeholders), dependency-free PWA icon generator.
Raw data staged: openfootball 2026 fixtures + martj42 international results CSV.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:49:13 +02:00