myFitZone
myFitZone
Booking and business management for independent personal trainers and boutique gyms. Scheduling, memberships, payments, and a client app, replacing WhatsApp threads and spreadsheets.
- date
- status
- active
- stack
- #typescript#react#react-native#expo#node#express#supabase#postgresql#stripe
- links
- live
The problem
Independent trainers run their business out of a chat app: bookings arrive as messages, cancellations get lost, credits are tracked in a spreadsheet, and payments are chased by hand. myFitZone replaces that with one system the trainer and their clients share. Trainers publish availability and recurring slots, clients book from their phone, and memberships, credit packages, waitlists, and payments are handled in the same place.
It ships in English and Greek, with three roles: platform admin, gym owner or trainer, and client.
What it is made of
A Yarn workspaces monorepo with a shared package of Zod schemas that every side of the product validates against, so the API, the admin, and the mobile app agree on one contract.
| Part | Stack |
|---|---|
| API | Node, Express, TypeScript, Zod-generated OpenAPI, Socket.IO, Stripe webhooks |
| Admin (owners and trainers) | React 19, Vite, Ant Design, TanStack Query, drag-and-drop calendar |
| Mobile (clients and owners) | Expo, React Native, Tamagui, Reanimated, offline query cache |
| Data and auth | Supabase Postgres with row-level security, RPCs, pg_cron, Google and Apple sign-in |
| Notifications | Firebase Cloud Messaging and Expo push, reminder fan-out on a 30-minute cron |
| Delivery | GitHub Actions for migrations, staging and production, DigitalOcean App Platform |
Engineering that mattered
- Timezone-first scheduling. Every gym has its own timezone and every slot, cancellation window, and reminder is computed in it. The test suite runs the scheduling matrix across four timezones so a daylight-saving change cannot double-book anyone.
- Waitlists that promote themselves. When a booking is cancelled inside the rules, the next waitlisted client is moved in and notified without the trainer touching anything.
- Credits and memberships as first-class ledgers. Packages with expiry, membership plans, walk-ins, and owner payouts are recorded as auditable entries rather than mutable counters.
- Owner onboarding wizard. Gym profile, joining method, and cancellation policy are set up in one guided flow, with an in-app tour for the admin afterwards.
- Billing that survived a provider change. Platform subscriptions moved from Stripe to another provider and back; the migration history is intact and the webhook layer is isolated so the switch did not touch the booking domain.
By the numbers
- 33 API route modules, 52 mobile screens, 59 admin pages
- 52 database migrations, about 116 test files across API, admin, shared, and mobile
- In active development since November 2025, currently at version 1.6
My role
Designed and built end to end as a solo project alongside a full-time role: product, architecture, all three codebases, the database, billing, and the release pipeline.