side project · early version live

On The Gate

Every football match near you, on one map — from the Premier League all the way down to the clubs where you still pay cash at the turnstile.

role
Solo — product, backend, frontend, data
status
Early version live at onthegate.app
stack
FastAPI, PostgreSQL, SQLAlchemy, Alembic, React, Vite, Leaflet, PWA
testing
pytest for the API, Playwright end-to-end for the web app

The idea

“On the gate” is what you say when you pay at the turnstile instead of buying a ticket in advance — something that still happens at hundreds of grounds across the English football pyramid.

If you support a big club and can’t get a ticket, your options are usually a dodgy stream or nothing. Meanwhile there’s a Step 5 game fifteen minutes away, it’s a fiver on the gate, and it might be the best afternoon you’ve had in months.

The problem isn’t interest, it’s discovery. Score apps tell you what’s on but not what’s near you, and non-league information is scattered across hundreds of club websites. On The Gate puts it on one map: open it, see what’s nearby, go to a game.

What it does

  • Map-first. Opens centred on your location with the nearest fixtures pinned, colour-coded by step of the pyramid. Cup ties stand out.
  • List view for the same fixtures sorted by distance or kick-off time, with filters (the default is “next 7 days”).
  • Club, ground and fixture pages, plus favourites — and real club crests for 241 of the 253 clubs currently loaded.
  • Installable PWA with an offline app shell, so it behaves like a native app on iOS and Android without an app store.

How it’s built

The backend is a FastAPI service over PostgreSQL, with a deliberately boring shape: thin routers, all queries in a CRUD layer, SQLAlchemy models kept separate from the Pydantic schemas that define the API contract, and hand-reviewed Alembic migrations. The frontend is React and Vite with Leaflet for the map.

A few decisions I’m pleased with:

  • Nearby search without a full table scan. /fixtures/nearby first filters by a latitude/longitude bounding box, then ranks the survivors by exact Haversine distance — cheap, and no PostGIS needed at this scale. (I wrote this one up.)
  • Security before launch, not after. I ran a dedicated audit pass and fixed what it found: input bounds on coordinates and radius, per-IP rate limits weighted by endpoint cost, an admin key on every write, security headers and gated API docs.
  • Data as a first-class problem. Club, ground and fixture data is researched into versioned JSON with documented sources and loaded by an idempotent seeder, so the dataset can grow without anyone touching code.
  • Built with AI, reviewed by a human. Like my day job, I use AI coding agents heavily on this project — with a written project log, a clear split between planning and execution, and every change reviewed before it lands.

What’s next

Broadening fixture coverage down the pyramid, pagination and caching on the API, a privacy-first location consent flow, and getting it in front of more fans. If you run a non-league club and want to be on the map, I’d love to hear from you.

← Back to George Mather’s projects