Case Study · SaaS Platform

TrotBritain Race Management Platform

A national governing body, running on spreadsheets. We replaced the lot with a single platform (public site, member portal, admin back-office) shipped for the 2026 season opener.

Client
TrotBritain
Sector
Sports Governance
Project Type
Full-stack SaaS

At launch · 2026 season

1 Mar
Licence release ran on the new platform
203
Horses migrated
77
Licences issued (45 holders)
£13,250
Processed through Stripe

The problem

Every Monday morning, TrotBritain staff spent three or four hours typing the weekend's race results into a spreadsheet, recalculating ratings by hand, cross-checking championship points across six leaderboards, then emailing the updates to the web team to publish.

The master spreadsheet was the source of truth, and the single point of failure. It couldn't be opened on a phone at a race meeting. It had no audit trail. Two people editing it at once meant a lost afternoon.

Around it sat a separate WordPress site, manual licence applications by email, payments by bank transfer, flu vaccination dates tracked nowhere in particular, and championship tables that lagged the actual standings by a week.

The brief: replace all of it with one platform. Retire the spreadsheet permanently. Cut Monday morning to under an hour.

What success looked like

Three top-line targets:

  • Zero spreadsheets after launch. The website becomes the sole source of truth.
  • Monday morning under an hour, with results entered in under two minutes per race.
  • Live for the April 2026 season, with all licensing, payments and championships running end-to-end on day one.

How we approached it

One early call shaped everything: one app, one database, one login.

The old setup had a WordPress public site and a staff portal as separate systems with separate accounts. We merged them into a single Next.js application backed by Supabase Postgres.

Staff log in at the same domain the public sees. When they finalise a race, the data is already on the public site by the time the database transaction commits.

That decision killed an entire class of integration bugs (sync drift, stale caches, divergent schemas) before they could exist.

It also meant Postgres row-level security became the only authorisation model we needed, instead of duplicating permission logic across two stacks. RLS on every table; the service-role admin client used only where bypass is genuinely required.

What we built

The results engine

The Monday morning bottleneck. Every horse in a race appears on a single page with two fields per row: finishing position and finishing time. Everything else (owner, trainer, driver, current rating, prize money) is pre-populated from the race card.

Clicking Finalise Race runs a single transaction that distributes prize money, updates lifetime earnings, recalculates each horse's Sulky or Monte rating, awards points across all six championships, increments seasonal run counts, and publishes the results to the public site. One click. No spreadsheets. Designed for under two minutes a race.

A Ratings Free toggle excludes individual horses from rating changes for promotional or invitational races, matching how the sport actually operates.

Dual ratings & six championships

British trotting runs two disciplines (Sulky and Monte). Every horse holds two independent ratings, one for each.

The ratings start equal at season open and diverge through the year as horses race. The system applies the right formula to the right race type automatically; staff never pick a rating manually.

One horse, two ratings
Horse record
Sulky rating
Used in Sulky races
Monte rating
Used in Monte races
Six championships, two scoring systems
Standard points
10 / 6 / 4 / 3 for 1st–4th
  • Owner
  • Trainer
  • Sulky Horse
  • Monte Horse
Variable points
Scaled to field size (winner of 14 = 14 pts)
  • Sulky Driver
  • Monte Rider

Qualifier races award no points.

End-of-season is one click: rating deduction across every horse, seasonal run counts reset, 50% of driver points carried forward, new season activated.

Licensing, ID cards & payments

Licence applications happen on the website end-to-end. Application form, Stripe checkout, admin approval, sequential licence-number generation, and a one-click photo ID card PDF (@react-pdf/renderer) ready to print. Renewals and additional applications reuse the existing photo and pre-fill personal details. Driver silks replace the default icon on driver ID cards.

Licence types (prices, categories, horse-access flags) live in a database table the admin can edit at any time without a deploy. iPhone HEIC photo uploads convert to JPEG client-side via heic2any so they work in every browser.

Owners buy race-entry credits in Stripe-driven packages (5/3/1 runs at £500/£300/£100). Visiting international horses pay £250 to register and create a pending run-purchase on approval. Stripe promotion codes are enabled on every checkout. Bank details captured on each run purchase are editable inline by admin.

The public site

Every public page reads from the same live database the admins write to. Results browser, race cards, horse / driver / owner / trainer profiles with full history tables and season statistics. Crucially, historical results record the owner, trainer and driver as they were at the time of the race, so a horse changing hands doesn't rewrite history.

