La Fossa Events
The platform behind a local sports festival I co-organize — a management app for the staff and a public site where players sign up and book the pitch.
- Status
- In production · 2 editions run on it
- Role
- Sole developer, co-organizer
- Period
- Jun 2026 – now
- Platform
- Web · desktop, tablet and phone
- Stack
- Next.js · React · TypeScript · Supabase · Postgres · TanStack Query

Problem
La Fossa Events runs local sports events in Santa Maria La Fossa, a village near Caserta: La Fossa Games, a summer week of tournaments, and FantaFossa, a five-a-side tournament where the teams are built at an auction, fantasy-football style. I'm one of the organizers.
An edition means tournaments, teams, a bar till, sponsors, invoices, and a pitch that people book all year round. The first La Fossa Games had 350 players, over 1,000 attendees and 58 local sponsors. That needs one system the staff can trust on a match night, and a public face that sends requests straight into it. I build the software I use myself.
What I built
- One management app for the whole edition: tournaments with groups, fixtures, results and standings; teams and players; sponsors, sign-up requests, documents and invoicing.
- A till and stock for the bar, used on a tablet at the counter, with end-of-night cash closures and printing through a separate print agent.
- Full-screen views for the room: draws and the FantaFossa auction projected on a screen, without the app's navigation.
- Roles and permissions for owners, admins, cashiers, staff and viewers, set per module and action and enforced by row-level security.
- The public site: every format and past edition, standings for public tournaments, and requests to join a tournament or book the pitch, which reach the management app as pending until the staff confirm them.



Decisions
The management app runs one edition at a time, by construction.
The festival only ever prepares one edition, so the database has no event ID at all. The current edition is a single-row table that can't hold a second one, which keeps queries and permissions simple. Going multi-event would take a new decision and a migration, not a stray foreign key. Before a new edition starts, the app takes a backup that can be restored, then resets.
The bar and the pitch outlive the festival; the tournaments don't.
I split the data into two lifecycles. Pitch bookings, the till and the stock run all year and survive the reset; tournaments, teams, sponsors and the festival's accounts belong to the edition and go with it. No permanent table may point at one that gets reset, and the festival's bar takings are derived from the till closures within its dates instead of being copied into its accounts.
The public site keeps its stories in code, not in the database.
The management app wipes its edition every year, but the site has to keep an archive of every past one. So editorial content is versioned with the site, and only live state — free pitch slots, open tournaments — comes from the database. Every text change needs a release; in exchange, a reset can't erase the archive and there's no CMS to run.
Quality
- 514pgTAP assertions on the database rules, in 39 suites
- 640+Vitest tests across the two apps
- 0secret keys on the public site — it reads only through database functions that return public data
How I worked
Spec → tickets → coding agents, every decision reviewed and owned by me. 26 ADRs across the two apps, one shared glossary, and one rule for the agents — document only what the code actually does.
Status and links
- StatusIn production · 2 editions run on it
- Public sitelafossagames.com(opens in a new tab)
- CodeOn request