Changelog
What's new in Work2Survive
Cancelled race support, dependency updates, lint cleanup
β¦ New / Improved
- +Bahrain GP (Round 4) and Saudi Arabian GP (Round 5) marked as cancelled β calendar shows them with a CANCELLED badge and muted styling
- +All scoring, lock processing, and cron jobs automatically skip cancelled races
- +Token grace reset: players receive 2 banked tokens for the next active race after a cancellation gap, so nobody is penalised for missed weeks
- +Calendar header now shows active round count and cancelled count separately
- +Updated to Next.js 16.2.2, React 19.2.4, TypeScript 6, and other dependency patches
β¦ Fixes
- β³Fixed all 38 ESLint warnings (unused imports, variables, parameters) β lint now reports 0 problems
- β³Roster carry-over after scoring now skips cancelled rounds when finding the next race
Sprint race scoring, standings rank changes, race commentary on results
β¦ New / Improved
- +Leaderboard now shows week-to-week rank changes (β²/βΌ) and last race points for each player
- +Race commentary displayed on individual results pages with player/team names highlighted in bold
- +Calendar now shows all practice sessions (FP1, FP2, FP3) and sprint session times
- +Six sprint weekends correctly flagged: China, Miami, Canada, Britain, Netherlands, Singapore
β¦ Fixes
- β³Sprint race detection fixed β OpenF1 API uses session_name (not session_type) to distinguish Sprint from Race sessions
- β³Sprint results now correctly synced and scored for sprint weekends
- β³Driver ID mismatch between OpenF1 and Jolpica APIs resolved β canonical short-form IDs used everywhere
- β³Scoring pipeline now refreshes calendar data from API before scoring to catch stale sprint flags
- β³Jolpica fallback result parsers now resolve driver IDs via DB to prevent FK violations
Weather forecast, track maps fixed for all circuits
β¦ New / Improved
- +Weekend weather forecast on the Analytics hero card β shows per-session forecast (FP1, FP2, FP3, Quali, Race) with temperature, rain probability, and wind speed, sourced from Open-Meteo
- +High rain probability sessions are highlighted in blue to help with tyre strategy decisions
- +Forecast updates hourly and appears automatically for upcoming races within the 7-day window
β¦ Fixes
- β³Track circuit maps now display correctly for all 24 races β previously most circuits showed "No track data" due to mismatched circuit name variants between the database and GeoJSON mapping
Auto-carry rosters, token fix, leaderboard roster change indicators
β¦ New / Improved
- +Rosters now auto-carry to the next race when scoring finalizes β no need to re-submit if keeping the same picks
- +Leaderboard shows a "SWAP" badge on players who changed their roster from last race
- +Expand a player row to see exactly what changed (old β new constructor/drivers)
β¦ Fixes
- β³Token bank: Race 1 free token no longer rolls over β after Round 1 players correctly start Round 2 with 1 token instead of 2
Security hardening β rate limiting, security headers, input validation
β¦ New / Improved
- +Rate limiting on login and passphrase endpoints β 5 attempts per 15 minutes per IP to prevent brute-force attacks
- +Rate limiting on league join β 3 attempts per 15 minutes per IP
- +Security headers added via Caddy β HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy
- +Analytics event tracking now requires authentication
- +Input validation: search queries capped at 200 characters, array parameters limited to 20 items
β¦ Fixes
- β³Passphrase minimum length increased from 4 to 6 characters for new and changed passphrases
- β³Admin check in commentary endpoint now uses isAdmin flag instead of hardcoded player ID
- β³Caddyfile updated to match blue/green deployment upstream names
Major news improvements β search, thumbnails, time grouping, and more
β¦ New / Improved
- +Search articles by keyword across titles and summaries
- +Article thumbnails extracted from RSS feeds and displayed in news cards
- +Time-based article grouping (Today, Yesterday, This Week, Older)
- +Unread news badge on sidebar and mobile nav
- +"Mark all read" button to clear all unread indicators at once
- +"My Picks" filter chip now shows article count badge
- +Scroll gradient indicators on filter chips when more options are available
- +Expand/collapse chevron on news cards with larger tap targets
- +Auto-refresh during race weekends with "new articles available" toast
β¦ Fixes
- β³Bookmarked filter now works correctly with pagination (DB-level filtering instead of post-query)
- β³Source filter now works server-side for accurate pagination and counts
- β³Better F1 content filtering β non-F1 motorsport articles (MotoGP, IndyCar, etc.) are now excluded
- β³Duplicate articles from different sources are now detected and deduplicated
- β³Stale articles older than 30 days are automatically cleaned up during sync
Leaderboard picks fallback and CI improvements
β¦ New / Improved
- +Leaderboard player cards now fall back to last race's picks when no picks exist for the upcoming race β tap any player to see their current roster
β¦ Fixes
- β³Staging CI deploys no longer hang indefinitely β migrator image build optimised to skip the full Next.js rebuild
Garage improvements and scoring fixes
β¦ New / Improved
- +Garage page now shows your current picks at a glance β if you haven't picked for the upcoming race yet, your last race picks are shown as a starting point
β¦ Fixes
- β³Removed fastest lap bonus point β there is no fastest lap bonus in our league rules. Existing scores have been corrected.
Migrated all F1 data feeds to OpenF1 as primary source
Added user metrics for app performance analysis
Live standings improvements β DNF detection, full driver breakdown
β¦ New / Improved
- +Live Race Breakdown now shows all drivers with their current position (e.g. P13: +0), even when outside the top 10 β previously only scoring drivers appeared
- +Retired/crashed drivers show "OUT: 0" in red in the breakdown, so you can instantly see which of your picks have DNF'd
- +DNF detection now uses OpenF1 session results (dnf/dsq flags) in addition to position-based detection β more reliable during live races
- +Docker environment updated: OpenF1 sponsor credentials now passed to all app containers for authenticated API access
Starting grid sync with DNS detection and race control messages
β¦ New / Improved
- +Quali Projection now uses the official starting grid from OpenF1 instead of raw qualifying results β grid penalties (e.g. pit lane starts, position drops) are automatically reflected in the projection before the race starts
- +DNS (Did Not Start) detection: drivers who are confirmed DNS (e.g. crash on reconnaissance lap) are excluded from the projection and score zero points
- +Grid Changes section: when post-qualifying penalties or grid changes are detected, the Quali Projection tab shows a compact list of race control messages explaining what changed
- +Banner text updates dynamically: "Based on official starting grid (penalties applied)" when grid data is synced, falling back to "qualifying order" if not yet available
- +Starting grid sync runs automatically within the existing polling window (1 hour before race start), retrying every 30 seconds until grid data is available from OpenF1
Live Standings tab with real-time race position tracking
β¦ New / Improved
- +Live Standings tab: during a race, a new emerald-accented "Live Standings" tab appears on the Dashboard showing projected season standings based on actual live race positions from the OpenF1 API β tap any row to see a full points breakdown
- +Positions update every 30 seconds during the race with a pulsing live indicator and "Updated Xs ago" timestamp
- +DNF detection: drivers who retire from the race are automatically excluded from scoring
- +The Live Standings tab automatically appears 1 hour before race start and disappears once final results are synced, seamlessly handing off to the regular standings
Work2Survive logo, News module, UI refinements
β¦ New / Improved
- +Work2Survive logo: custom SVG logo with animated gradient and glow effects, integrated into the header and sidebar
- +News module: a dedicated News page aggregating F1 headlines from multiple RSS sources with category filtering, source badges, breaking news ticker, and pick-impact banners highlighting news relevant to your roster
- +News articles are synced automatically every 30 minutes via cron
- +Bookmark and read-tracking: mark articles as read or bookmark them for later
Qualifying Projection standings, Apple HIG font size overhaul
β¦ New / Improved
- +Qualifying Projection tab: once qualifying results are in, a new "Quali Projection" tab appears on the Dashboard showing projected season standings if the race finishes in qualifying order β tap any row for a full points breakdown (Driver 1, Driver 2, Constructor, Sprint, Penalties)
- +Site-wide font size overhaul following Apple Human Interface Guidelines for mobile: player names bumped to 16px, driver codes and labels to 14px, 12px minimum floor enforced everywhere, and a 17px base font on mobile screens for comfortable touch-device reading
β¦ Fixes
- β³Eliminated all sub-12px text sizes across the entire app (previously some badges and labels were as small as 7px)
- β³Chart axis labels in analytics graphs bumped from 10px to 11px for readability
Analytics Intel Hub, Feedback system, Prediction audit trail
β¦ New / Improved
- +Analytics Intel Hub: a full race weekend intelligence dashboard powered by FastF1 telemetry data β qualifying predictions, race pace rankings, tyre degradation curves, compound life estimates, pit strategy hints, and pick recommendations (aggressive vs safety picks) all computed from FP1/FP2/FP3 practice session data
- +Track maps, speed comparisons, sector waterfalls, position charts, lap scatter plots, and reliability heatmaps provide deep data visualisation for each race weekend
- +FastF1 sidecar: practice session telemetry (lap times, sectors, tyre data, weather) now synced via a dedicated FastF1 Python sidecar service instead of OpenF1, providing richer and more reliable data
- +Feedback system: players can submit bug reports, feature requests, and improvement suggestions directly from the app via a new Feedback page β admin can review, triage, and export feedback as CSV
- +Prediction audit trail: every prediction snapshot is now stored automatically after each practice session sync, recording qualifying predictions, race pace rankings, strategy hints, and the tuning parameters used β enabling accuracy tracking and future algorithm improvements
- +Prediction accuracy scoring: after race results are finalized, predictions are automatically scored against actual qualifying and race positions using Mean Absolute Error, Spearman rank correlation, and top-3/top-10 accuracy metrics
- +Admin API endpoints for reviewing prediction accuracy history across the season
FP1/FP2/FP3 results synced via OpenF1
β¦ New / Improved
- +Practice session results (FP1, FP2, FP3) are now synced automatically from the OpenF1 API β driver finishing positions and best lap times appear in the FP tabs on each race detail page as soon as a session completes
Session results β Qualifying grid + FP/Race tabs
β¦ New / Improved
- +Race detail pages now have tabbed session results: Overview, FP1, FP2, FP3, Qualifying, and Race (Sprint weekends replace FP2/FP3 with Sprint tabs). Sessions without data show a placeholder
- +Race detail pages are now accessible before scoring is finalized β browse qualifying and practice results for any race, not just completed ones
- +The Calendar page shows the qualifying grid inline on the next race card once qualifying has completed, so you can check starting positions before the roster lock
- +Qualifying results are synced automatically via a new /api/cron/sync-sessions endpoint (runs after qualifying, before the race)
Lock countdown on the standings page
β¦ New / Improved
- +The league standings page now shows a live lock-state banner: a green pulsing dot and countdown timer when picks are open, with a direct link to the Garage to edit your picks. Handles all states β Sprint Locked (with time until free window), Free Window (no token cost), and Locked
Popular Picks widget, driver headshots
β¦ New / Improved
- +Popular Picks card on the league dashboard: shows a ranked bar chart of the most-picked constructor and drivers for the current race week, with team colours and driver headshots
- +All 24 drivers now have proper head-and-shoulders headshots β 16 sourced from the 2025 season archive, 8 new 2026 rookies (Antonelli, Bearman, Bortoleto, Colapinto, Doohan, Hadjar, Lawson, Lindblad) sourced from the official F1 media CDN
β¦ Fixes
- β³Removed the Next Race hero card from the bottom of the league page (race info is already visible in the garage and calendar)
Vivek J added, dinner line logic fixed, login redirect fixed
β¦ New / Improved
- +Vivek J added as the 11th player
- +Dinner line labels now show exact player counts (e.g. "5 Eating Free" / "6 Splitting the Bill")
β¦ Fixes
- β³Dinner line split corrected: with an odd number of players, more players now split the bill than eat free (11 players β 5 eat free, 6 pay)
- β³Login no longer freezes after signing in β the page now navigates immediately to the garage without needing a manual refresh
Roster confirmation sheet, mobile nav improvements, 2026 roster fix, rules rewrite
β¦ New / Improved
- +Confirmation sheet: tapping Save Roster now shows a bottom sheet with your selected picks, token cost preview, and a desperation trade warning before committing
- +Mobile nav is now horizontally scrollable β all 7 tabs (including History and Changelog) are accessible on phone
- +Rules page rewritten for accuracy: Swap Tokens now correctly explains per-pick token cost; Desperation Trade rule fixed to reflect per-change-beyond-balance logic; Sprint Weekends clarifies token bank is shared and free window applies to main picks only
β¦ Fixes
- β³2026 driver and constructor data corrected on staging and production: Audi and Cadillac constructors added, Sauber marked inactive, Bortoleto and HΓΌlkenberg moved to Audi, Lawson to RB, Hadjar to Red Bull, Bottas and PΓ©rez added to Cadillac, Lindblad added to RB
- β³Mobile nav was missing History and Changelog tabs
Per-component token costs, leaderboard picks display, results page, sign-out
β¦ New / Improved
- +Results page: list of scored races with top scorer, links through to per-race breakdown showing all player scores and the F1 top 10
- +Leaderboard now shows each player's constructor (logo or coloured pill) and two driver codes at a glance
- +Leaderboard shows each player's team name below their display name
- +Sign-out button added to the sidebar (desktop) and mobile header
- +Token cost is now per changed pick component β changing just one driver costs 1 token, changing both drivers and the constructor costs 3 tokens
- +Reordering the same two drivers (no actual change) costs zero tokens
- +Round 1 (Australian GP) is a free-for-all β unlimited roster changes at no token cost before the first race locks in
- +Automated weekly database backup from production to dev server (Sundays 03:00 UTC, 30-day retention)
β¦ Fixes
- β³Results page was incorrectly showing the admin panel β now shows race results
- β³Production site was missing LEAGUE_ID environment variable (fixed)
- β³Missing player table columns (passphrase_hash, team_name, team_acronym) added to production database
- β³Staging site was showing the generic league-join screen instead of the player login
β Known Issues
- !Jolpica API returns 10 constructors for 2026 (missing Cadillac) β Cadillac data added manually
- !Jolpica 2026 driver-constructor assignments are incorrect for Audi, RB, and Red Bull β corrected manually in the database
- !Per-race results detail page requires a race to be fully scored before it's accessible (correct behaviour, but shows a 404 for unscored races)
Initial production launch
β¦ New / Improved
- +Player authentication: click your name on the login grid, set a passphrase on first visit
- +Leaderboard / Dashboard: live standings with rank, points, dinner line indicator, and a season points chart
- +Garage: pick 1 constructor + 2 drivers per race, with lock-time countdown
- +Token bank system: 1 token earned per race week, bank up to 2, spend to swap picks
- +Desperation trades: swap with zero tokens at a β10 pt penalty
- +Sprint weekend support: separate sprint picks with a free-change window between sprint and main qualifying
- +August wildcard: one-time full team swap during the summer break
- +Calendar page: full 2026 season schedule with session times and lock countdowns
- +Rules page: full game rules with examples
- +Admin panel: manual data-sync triggers (calendar, drivers, results)
- +24 driver headshots and 11 constructor logos served locally
- +Automated race scoring: results fetched from Jolpica API every 2 hours on race Sundays, scores calculated and standings updated automatically
- +Real-time leaderboard updates via Server-Sent Events
- +8 players seeded: Elaine L, Danny W, Corrine T, Ken L, Cara C, Anushka M, Pratik K, Raunaq K
β Known Issues
- !Results and History pages not yet built (placeholder screens)