All work

Personal trainer — site + agenda + FitLab

Bookings that respect the trainer's own calendar, plus a client area and a cockpit for his business.

Stack:
  • Astro
  • React
  • React Three Fiber
  • Cloudflare Workers
  • Cloudflare D1
  • Google Calendar API
  • Resend
  • Workers AI
Launch video · 9:16
  • ≈45API endpoints for booking, admin, client area and cockpit
  • 24SQL migrations on Cloudflare D1
  • €0monthly hosting: Cloudflare and Resend free tiers

Bookings that bend around his own calendar

One booking engine shared by the site and a cron worker, his Google Calendar as the source of busy time, one D1 database, a client area and a cockpit for the business.

Tap a block to see what it does.

  • Input
  • People
  • Logic
  • Data
  • Output
  • Infrastructure
What comes in
Shared engine
One database
What goes out

Input

One-page site

Astro SSR on Workers with React islands. The booking wizard asks the server for free slots; the 3D barbell loads only on desktop without reduced motion.

  • Astro
  • React
  • React Three Fiber

Hands to Booking engine

The training section of the site, a frame from the desktop recording

The problem

A personal trainer booked his clients by hand, over messages and phone calls. He wanted a booking system of his own, with no subscription tool and nothing new to learn: when he blocks time in his Google Calendar, that slot disappears from the site.

What I built

  1. I split the code into a pnpm monorepo: the site, a cron worker and a shared booking engine used by both.
  2. I computed slots on the server from his working hours minus his calendar's busy times, stored every time in UTC and converted it in one tested module.
  3. I added a client area behind an email link and a 6-digit code: intake form, measurements, training programmes, workouts with set logging, programme as PDF.
  4. I built a cockpit for clients, packages and payments, where a voice note becomes draft entries (Whisper, then Claude) that he confirms before anything is saved.
  5. I put a procedural 3D barbell in the hero, downloaded only on desktop when the browser is idle; phones get a CSS poster.

The hard part

Preventing double bookings without transactions. Each booking is one insert guarded by NOT EXISTS, which D1 runs one at a time, and the calendar is checked again just before writing. Clock changes are covered by tests on both daylight-saving switches.

Result

In production on the client's own domain, on free Cloudflare and Resend tiers. The same engine became the base of two later client sites.

My role

Solo client project. I gathered the requirements, chose the architecture, reviewed and tested every flow against a go-live checklist and set up domain, DNS and secrets; Claude Code wrote 219 of the 220 commits.