A Product Case Study in building an Android MVP solo, with AI writing the code and requirements discipline doing the actual work.
The warm-up
I’ve been training most of my adult life — since 2005, when I came to a Pilates class for the first time. Then I tried many workouts and disciplines: Step, Aerobics, Capoeira, Hustle social dancing, TRX (I even took a certification course and taught my own TRX classes for about 1.5 months). From 2015 to 2020 I was a Zumba instructor — challenging and fun at the same time.
But out of all these disciplines, the gym is what I liked most.
Weight training always gave me that feeling of satisfaction — of work actually done. It also helped me cope with anxious thoughts in the hard moments of life. That’s why I’ve kept training in the gym for the last five years and haven’t looked for alternatives.
The human body is an amazing instrument. You can spend years exploring your own body’s reactions, capacity, and potential — simply by doing basic movements in a gym thoughtfully, and tracking weights, sets, reps, and how it all felt.

The selfish idea
I train four times a week. Weight machines, barbells for the last five years of it. (My best competition lift is a 137.5 kg sumo deadlift — I mention it because I earned it, not because it matters for this text.)
What I wanted was simple. Track my progress. Get next week’s plan adapted to what I actually did — not to what a template assumed I would do. Apps like that exist. Sort of. Some track well. Some generate plans. The adaptive part — the “buddy” part — never worked the way I wanted.
So I did the classic PM thing: turned a personal annoyance into a product scope. The honest name for this project is a selfish idea with documentation.
At the same time, I was open to new opportunities. So I let this project become both a useful personal tool and a portfolio piece — a way to show the kind of product work I enjoy most: thoughtful, structured, practical, and grounded in real user needs.
I mentioned GymBuddy for the first time here.
The constraint that shaped everything
I built it alone. No dev team, no designer, no QA. AI coding tools instead.
That sounds like freedom. It isn’t — it’s the removal of every safety net. On a normal team, unclear requirements get caught: a developer asks an annoying question, QA finds the contradiction, a designer refuses to build the fifth button variant. Working solo with AI, nobody pushes back. Cursor executes ambiguity with total confidence.
Which means requirements are the whole game. Not most of the game. The game.
The document system
Before serious code, I wrote about fifteen canonical documents. PRD. MVP Decision Log. Screen Specification Matrix (31 screens, S01–S031). Canonical ERD with table-level contracts. Enum glossary. Seed data workbook with a 40-exercise pool in the beginning, then +9 additional exercises. First-program generation rules. Weekly adaptation rules. UI component library with usage rules. A handoff checklist before any “vibe-coding” was allowed to start.
For an app with one user, this looks insane. It was the cheapest part of the project.
I had also seen enough “I vibe-coded an app over the weekend” posts to secretly hope this might be fast. A working product, a neat portfolio item, visible proof that I could turn product thinking into something real.
That illusion did not survive very long.
Very quickly, I understood that my “Blitzkrieg” would take more time than I wanted. Then something useful happened: I stopped treating the timeline as the point. I accepted the slower pace and started enjoying the process.
There were moments when the project felt like a quiet room while the rest of the world kept moving. No rush, no noise, no vague anxiety — just a clear problem, a clear next decision, and a system slowly becoming real. In the current reality, that kind of focused calm is rare.
So, back to the documentation package.
My favorite artifact is the Decision Log. Its stated purpose: freeze major MVP decisions and prevent older contradictions from returning.
Early drafts allowed three active programs per user. Later I cut it to one. Without the log, the old “three programs” assumption would keep leaking back through older documents into generated code — a zombie requirement. The log is where zombie requirements go to die.
What AI did — and what it was never allowed to do
ChatGPT was my product-logic sparring partner: edge cases, flows, documentation review. Cursor wrote most of the Kotlin.
Magic Patterns produced screen concepts.
Midjourney drew a mascot (the least useful part and the most fun, in exactly that order).
What AI never did: make product decisions. My project brief contains this instruction, written for the AI:
Do not invent business rules. Do not invent enum values, status transitions, or schema fields.
I wrote it for the AI. It works for humans too.
Three decisions worth reading
One active program per user. Multi-program support was cut and the decision frozen. Every feature downstream — dashboard, adaptation, renewal — got simpler. Scope cuts compound.
Plan and execution never mix. The recommended plan (ProgramDayExercise) and what actually happened in the gym (WorkoutSessionExercise, set-level logs) live in separate structures. Confirmed history is immutable. Weekly adaptation never edits the past — it creates a new immutable ProgramVersion for the future. This one rule is why analytics can be trusted.
The engine is deterministic — on purpose. The obvious 2026 move was to call an LLM for program generation. I chose a rules engine: same inputs, same program. Testable, explainable, free, works offline. An LLM adds real value where judgment is needed, not where a template pipeline is the honest right tool. Knowing when not to use AI is also an AI-PM skill. Maybe the rarer one.
What shipped
A working Android MVP, running on my phone. APK (watch video) , on-device — not on Google Play; that was never the MVP goal.
Onboarding and calibration. A recommended training structure. A generated program anchored to real calendar dates. Workout execution with set-level logging. History and per-exercise analytics. Weekly adaptation of the future plan. Explicit program rebuild and renewal.
The scope is narrow by design. Narrow and finished beats wide and abandoned. (For the technically curious: Kotlin, Jetpack Compose, Room, Firebase Auth, Cloud Firestore, WorkManager.)
Week one of dogfooding
The MVP has been on my phone for a week now. I test it in the gym, on my own training. Results, in order of humility:
It prescribed me my one-rep max — for a set of twelve. The starting-load logic skipped the step where weight depends on target reps. I found it mid-workout, between sets. The fix became a whole calibration section in the rules: rep-aware load derivation, plus honest numeric clamps — the first training week should feel deliberately easy, because a too-light week costs nothing (adaptation corrects it in one cycle) and a too-heavy week costs failed sets and trust.
The plank showed “30 sec” in a field measured in kilograms. Not a UI bug — a missing concept. The data model simply had no idea timed holds exist. The honest MVP answer was not to patch the label but to descope the plank until timed holds become a real, deliberate feature.
My own generator cannot build my actual training program. Nine exercises, a coach’s conditional logic, rehab constraints. And that is correct behavior — it’s a template engine for people who need a trustworthy plan, not a replacement for a coach. For myself, the plan arrives by a one-time import; the app’s real job for me is logging, history, and trends.
Narrow and finished beats wide and abandoned. Shipped and used beats both.
What’s next
The v2 feature is specified before it is built: LLM-augmented weekly adaptation. The LLM proposes the next week’s adjustments; a deterministic validator checks every proposal against the canonical exercise pool and progression bounds; the shipped rules engine is the fallback for every failure state. The spec includes an evaluation rubric, threshold-based acceptance criteria, and a four-state fallback flow.
Spec first, then build. Because I’m still a Product Manager — even when the client is me 🙂 .



Leave a Reply