Case study · Olympus Marathon In development
Seven races, one place to enter them
The Olympus Marathon organises seven mountain races in Litochoro, at the foot of Mount Olympus. This is the new site and registration platform replacing the old one: entries and payment, the secretariat's admin, results, an athlete registry going back to 2004 and finisher certificates, Greek first with English alongside.


Why there is no link
Nothing to open yet. The platform is built and tested, and goes live right after the winter race on 13 December 2026, so this page shows the build itself: the screens, the rules underneath them and why they are there.
- 7mountain races in Litochoro, each with its own entry form
- 13,089athletes in a registry going back to 2004
- ~21,000archived results, linked to their athletes
- 1,000concurrent checkouts in the load test, no place oversold
The brief
One platform instead of a site and a drawer of tools
The organiser ran the races on an old Drupal site, with registrations, results, the athlete history and the live leaderboard each living somewhere else.
The new platform puts all of it in one place the secretariat runs itself: the public site, entries and payment, approvals and bib numbers, start lists for the timing company, results with splits and a live page, the registry since 2004, finisher certificates as PDF, news, photos, sponsors and a newsletter. Greek first, English alongside, and every old URL redirects to its new page.
Registration
An entry counts only once it is paid
The form is built per edition from its own config and saved on the device as the athlete types, so a dropped connection loses nothing.
At checkout the place is held for fifteen minutes and the price is computed on the server, in SQL, never taken from the browser. Every checkout gets its own merchant reference, and the bank's callback is signed and idempotent, so a repeated or replayed callback can't pay twice or confirm a place that was never held.

Load
Tested for the morning registrations open
Capacity, bib uniqueness and duplicate entries are enforced by Postgres itself, not by application code that two requests arriving together could both slip past. Every constraint and SQL function has its own database test.
Before summer registrations open, a load test fires a thousand checkouts at the same moment. The race fills to exactly its capacity, and not one place more.
The registry
Twenty years of results, one athlete each
About 13,000 athletes and 21,000 results came over from the old system and the organiser's timing archives. The old system had often created several records for the same person, so duplicates with the same name, birth date and sex are merged, and anything uncertain lands on a review screen for the secretariat instead of being guessed.
Each athlete gets a page with every result since 2004, and a finisher can download a certificate for any race they completed.

The secretariat
The people who run the race run the site
Staff sign in with a code sent to their email, with admin and secretariat roles. They open and close registrations by date, set fees and add-ons, approve entries with registry matches suggested and the next bib number filled in, export start lists for the timing company, import teams from Excel, and manage news, race pages, sponsors, photos and the newsletter.
Every change goes to an audit log, so the question of who changed what always has an answer.

Privacy
Public lists show only what an athlete agreed to
Participant lists show only the columns each athlete consented to, and every consent is stored with the exact version of the text they agreed to. Nothing non-essential loads before cookie consent, and no secret ever reaches the browser.
Athlete accounts are optional and never required to register: an emailed code or a password shows your entries, your results since 2004 and your stats, and fills in the form for the next race.
Where it stands
October 2026 Built
Contract signed. The platform is built and tested: registration and payment, the admin, results, the registry and the imported archive.
13 December 2026 Ahead
Live right after the winter race, which runs on the old site to the end.
January 2027 Ahead
Summer registrations open on the new platform, load-tested and rehearsed with the secretariat beforehand.
Built with
Site
- Astro
- TypeScript
- Plain CSS
- Node on Railway
- Cloudflare
Data
- Supabase Postgres
- Row Level Security
- pgTAP
- Storage
Money
- Piraeus e-POS
- wrapp.ai myDATA receipts
Mail and tests
- Resend
- Vitest
- k6
Building something this size?
Tell me what your business needs to run on and I'll come back within 24 hours with a clear, no-obligation quote.
Request a quote