← All projects

Fantasy Auction

Auction fantasy football, rebuilt as a platform: a private app that scores every match and explains every point, a public sales site and two launch films. It's live now, running in parallel with our league's old setup, and the aim is paying leagues and hobbyists from next season.

Film 01 / 0:53 Fantasy Auction showreel The 53-second launch film on fantasy.auction. Motion graphics built around the real product: the auction, the squad, sealed bids and the table. Exported by Claude in Remotion.

The short version

managers in the founding league
19
scores identical in the first independent check
287/293
automated test cases
690+
written decision records
40
guides on the sales site
29

What it is

Fantasy Auction is fantasy football where every player has exactly one owner. Your group holds a real auction, in a room, with £100m each. Then the app runs the season: pick an XI before every kick-off, scores after every match, swaps between managers and blind sealed bids for new signings.

It's live now. It has scored every match for Thame Lads League, 19 managers, since 29 August 2026, running in parallel with our old setup this season. I imported everyone's existing totals, let the app score everything after the switch and kept comparing the two. From next season the aim is real paying leagues and hobbyist groups as well as us.

What I had to steer

The rule I kept drilling into the agents: every point must be explainable from four facts. The player and fixture, the owner at kick-off, the XI saved for that kick-off and the scoring rules in force. If one fact is missing the app shows a failure instead of guessing. Agents kept reaching for sensible-looking defaults, and I didn't want any.

The other steer was memory. Agents forget everything between sessions, so the repo remembers for them: one status page that a script rejects if it grows past 80 lines, one roadmap, a plain-English game guide and 40 dated decision records. When the FPL feed started refusing about a fifth of our requests, my call was to stop chasing the cause, measure the damage and run a month-long retry trial with a written exit rule.

What I wired together

Next.js and TypeScript on Vercel. Supabase for Postgres, auth and row-level security, across 146 migrations. Premier League statistics from the official FPL feed, a second source fenced off for penalties and API-Football ready as a fallback. Web push for the Friday team reminder, nightly encrypted backups, and a weekly scoring check where Claude in Chrome reads the old site so the app can be compared against it.

The sales site at fantasy.auction is a separate Next.js project: 29 guides, a real auction-price dataset, structured data, Search Console and IndexNow. The films were made in Remotion around the real team-pitch component with a sample squad.

Where I pushed it

This is the furthest I've taken an AI-built product. Real people use it every week, and the season doesn't pause for bugs. It's now built for more than one league: two leagues share the same football facts without sharing anything private, and an organiser can sign up and set up a league without me. That's what lets it take on paying leagues next season.

The bit I'm proudest of is the honesty. The first independent check matched 287 of 293 scores exactly, and the six differences sit in the open with their causes where we know them. An early website draft had a made-up founder quote and staged manager quotes. I cut them. The auction film uses an illustrated garden and says so.

Live site

See it live.

fantasy.auction homepage
Sales site The public site. Press 'Let the bids climb' in the hero to play an auction. The league app itself sits behind sign-in at app.fantasy.auction, so it stays out of the embed.

Films

More films.

Film 02 / 0:30 Auction night The first film. A generated garden illustration, the real team-pitch interface with a sample squad and original synthesised percussion. The captions describe every sound cue, so it works on mute.

The build log

From the chairman's arithmetic to a platform

Our league does fantasy football the old way. Everyone gets the same budget, we sit in a garden and auction the players, and once you own a player nobody else can have him. The rest of the season ran on an ageing website, a spreadsheet and whatever the chairman could work out in his head.

I wanted to rebuild the whole thing, properly enough that 19 managers would trust it with their bragging rights.

The auction stays in the garden

That was the first decision and it’s never moved. The app takes over once the squads are set: pick an XI before each kick-off, score each match from the official statistics, run swaps and sealed bids, keep the table.

Trust

The screens were the easy part. Every score has to be rebuilt from four stored facts, and anything ambiguous fails loudly. I imported everyone’s totals from the old site up to 29 August, let the app score everything after that and compared the two. A weekly check keeps comparing.

Agents and memory

Agents did almost all of the typing, so the documents mattered as much as the code: a short status page, one roadmap, a game guide in plain English and a decision record for every rule we argued about. New sessions read those first. That’s how a project this size stays coherent across well over a hundred agent sessions.

Selling it

Then the sales job: a separate site at fantasy.auction, a guide library for organisers and two films made in Remotion, a 30-second auction-night story and a 53-second showreel.

Where it is

It’s live. It has scored all 19 teams since 29 August, running in parallel with our old setup this season. Self-service signup is open, and from next season the plan is real paying leagues and hobbyist groups as well as ours. The FPL feed still refuses a chunk of our requests, and we’re partway through a retry trial with a written rule for when to switch sources.

Running a season

Since 29 August the app has been the league’s real system for all 19 managers. Building it was one job. Running it every week is another.

Scoring runs after every match and skips any match whose inputs haven’t changed, so a normal run takes a few seconds. Results close seven days after a match, and a closed match keeps the facts it closed with even if the source data changes later. By mid-October, 35 of our matches had closed.

Every Tuesday a check compares our scores with FantasyLeague.com. The first run matched 287 of 293 players exactly, and the five differences had known causes. Once the new players with different spellings were matched, the same list compared 299 of 299.

Then the jobs nobody sees: a nightly encrypted database backup, a daily clean-up that keeps the free database tier from filling up, a review tray for new players’ positions and sealed-bid rounds that I process as chairman. There’s a banter board and chairman announcements now too, because it’s still a league of mates.

The weak spot is the FPL data feed, which still refuses a share of our requests. The retry trial found no recovery, and there’s a written rule for when to switch sources.