Project facts
- Client
- JoGym (a gym in Mexico)
- In production
- Since 10 August 2026
- Status
- v1.5.0, with the deployed version verifiable from the service itself
- Role
- Product, build, deployment and operation
- Scope
- Members, payments, QR check-in, metrics, overdue tracking, reminders and data purge
Context
The business is a gym that tracked members, payments and attendance across notebooks and spreadsheets. Every month someone had to reconstruct by hand who was up to date, and the answer varied depending on who reconstructed it.
Whoever was going to use the system every day is not a technical person and works standing up, at the front desk, with people waiting. That ruled out any solution requiring a computer, a long training session or a manual.
The brief also included something that is not always asked for and here it was: being able to delete a member's personal data when they request it.
The problem
If the system doesn't fit on the front desk it doesn't get used; and if it isn't used, control goes back to the notebook.
The biggest threat to a small management system is not a technical failure, it is abandonment. Any friction — opening the laptop, waiting for a load, hunting for a record across tabs — sends the person back to paper on the day they are in a hurry. And the day they are in a hurry is every day.
The second problem was trusting what is deployed. When someone reports that «something isn't working like yesterday», you need to know with certainty which version is running right then, not deduce it.
And the third was infrastructure: the site is published through a remotely managed tunnel, where local configuration has no effect at all. Editing the file that looks like the right one changes nothing, and the symptom is a healthy service that simply does not show up.
Key decisions
An installable app, not a website
Built as an installable PWA, with QR code reading from the phone camera and native browser push notifications.
Because real usage happens standing up and one-handed. An app living on the phone's home screen opens in a second; a link saved in a browser does not get opened.
The deployed version can be asked
The service exposes its version and the project keeps a disciplined changelog with semantic versioning that matches what is actually running.
Without that, diagnosing is guessing. Being able to ask «which version are you?» and get a reliable answer turns an argument about impressions into a thirty-second check.
Really delete when someone asks
There is a purge of a member's personal data, designed as a right of the data subject rather than as technical housekeeping.
In a small business, people's data piles up with no plan and nobody knows where it ended up. Building the exit from the start avoids having to improvise it the day someone claims it.
Learn how the service actually gets published
Publication goes through a remotely managed tunnel: local configuration publishes nothing, and it has to be changed through its administration interface, backing up the current state first.
It is the kind of detail that appears in no guide and costs an entire afternoon the first time. It went into the deployment procedure so that the second time costs five minutes.
A day at the front desk
The whole daily flow fits in a phone: the member arrives, checks in, and the system knows who is up to date and who owes.
QR check-in
The member scans and is registered, with no notebook and no spreadsheet.
Membership status
The system knows who is up to date, and since when.
Overdue and reminders
Notices go out over WhatsApp and push, without chasing anyone from memory.
Business metrics
Attendance and membership status, to decide with data rather than impressions.
Purge on request
A member's personal data can be deleted when they ask for it.
The solution
The interface is React with Vite, packaged as an installable PWA, with QR reading in the browser. The backend is Express over PostgreSQL, with a token session in a cookie and push notifications.
Features cover the gym's full cycle: adding and removing members, recording payments, QR check-in, overdue tracking, WhatsApp reminders, attendance metrics and on-request purging of personal data.
Delivery discipline matters as much as the code: a changelog with semantic versioning and a version you can query from the service, so each deployment is verifiable rather than announced.
Results
- In production since 10 August 2026, in daily use for member and payment control.
- v1.5.0 deployed, with the running version verifiable from the service itself.
- QR check-in straight from a phone, with no computer at the front desk.
- WhatsApp collection reminders and push notifications, plus personal data purged at the member's request.
- The full visual redesign was produced with the help of an AI-assisted design tool.
What I learned
That in software for small businesses the competition is not another system: it is the notebook. And the notebook wins whenever the app takes more than a few seconds to be ready.
That a changelog is only useful if it can be checked against what is deployed. As long as the version cannot be queried, a changelog is an intention.
And that someone else's infrastructure has invisible rules. Discovering that the tunnel's local configuration publishes nothing cost time once; writing it into the procedure meant it never cost time again.