The choices I would be asked about in an interview, and the reasoning behind each one.
Two models, two jobs
GPT-4o only looks at the photo. Claude only writes the plan. Neither does both.
Why: Extraction and generation fail differently. Keeping them separate means a bad room reading is visible in the analysis before it contaminates the plan, and either model can be swapped without touching the other.
A structured report, not a wall of text
The language model returns typed fields, parsed into a DesignReport model. They cover layout recommendations, a colour palette of name and hex pairs, and decoration ideas.
Why: Prose can't be rendered as swatches, saved to a history list, or matched against a product catalogue. Fixing the shape at the model boundary is what makes the rest of the app possible.
Every integration has a mock behind it
With no API keys present, the vision model, the language model, and the furniture API all fall back to mock responses, and the full flow still runs.
Why: An alpha test or a supervisor demo shouldn't depend on a key being live and in quota. The failure I was most likely to hit was the one I designed for first.
The client finds its own backend
The API base URL resolves in a fixed order: a compile-time --dart-define, then .env, then a platform default, which is 10.0.2.2 on the Android emulator and localhost everywhere else.
Why: I was switching between Chrome and an emulator constantly. Editing a config file every time was a step I would eventually forget, so I removed the step instead of trying to remember it.
Provider over a heavier state library
Provider, with a notifier per concern.
Why: One developer, a linear flow, and no code generation step. State management was never the bottleneck in this project, and something bigger would have added a build step it didn't need.
Rebuilding rather than patching
Partway through, I deleted the codebase and rebuilt it leaner.
Why: The first version had grown organically until I couldn't hold it in my head or explain it in a supervisor meeting. Starting again with what I'd learned cost less than continuing to work inside something I no longer understood.