The member portal

Licensed members get their own self-service area: apply for or renew a licence, download their photo ID, manage their horses, upload flu-vac certificates, request transfers of ownership or training, buy run packages, and enter races with a preferred driver (or a "TBC" option, for when the booking isn't done yet).

A hard problem we solved: keeping expired horses out of races

British Horseracing Authority rules say a horse with an expired flu vaccination cannot race. Under the old setup, that was enforced by a member of staff remembering. We needed it built into the platform, and built into it everywhere, not just on one form.

The fix is a three-layer defence:

  1. Form layer. When an owner picks a horse to enter, ineligible horses are greyed out and unselectable. Most users never hit anything else.
  2. Server layer. The submission action re-checks the vaccination expiry against today's date in Europe/London time, regardless of the user's browser. A user with the form open from yesterday can't submit it today if the vac lapsed in between.
  3. Admin promote layer. When staff click accept entry, the admin flow runs the same check a third time. Vaccinations can lapse between submission and approval; the platform doesn't trust state it captured earlier.

Three layers because each catches a different failure mode. The UI prevents accidents, the server prevents tampering, and the admin gate catches drift.

The reactive side is matched by an active one: a cron job sends reminder emails to owners and staff at 14, 7, 1 and 0 days before expiry. Owners and trainers can upload new flu-vac certificates from their dashboard for admin review. The platform doesn't just block expired horses; it works to keep them eligible.

At launch

Phase 2 (the full platform replacing the spreadsheets) opens for the 2026 season. The 1st March licence release ran on the new system, and the platform is live and operational as the season begins.

What's true on day one:

  • The spreadsheets are retired. Every operational data point (horses, owners, trainers, drivers, licences, vaccinations, fixtures, integrity tests) was migrated into Postgres and is now edited only through the website.
  • The 1st March licence release ran on the new platform. Applications, Stripe payment, admin approval, sequential licence-number generation, and one-click photo ID PDF, all end-to-end through the website. No email or bank-transfer fallback.
  • Race cards, fixtures and championship pages are publishing live from the same database staff edit. No second system to sync, no email handoff to a web team.
  • Flu-vac enforcement is active across all three layers, with the reminder cron running on schedule.
  • The Stripe pipeline is open for licences, run packages, visiting-horse registrations and race-naming rights. The full payment surface, day one.
  • Public pages are holding under the 3-second target through the pre-season warm-up traffic.

What we'll measure in season one

The launch numbers above are the proof of shipped. The proof of working comes from a full season of operational use. We'll be tracking, and updating this page in autumn 2026 with:

  • Average results entry time per race, against the under-two-minute target.
  • Publishing time from race finalise to the public site, aiming for within seconds.
  • Total Stripe volume across licences, run packages, visiting-horse fees and race-naming rights.
  • Public pages stay under the 3-second target during race-day traffic surges.
  • Number of operational issues that needed a manual workaround, target zero.

The bespoke system that Calm Ventures have built for us has revolutionised our sport and brought it from working on spreadsheets to a modernised database.

Joseph Ripley, TrotBritain

What was a stack of spreadsheets, email chains and manual recalculations is now a single live platform, built to brief and shipped on time, open for business as the 2026 season begins. We'll update this page with season-one results in autumn.

Published April 2026 · At launch

Stack

  • Next.js 16 · TypeScript · React 19 Single app for staff and public, no separate front-ends to keep in sync.
  • Supabase Postgres, Auth, Storage, RLS Row-level security on every table is the only authorisation model, instead of duplicate permission logic across two stacks.
  • Stripe Checkout & promotion codes End-to-end licensing, run packages, visiting-horse fees and race-naming rights, with no bank-transfer fallback.
  • AWS SES Transactional email for entry confirmations, transfer requests, and the flu-vac expiry reminder cron.
  • @react-pdf/renderer, heic2any One-click photo ID cards and horse-history exports; iPhone HEIC uploads convert client-side so they work in every browser.
  • Tailwind CSS One design system across public site, member portal and admin back-office.

Delivery

  • Live: April 2026 season open
  • Engagement: Phase 2 build, end-to-end
  • Hosting: Vercel + Supabase
  • Site: trotbritaingb.com ↗

Got a platform that's outgrown its spreadsheets?

We build bespoke software for businesses that need more than off-the-shelf, from governing-body platforms to scheduling SaaS. Let's talk.

Book a Consultation See More Work