Warriors Gym membership system
One API and three apps for a real gym, covering members, plans, payments and QR check-in at the door.
A The problem
A gym needed registration, membership plans, payments and attendance in one place, usable at the front desk, on the gym floor, and from members’ own phones.
B The outcome
An Express and PostgreSQL API with 44 documented endpoints, a React admin panel, a staff app and a member app. 99 tests run against a real PostgreSQL. It’s a public demo you can sign in to, with the data reset every night.

Approach
One API, three clients
Staff use a React admin panel at the desk and an Expo app on the gym floor for QR check-in and payments. The staff app keeps working when the connection drops. Members get their own app with workout videos, membership status, payments and attendance, in English, Amharic and Tigrinya. Both mobile apps also build for the browser, which is how the landing page shows them live.
Locked down by default
Admin sign-up needs an invite code, tokens expire, password hashes are never returned by any query unless a password is being checked, and the auth routes have their own rate limit. Schema changes are reviewed migration files instead of sync(), and one test fails if the OpenAPI spec and the routes disagree.
Built to survive free hosting
The API runs on Render’s free plan, the database on Neon, and the four front ends on Cloudflare Pages. A scheduled job keeps the API awake on a route that never touches the database, deploys wait until the new commit answers, and the demo data resets nightly. The demo logins are locked and payments are simulated, so anyone can poke at it safely.
What I’d do next
Wire in real payments through Chapa (the client exists but isn’t connected), add Playwright tests for the three front ends, move uploads to object storage, add error reporting, and support more than one gym.
Screens



