FFFF Add Pole Position Fantasy League to Fantasy F1 by Zesty0wl · Pull Request #14 · subinium/awesome-f1 · GitHub
[go: up one dir, main page]

Skip to content

Add Pole Position Fantasy League to Fantasy F1 - #14

Open
Zesty0wl wants to merge 1 commit into
subinium:mainfrom
Zesty0wl:add-pole-position-fantasy-league
Open

Zesty0wl wants to merge 1 commit into
subinium:mainfrom
Zesty0wl:add-pole-position-fantasy-league

Conversation

@Zesty0wl
@Zesty0wl Zesty0wl commented Oct 29, 2026 •
Copy link
Copy Markdown

Adds Pole Position Fantasy League to Fantasy F1.

It's a free F1 fantasy game with no paywall. You pick 2 drivers, a constructor and a captain on a $100M budget, and transfers are unlimited. You can run private leagues for friends or offices, and there are Guess the Podium and Driver of the Day side games. The site also has post-race reports, price/form tracking and a driver Fact File built on F1DB data. It's updated every race weekend of the 2026 season.

Disclosure: I'm the developer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@subinium
subinium commented Nov 7, 2026
Copy link
Copy Markdown
Owner

Thanks for the submission. Current schedules, reports and price data show substantive functionality. A deeper rules/results cross-check found a scoring inconsistency that needs resolution before inclusion.

Reproducible public discrepancy

  • Gabriel Bortoleto's Fact File lists the 2026 Azerbaijan race as P17 to P15 with 8 PPFL points.
  • Official qualifying, starting grid, and final result confirm Q17, grid P17, final P15.
  • Your current published rules award two points per place gained from qualifying. That gives 2 x (17 - 15) = 4, with no top-ten finish/qualifying or applicable fastest-lap bonus. Captaincy doubles race-finish points only, and this table explicitly excludes the captain bonus.
  • The same value feeds the displayed six-race form: 2.2 versus 1.5 after correcting this entry alone.

Please explain or fix this mismatch, identify the applicable historical rule version if different, and establish whether any manager totals or derived statistics also need correction. A stale provisional classification is a plausible explanation, not a verified cause.

Please also reconcile the deployed privacy text on immediate anonymization with the 30-day restoration window in the deletion component, and identify the responsible controller and relevant hosting/email processors.

I could not validate server-side private-league authorization without an account; some direct API requests received edge-level 403 responses, which prove neither a broken backend nor correct application authorization. An anonymized reproducible example or documentation of those controls would help.

This remains on hold pending the score reconciliation and disclosures. Closed source and the Claude Code attribution are not rejection reasons, and the review did not establish fraud or credential theft.

@Zesty0wl
Zesty0wl commented Nov 7, 2026 •
Copy link
Copy Markdown
Author

Thanks for the careful review. The Bortoleto entry was a real error, and checking it properly turned up more. Everything below is fixed and deployed.

Score reconciliation

  • Root cause: Azerbaijan was scored as soon as F1DB published the classification. The stewards then gave Bortoleto a 10-second time penalty (P13 to P15) and F1DB was corrected, but PPFL never re-scored a race it had already scored. His stored score used the pre-penalty result: 2 × (17 − 13) = 8. The same thing happened at Miami (Leclerc, 20 s) and Great Britain.
  • Fix: each scored race now keeps a fingerprint of the classification its scores came from. After every F1DB update, any race whose result has changed is re-scored with the same scoring code in one transaction (team scores, season totals and ranks, side games). Every change is logged with old and new points per pick and the reason, and the affected managers are told.
  • A full audit of the season against current F1DB data found two more issues, also fixed:
    • A driver who retired late but was still classified was scored as a DNF (−5), because F1DB records a retirement reason for him, and an NC driver scored 0. Finished / DNF / DSQ now come from the official classification in one place: classified = finisher, not classified = DNF. This is scoring version 4. Scores stored before today used version 3, which treated any retirement reason as a DNF. The published rules now say this.
    • 8 teams had no score for three rounds in which one of their drivers had no race entry. A rule added on 1 November (such a driver scores 0 and the rest of the team counts) had not been applied to those earlier rounds.
  • Impact: 296 team-race scores across 11 rounds, 107 of 129 teams. Season totals and ranks, Fact File stats and form, leaderboard figures and race reports are all recomputed from the corrected scores. Every affected manager has been told what changed and why, and all players received a notice. Prices already set after each race are not changed retroactively, as the rules state.
  • The leaderboard "top drivers / top constructors" and "perfect pick" figures had their own simplified calculations. They now use the same scoring path as team scores.
  • Your example now shows Azerbaijan P17 to P15, 4 points, and a six-race form of 1.5: https://polepositionfantasyleague.com/factfile/drivers/gabriel-bortoleto

Privacy

The policy (https://polepositionfantasyleague.com/privacy) now matches the deletion code. Name, email address and team name are removed immediately and sign-in links are deleted. The team, picks and league memberships are kept for 30 days under an anonymous placeholder so the account can be restored on request, and are then purged. The policy also names the controller (me, Neil Johnson, in 892B England) and the processors: Fasthosts (UK hosting), Cloudflare, Microsoft 365 (email), Anthropic (race reports: race statistics and top team names only), APNs, Firebase Cloud Messaging, and Google / Apple / Meta sign-in when a player uses it.

Private-league authorization

All league endpoints require a signed-in session. Without one they return an application-level 401, e.g. GET /api/leagues/mine → {"error":"Unauthorized","message":"Authentication required"}. For a signed-in user:

  • A private league's details return 403 unless the user is a member (or an admin). Member lists and the league table are members-only.
  • Joining a private league by ID only creates a join request, which the owner must approve.
  • Owner-only actions (settings, delete, regenerate the invite code, approve / reject requests, remove members) return 403 for anyone else. Approvals are checked against the league the request belongs to, so the owner of one league can't act on another's requests.
  • Invite codes of approval-required leagues are never returned to non-owners, and league IDs are random UUIDs.
  • The public leaderboard shows team names only when logged out.

These are covered by automated route tests that run on every release. The edge-level 403s you saw were most likely Cloudflare's bot protection in front of the site rather than the app. Unauthenticated requests that reach the app get the 401 above.

Happy to provide anything else you need.

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.

2 participants

0