Maestro: the training app I designed and built end to end with AI
- Period
- 2026
- Disciplines
- Applied AI, Design System, Product Strategy

The gym apps I use are bad, and Maestro was born out of that frustration. It is a training app that connects personal trainers and their students: the trainer builds the routine and follows the progress, and the student logs every set on their phone. In October 2026, 3 trainers and 17 students use the app for real.
It was my first native app, built on my own starting in July 2026, from the design system in Figma to the Flutter code. I am not a developer. The code was written by AI agents that I created and orchestrated, and the product decisions this case tells are mine.
Learning before shipping
The project started with a choice of goal. There were two on the table: set up the app store publishing pipeline right away, or learn Flutter with no store deadline. I took the second one. A new stack costs weeks before it reaches the store, and I would rather understand what I was building than chase a date.
Until then, every mobile app I had made was a PWA. I chose Flutter because I had already designed two apps in it. From the competitors I took a reference of what a training app needs to solve; the visual side did not come from them.
Two constraints shaped the rest. Body measurements are health data, sensitive under Brazil's data protection law (LGPD, art. 11), so the database lives in São Paulo and consent is part of the product flow. And the app's AI has a ceiling: US$ 30 a month.
The decision to let the link start from either side
In the first design, only the trainer could invite. A student who wanted to bring their own trainer into the app had no way to do it. On July 27 I decided to mirror the invite on both sides, with no approval step: either one could call the other and the link was made.
Four days later I distrusted my own solution and asked: "wouldn't it be easier... to have a fixed code... or is that risky?". The fixed code became an address. Typing someone's code sends a request, and whoever receives it approves. That walked back the "no approval" of July, and the old codes that had not been used yet stopped working.
The other half of the decision came on August 20. A trainer can register a student's profile, with measurements, before the student has an account. Out of three proposals, I chose a hybrid where the student decides when they come in through the code: without their yes, the measurements are deleted and stay with no one.
I accepted a limit along with it: someone who never redeems the code still doesn't know they exist in a database. And the decision touched both sides. The student gained their own path to the trainer, and the trainer lost the automatic link they had before.
The decision not to let the AI prescribe load in the dark
Maestro's AI helps the trainer build the student's workout. The first rule I gave it was about load: with no training history, it suggests no weight at all. With history, the load shows up as an explicit suggestion, because, as I put it back then, "we have good days and bad days of training and you can't always keep it up".
The second rule changed after a test of mine. The old version refused any health topic, and I asked for a "hypertrophy workout focused on lipedema". The rule would have blocked the request, coming from exactly the person who most needs a workout planned around their condition. I corrected it: "the disclaimer should be that it needs the advice of a professional".
Since August 8, a health condition is an input to the workout. The AI uses what the person shares as context and still refuses diagnosis, lab reports, medication and diet. When in doubt between refusing and adapting, it adapts.
The AI also never saves anything on its own. The chat writes nothing to the student's workout, and the draft it builds lands on a review screen for the trainer. I also chose three product limits: the answer arrives whole, with no streaming, because the load filter needs to read all of it before showing it; leaving the screen ends the conversation; and each person gets 20 messages every 24 hours.
As of October 2026, none of these limits has drawn a complaint. The cost stayed far from the ceiling: in the first measurement, in August, it was US$ 0.78 over 30 days, 2.6% of the budget. Charging for the AI is logged as an open question, because without usage data any price would be a guess.
The decision to give each token the same name in Figma and in code
Since August 2, Figma uses the literal name the token has in the Dart code, and an automated test checks that the two match. On August 13, all 20 tokens checked matched. For divergences, I decided that the code wins: Figma gets corrected until it catches up with the app.
On August 26 I made a round of choices in the system. I created a new spacing step and declared four tiny spacings as exceptions, with the reason written in the code. And I removed the glass axis from the input after asking "isn't that an inconsistency?".
In the same round, I had the CTA button created against the agent's recommendation. It wanted to treat the case as a bug, based on a project rule that was out of date: the code had already changed, with the contrast measured. My choice closed a debt the code itself declared.
Measured across the component pages, Figma has 1,107 spacing properties bound to tokens and 57 without one, 55 of which are the declared exceptions. The test checks only the token's name; the value is left out, and in October there were still open divergences. I would rather write that down than say everything matches.
The decision to take Edit and Video out of the menu
On September 9 the first complaint from the field came in: a trainer couldn't upload the exercise videos. My read was direct: "the card needs to have those options outside. As buttons." I asked for three proposals and chose a mix of two of them, where Edit and Video leave the menu and become buttons on the card.
I accepted two losses. The card stopped telling apart an exercise that still has no video from one that already has it, and a gesture that starts on top of a button can't drag the block. The direct shortcut to upload was left out: uploading a video used to take five taps and now takes two.
Credit
I made Maestro end to end, with the support of AI. I am not a developer, so I need AI to write the code. I was the one who orchestrated everything: I created the agents that wrote the code, the guardrails that hold those agents, and the evals that check the result. Even the project's decision log was written by an agent, and the decisions recorded there are mine.
The guardrails I defend the most are four. A test checks that token names match between Figma and code. A security and LGPD audit looks for leaks of confidential data. A check takes care of code quality. And there are safeguards for people with health conditions when the AI builds the workout.
What I would do differently
If I started today, I would put AI at the center and design the experience from there, with a more conversational app, closer to an assistant. It is my own bet, watching how the use of apps has changed after AI in people's everyday lives.
The trainer's review would stay. The topic is sensitive, and you can't remove the review 100%. What would change is the AI's reach, which would go into assessment, insights and planning. That is where I want to take Maestro.
loading comments...