Gym app
gn33
gn33 is a fitness-studio booking platform. Members browse a class schedule, book spots against their subscription, and get reminders. Staff run the studio: classes, rosters, attendance, plans, users, and reporting.
Production runs at app.gn33.eu.
Who uses it
| Role | What they do |
|---|---|
| USER (member) | Browse and book classes, manage subscriptions, review instructors, control their own privacy and notifications. |
| INSTRUCTOR | See rosters for their classes, mark attendance, view their own reporting dashboard. |
| MANAGER | Everything an instructor does, plus manage classes, series, users, locations, and moderate reviews. |
| ADMIN | Full control: plans, categories, difficulty levels, app settings, legal documents, CSV import, GDPR erasure. |
Role changes take effect immediately, because authorities are rebuilt from the database on every request.
What it does
For members
- Sign up and sign in: a six-step signup wizard with email PIN verification, Google and Facebook social login, and optional two-factor authentication (email OTP or authenticator app).
- Classes: a calendar and an upcoming feed grouped by day, with filters (location, room, instructor, category, difficulty) and free-text search.
- Booking: one-click booking with an Undo action, multi-spot booking on unlimited plans, and a waitlist that promotes members when a spot frees up.
- Subscriptions: buy a plan online (Netopia), track entries used, and freeze a subscription for vacation or injury.
- Cancellation policy: a configurable cutoff, and a no-show and late-cancel strike system that can trigger a temporary booking ban.
- Reminders and notifications: emails, Web Push, and WhatsApp for waitlist promotion, class reminders, and cancellations, with per-channel preferences.
- Calendar sync: a live
webcal://feed, per-booking.icsdownloads, and Google Calendar links. - Reviews: star ratings and comments for instructors, gated by an attendance threshold.
- Privacy: a GDPR self-service page to export all personal data as a ZIP and to delete the account.
- Help center: a searchable in-app help section, translated into all five locales.
For staff
- Event management: create, edit, and cancel classes. Cancelling refunds bookings and emails members.
- Recurring series: weekly rules that generate classes on a rolling horizon, with room-conflict detection and "this class only" or "this and following" edits.
- Rosters and attendance: add or remove participants, mark attended or no-show, and keep a per-event audit trail.
- Reporting: attendance, occupancy, and no-show statistics with charts, per instructor or studio-wide, plus a client-side earnings calculator.
- Users: account status (enable, disable, expiry), role assignment, and profile management.
- Locations and rooms: CRUD with pictures.
- Admin settings: cutoff minutes, review threshold, waitlist toggle, reminder timing, schedule window, and strike policy.
- Data: versioned Terms and Conditions, and CSV bulk import of members and classes with a dry-run preview.
Architecture
The platform is three independent projects, each with its own git repository.
| Folder | Stack | Role |
|---|---|---|
gn33-app/ | Java 26, Spring Boot 4.1, Maven, PostgreSQL, Flyway | REST API under /v1, scheduled jobs, email and push delivery |
gn33-spa/ | React 19, TypeScript 6, Vite, pnpm | Single-page frontend |
gn33-deploy/ | Docker Compose, Caddy | Production stack, env examples, backup script, runbook |
Notable design choices
- Single origin: Caddy routes
/v1/*and OAuth paths to the backend and everything else to the SPA, so production has no CORS. - Single timezone:
Europe/Bucharest, usingLocalDate,LocalTime, andLocalDateTimethroughout. - Security: JWT access tokens with rotating refresh-token families, rate-limited login and 2FA, narrow projections on member-reachable endpoints, and sanitized logging of emails, phones, and tokens.
- Schema: append-only Flyway migrations, with Hibernate validating entities at boot.
- Notifications: one
NotificationDispatcherfans out to email, Web Push, and WhatsApp channels. - Deployment: immutable image tags (
ghcr.io/glwnick/gn33-{app,spa}by short SHA), single app instance by design, and a migration in progress from a TrueNAS host to a Debian Docker host.
Design and localization
- Kinetic design language: a lime primary on a deep green-charcoal ink surface, with full light and dark modes and a responsive shell. The shell has an ink sidebar on desktop and a bottom navigation on mobile.
- Five locales: en, de, es, fr, and ro, with matching backend message bundles and localized email templates. English and Romanian are the actively maintained ones.
- Branding: configured through
app.branding.*rather than hardcoded.
programmingfitness