Live capacity filtering
Availability is computed against confirmed bookings at query time, not cached from the last write, so a trip that fills drops out of discovery instead of accepting a seat it no longer has.
ESTGMAM
A two-sided marine tourism marketplace, built as one responsive web platform: Saudi captains list yacht trips, travellers book them, and live capacity removes a full trip from view before the same seat can be sold twice.
Double bookings
Capacity is checked against confirmed bookings at query time, not after the fact.
Payments through Moyasar
Every booking settles through the licensed Saudi gateway, not a payment path we built ourselves.
Applications, one platform
Customer, captain and operator consoles — responsive web apps installable as PWAs, not native store builds — on one source of truth.
Concurrency architecture
Stateless serverless rendering over pooled database connections, with availability resolved per request, so a booking spike is absorbed rather than queued.
THE CHALLENGE
A marine trip has a hard capacity and a fixed departure time. Overselling one is not a billing error to reconcile next month — it is a family turned away at the marina, and a marketplace is blamed by both sides of a booking it brokered.
THE APPROACH
One platform behind three front doors: a customer app for discovery and booking, a captain dashboard for the business behind it, and an internal console for the operator. All three are responsive Next.js web apps installable as PWAs rather than native store builds, so one fix reaches every device at once. Sessions come from Supabase Auth with one-time-code sign-in, scheduled jobs on Vercel release unpaid holds and move trips between states without anyone pressing a button, and a single shared client store keeps discovery, seat selection and payment reading the same numbers.
Availability is computed against confirmed bookings at query time, not cached from the last write, so a trip that fills drops out of discovery instead of accepting a seat it no longer has.
Discovery, seat selection and payment run as one flow over a single shared client store, so the screen never re-renders itself out from under a traveller mid-booking and the seat count cannot disagree with itself between two panels.
A dashboard that answers the questions an operator actually asks: what is booked today, what has been earned, and what is still to be settled.
Accounts are held by Supabase Auth with one-time-code sign-in, KYC gates a captain’s listings rather than trailing behind them, and every booking settles through Moyasar, the licensed Saudi gateway, rather than a payment path built in-house.
A private super-admin panel where the platform owners approve KYC submissions, set and adjust commission rates, and reconcile what was collected against what each captain is owed — the work a marketplace has to do on itself, kept off the two public apps.
Scheduled jobs on Vercel expire unpaid holds, so a seat someone stopped paying for returns to inventory instead of sitting reserved, and move trips between states as their departure passes. This is the housekeeping that decides whether availability is still true an hour later.
BUILT WITH
INSIDE THE SYSTEM
Screens from the running product, not a redesign of it.

THE OUTCOME
The platform now runs both halves of the transaction. Travellers book trips that are genuinely available, and captains can see what they have sold and what they are owed without asking anyone. Because capacity is settled at the source rather than reconciled afterwards, the double booking that a marketplace of this kind usually learns to apologise for does not arise. The architecture is sized for the spikes this market actually has — a holiday weekend, a promoted trip — with rendering that scales out per request and availability resolved against the database rather than a cache that can go stale under load.
That is the problem we solve most often. Tell us where the numbers stop adding up.
Start a conversation