I Spent a Day Vibe Coding a Room Visualizer for My Photography Business. Here’s What I Learned Before Testing a Single Line of It.
Part 1 of 2
I want to be upfront about something before we get into this: as of the moment I’m writing, the app I built yesterday has never run. The code exists. The subdomain resolves. The WordPress install is clean. Today I find out if any of it works.
That’s not a disclaimer. It’s the point.
I started doing something unusual for a photographer with an MFA and no engineering background. I’ve been building software.
Not tinkering with plugins. Not configuring a booking system. Actually building a web application from scratch, using AI tools to do the technical work while I do something else: knowing what I want, evaluating what I get, and refusing to accept less.
The app is a room visualizer for my photography clients. The concept is straightforward. A client uploads a photo of the wall where they want to hang artwork - a fine art print, a pet portrait, whatever they’ve been considering. The app either accepts a manual measurement or walks them through marking reference points in the photo (a standard door, a wall outlet) to calculate approximate dimensions. They browse my Photoshelter gallery, choose a print, select mat and frame options, and the app renders an augmented reality mockup of that image on their wall. The mockup is downloadable. It also gets emailed to me automatically.
If you’ve ever tried to sell fine art prints and watched a client hesitate because they couldn’t visualize the scale, you understand why I wanted to build this. The design consultation conversation changes completely when someone already has a mockup in hand.
Where the idea to build this way came from
I didn’t invent the workflow I used today. I borrowed it from Dan Roth, editor at LinkedIn, who described it on the How I AI podcast.
Roth builds iOS apps on weekends using Claude Code. He’s not an engineer. He’s spent 15 years inside a tech company, watched how engineering teams actually work, and translated that into a two-agent setup. One agent builds. One reviews. He breaks ties.
His builder is named Bob (yes, Bob the Builder). His reviewer is Ray - a persona prompted to behave like a senior software engineer obsessed with security, architecture, and not rubber-stamping everything the builder does. The human-in-the-loop isn’t optional. It’s the design.
Roth spent some time figuring out what to call his own role in this setup. He ruled out PM (too rigid, requires keeping the whole app in your head). He ruled out architect (an architect actually knows real details). He landed here:
“All I am is a really picky customer. I’m like walking through this house and I’m telling the architect, no, I want this room blue. I know you don’t think it’s a good idea. I’m telling you, this is what I want.”
That framing clicked for me immediately. I knew what I wanted to build. I had clear opinions about how it should work and what the client experience needed to feel like. What I lacked was the technical vocabulary to build it myself. The picky customer role is a real role. It turns out to be enough. Or at least I think it’s enough (part 2 to come).
I adapted the setup for my situation. My builder is Dag. My reviewer is Norbert. I am still the picky client.
What “agentic” actually means when you’re running a photography business
There’s a version of the agentic agent pitch that implies you set something in motion and come back to a finished product. That’s not what happened today.
The process took most of a day. Some of that was because I was doing other things in parallel - sessions to edit, emails to answer, the actual photography business continuing to exist. That’s the appeal of the setup: Dag works while you’re occupied elsewhere.
But this particular workflow has human handoff points built in by design. Dag builds to a milestone and stops. Norbert reviews and either approves or requires changes. The notes between them pass through me. When other work pulls your attention, it’s easy to miss the moment when the build is waiting on a review, or when Norbert has signed off and Dag is ready to proceed.
One thing I didn't expect: Norbert flagged real issues throughout the process. Not rubber stamps with minor suggestions - actual pushback that sent Dag back to revise. The fact that this happened within the same Claude application, with the same underlying model, just with different instructions, is worth sitting with. The tool isn't agreeable by default. The instructions determine the behavior. That's the whole argument for building this kind of structure in the first place.
This isn’t a flaw. Norbert exists precisely because unsupervised building is how you get code that looks finished but has real problems underneath. The handoff friction is intentional. Reading what Norbert flags, understanding why Dag made a particular technical decision, following the back-and-forth - that’s where the learning happens. I’m not trying to learn to code. But I am trying to understand enough of what’s being built to evaluate it. That’s a different skill, and it compounds.

The honest description of agentic work for a solo business owner isn’t “it runs while you sleep.” It’s “it works in chunks between your attention, and your attention at the handoff points still matters.”
The platform constraint that turned into better architecture
My original plan was to embed the room visualizer directly into my Squarespace site. That didn’t survive contact with reality.
Photoshelter - where I host both my fine art galleries and client proofing - only supports API keys for WordPress integrations. Squarespace isn’t on the list. The app needed Photoshelter access to pull gallery content, so Squarespace was out.
Unfortunately, we only provide API Key for WordPress for the Photographer's account
I have a hosting account with InMotion Hosting that I use for my custom domain. The fix was straightforward: spin up a dedicated WordPress install, point a subdomain at it via an A record on the Squarespace-hosted domain, and put the app there. The subdomain is visualizer.michaelklothphotography.com. It’s branded. It’s separate. It resolves.
What I didn’t fully appreciate until I was already committed to it: this is probably the right architecture regardless of the Photoshelter constraint. Squarespace is already slower than I’d like. A room visualizer with image upload, canvas rendering, and API calls would compound that load on every page that shares the domain. Isolating the app on a separate install protects the main site’s page speed, which matters for SEO and for the client experience on michaelklothphotography.com.
The workaround turned out to be the right answer. That happens more often than the planning-first approach would suggest.
One thing worth naming explicitly
The workflow I used today didn’t come from a photography forum. It didn’t come from a PPA webinar or a photography educator’s course. It came from a podcast about building with AI tools, hosted by and for people who are figuring this out in real time across industries.
I’m not saying that to be critical of photography education. I’m saying it because the photographers who are moving fastest on this aren’t necessarily the ones with the deepest photography networks. They’re the ones paying attention to how people in other fields are solving adjacent problems.
The How I AI podcast is one place to look. There are others. The instinct to look outside the industry for methodology is itself worth developing.
Part 2 is forthcoming, and I genuinely don’t know what it will say.
Today I will configure the WordPress install properly and drop the code in. Both Dag and Norbert signed off on the final build. That’s a good sign. It is not a guarantee.
If it works, Part 2 is about what a room visualizer actually does for the print sales conversation, and whether a day of parallel attention was a reasonable investment.
If it doesn’t, Part 2 is about that. Which, honestly, might be more useful.
If you want to hear the Dan Roth episode I referenced, I linked to “How I AI - Dan Roth” above. His newsletter is called Forward Deployed Editor.


