Booking SaaS, in production since July 2026
A booking website for every outdoor activity operator: their brand, their calendar, their Stripe account. One Next.js app runs all of them.
- 2,390commits in 93 days
- 8,547tests, Postgres in CI
- 100SQL migrations
dewex.io, 1 of 4
Sell on your own website.
The front door. An operator signs in at app.dewex.io with Google or a magic link, gets a site from the Default template, adds activities by hand, from a description or from a URL, and connects a Stripe account. The site is live at {slug}.dewex.io or on a custom domain with HTTPS issued on demand.
Studio, 2 of 4
A website builder, no code.
Every tenant site is a validated JSON document rendered by 75 section components in 18 families; the LLM never writes HTML. Studio edits it section by section with a desktop and a phone preview. Saves are versioned, a conflict is a recoverable state, and the translation worker's writes are rebased silently because it is the only other writer. Content is translated asynchronously into 20 other locales, never on the request path.
- 75section components
- 18section families
- 21site locales
Client site, 3 of 4
Their site, native booking.
The site Studio builds, with the booking engine inside it: a calendar of open departures, a seat hold, the Stripe payment element. hold_seats is one guarded UPDATE on the departure row; the second traveler on the last seat waits on the row lock, re-evaluates and gets a clean sold_out. The payment is a direct charge on the operator's Stripe account, the commission snapshotted in integer cents when the intent is created.
- 2→1concurrent holds, last seat
- 15 minhold TTL, swept every 60 s
- 6%Starter fee, none from Pro
Back office, 4 of 4
One place to run the business.
Departures calendar with capacity per slot, bookings, customers, payment status driven by Stripe webhooks: events claimed by id with a takeover window, status transitions compare-and-swap. Bilingual, phone-first, every query scoped by tenant, row level security on all 48 tables with zero browser-facing policies. Deployed on one VPS behind a health-gated deploy that fails loudly; rollback adds one commit.
- 48tables, all under RLS
- 16Stripe event types handled
- 1commit to roll back


