SpotAI
An AI gym buddy for members and a management console for Indian gym owners
01 · Executive Summary
Most gym software in India is a register with a login: it knows who paid and when, and nothing about what happens on the floor. Members get nothing from it. The apps members do use are generic workout trackers that have never heard of their gym.
SpotAI is one product with two sides. Members get a coach that watches their squat through the phone camera and gives one tip per set, a workout log, an opt-in gym leaderboard and buddies to train with. Owners get live arrivals with dues flagged, UPI payments inside the member app, busy hours, a front-desk console and a trainer console that reviews what the AI says before members see it.
What makes it different: the camera never uploads a frame, every purpose (camera, clips, face, matching, chat) is a separate consent with its notice version recorded, and a member can export or delete everything from the app. Built to the shape of the DPDP Act rather than retrofitted to it.
02 · The Stack
- Member app
- Vue 3 + Vite, packaged with Capacitor 8 for Android and iOS; TanStack Query cache persisted to storage so screens paint before the network answers.
- Owner and staff
- Two Vue 3 web consoles: owner dashboard, and a staff console for the front desk and trainers.
- API
- NestJS on PostgreSQL with row-level security per gym, NATS events with an outbox, S3-compatible clip storage.
- Pose
- MediaPipe in the WebView: landmarks, rep counting and per-rep flags on device at 30 fps.
- Language models
- Only through a gateway (Ollama, Groq, OpenRouter or Gemini) behind identity redaction, a consent check and an output guard, with template fallback.
- Offline demo
- The same app with the API answered on the phone from SQLite, so partner gyms can trial it for a week with no server.
03 · System Architecture Flow
- 1Check-in
A QR from the app, the front desk, or an optional face device at the door. The visit starts a session.
- 2Pick a session
A rule over the last 7 days suggests strength, cardio, cycling or mobility, then which muscle group is most rested.
- 3Pose on device
MediaPipe tracks the squat at 30 fps in the phone's WebView. Frames never leave the device.
- 4Flags, not video
Rep counts and per-rep flags (knee valgus, depth, lean) post to the API; a cue is picked from trainer-approved templates.
- 5Trainer review
Every cue template sits in a review queue with its wrong-rate, so trainers retire the ones members mark wrong.
- 6Gym-wide signals
Logs roll up into gains, an opt-in leaderboard, buddy suggestions, and the owner's arrivals, dues and busy hours.
04 · Deep Technical Breakdown
Frames never leave the phone
The coach is a MediaPipe pose model running inside the Capacitor WebView. The API only ever receives a set: a rep count and, per rep, a map of flag type to severity. The cue is chosen from trainer-approved templates on the server, so the text a member reads has been read by a human first. Clip saving is a separate consent, off by default.
One database, many gyms, no leaks
Every table carries a tenant id and PostgreSQL row-level security enforces it. The API opens each request inside a transaction that sets the gym, so a query that forgets a WHERE clause still cannot see another gym's members. The test suite runs two gyms side by side and asserts the boundary on every endpoint.
Consent as data, not a checkbox
Each purpose is a row: status, notice version, method and time. Features read the row before they run (the leaderboard checks age, the camera checks the camera consent, reminders check the reminder consent), and the privacy centre lets a member flip any of them, export a JSON of everything, delete the account, or file a complaint that gets a reference number the gym must answer.
A demo that behaves over real days
The offline build answers the API from on-phone SQLite. The seed is a snapshot from one day, so anything date-dependent (today's plan day, check-in state, streak, this week's kilograms, days left on the membership) is derived from the saved logs and visits on every read, the same rules as the server. A week-long soak with the clock moved forward day by day showed check-in resetting each morning, streaks rising and breaking, and Monday starting a new week.
Evidence
- 179 API tests across auth, tenancy, training, consent, clips, connect, owner and load.
- Browser tests across member, staff and owner apps with WCAG AA checks on every main screen.
- ~40k lines of TypeScript, Vue and Python across three apps, the API, a model gateway and an edge agent.
- Marketing site with JSON-LD, sitemap,
llms.txtand real app screenshots, built in Astro + GSAP.