← Blog

Building a production product solo with Claude Code

Visiban is a production-quality, fully open-source Kanban application. It has a real-time WebSocket board, a complete card movement audit trail, five OAuth providers, RBAC with five roles, a Helm chart with PodDisruptionBudgets, 90%+ backend test coverage, and a twelve-stage CI pipeline that includes SAST, migration safety checks, and a dedicated AI code reviewer.

I built it solo. It took six weeks. I used Claude Code.

This is an honest account of what that workflow looked like — what worked, what needed adjustment, and what I’d do the same way again.

What Claude Code is

Claude Code is Anthropic’s CLI for agentic software engineering. You run it in a terminal inside your project and it can read files, write code, run tests, execute shell commands, and search the codebase. It’s not an autocomplete tool. It’s an agent you direct at problems.

The key difference from a chat-based AI: it operates with persistent context in your working directory. It can read your CLAUDE.md project instructions, follow your conventions, run your test suite, and produce changes that actually integrate with the existing codebase rather than being correct in isolation.

The agent workflow

The most important structural decision I made was to treat Claude Code as a team, not a single assistant. Different problems need different lenses, and a single agent asked to do everything tends to optimize for what it’s currently focused on rather than looking across concerns.

I defined a set of specialized agents for distinct responsibilities:

  • architect — reviews the technical approach before any code is written; asks the questions a senior engineer would ask about coupling, reversibility, and migration risk

  • security-review — OWASP Top 10, IDOR prevention, serializer field exposure, WebSocket broadcast safety

  • perf-check — N+1 query detection, missing select_related/prefetch_related, transaction boundaries

  • rbac-check — authentication gates, board membership checks, minimum role enforcement per HTTP action

  • migration-check — destructive operations, NOT NULL without default, column renames that should be three-step

  • broadcast-check — verifies that every board mutation broadcasts correctly and is deferred with transaction.on_commit()

  • regression-check — stale mocks, permission boundary changes, broken test suites before any MR opens

  • changelog — fragment file creation; the CI changelog-check job blocks without it

Each agent runs in its own context with tools scoped to what it needs. The architect sees the full codebase and can ask questions. The security reviewer reads views and serializers. The migration checker reads models and the migrations directory.

This keeps each agent focused and avoids the “helpful but wrong” failure mode where a general-purpose agent makes a change in one layer that quietly breaks invariants in another.

Voice of Customer panels

One of the more unusual practices I developed was running a VoC (Voice of Customer) panel before designing any user-facing feature.

The project’s CLAUDE.md defines four personas: Maya (project manager, values speed and overview), Jordan (senior engineer, lives in the board all day), Sam (designer, occasional user), Alex (IT admin, manages provisioning). Before building a feature, I’d run /voc all <feature description> to get scored feedback from each persona.

This sounds like theater, but it consistently caught solo-builder drift — the tendency to build what’s technically interesting rather than what the primary user actually needs. Jordan always wants keyboard shortcuts and full history; Maya wants fewer clicks to the information she needs; Sam wants the UI to be intuitive on first contact. When all three are pushing in different directions, the design space becomes visible in a way it isn’t when you’re just coding.

The VoC output went into the architect prompt, so the technical design questions were weighted by actual user priorities rather than just technical correctness.

The CI reviewer stage

The most structurally interesting decision was adding a Claude Code reviewer stage to the CI pipeline.

Every merge request triggers a GitLab CI job that runs the same security, RBAC, performance, and broadcast-wiring checks that were applied during development. The reviewer has access to the diff and the full project context — CLAUDE.md, the conventions, the patterns the codebase has established.

What this means in practice: the codebase reviews its own MRs. It knows the project’s patterns and flags deviations from them. A new view that’s missing a board membership check gets caught. A serializer that exposes a field it shouldn’t gets caught. A card mutation that’s missing transaction.on_commit() on the broadcast gets caught.

This wasn’t a substitute for human review — it was a compensating control for not having a team. The quality bar it established was consistent in a way that human review from a solo developer is not.

NB! Claude Sonnet, can at times, act like a feral cat. While I used GitLab CI & SonarQube to reign in Claude’s freewheeling tendancies, I HIGHLY recommend having a third party tool access the committed code.

Domain expertise as context

Two decades of experience across sales, engineering, and operations went into the CLAUDE.md files. Not just technical conventions — the actual domain model: what a card movement audit trail needs to capture, why transaction.on_commit() matters for WebSocket broadcast, why per-seat pricing is the wrong model, what “WIP limit” means to a practitioner.

The difference between an AI agent with shallow context and one with deep domain context is the difference between code that’s syntactically correct and code that’s architecturally correct. The former is easy. The latter requires that the agent understand why the code is structured the way it is, not just what it does.

Investing in well-maintained CLAUDE.md files — project instructions, per-directory instructions, explicit architectural decisions and the reasons behind them — was one of the highest-leverage things I did in the project.

What worked

Consistent quality gates. The combination of specialized agents, a well-defined CLAUDE.md, and a CI reviewer produced consistent code quality across the entire twelve-week build. The last commit has the same security posture and test coverage as the first.

Stakeholder simulation. The VoC panels prevented the product from becoming a tool built for engineers by an engineer. The personas kept the design honest.

Catching things early. Security and performance issues caught before merge don’t become technical debt. The migration safety agent prevented at least three migrations that would have been problematic under zero-downtime deploy requirements.

Speed without shortcuts. Twelve weeks for a production-quality, fully open-source application with this feature set would have been ambitious for a small team. Solo, with conventional tooling, it would have required significant scope cuts. With Claude Code, the scope stayed intact.

What needed adjustment

Agents start fresh. Each agent invocation has no memory of prior sessions. It knows what’s in the codebase and what’s in CLAUDE.md, but not what decisions were made in previous conversations. Early on I had to re-explain context that I thought was established. The solution was to make that context explicit in CLAUDE.md rather than assuming it was “known.” Every architectural decision worth preserving needed to be written down.

Pre-release audits don’t converge. Running a full pre-release audit (/pre-release full) more than twice on the same codebase produces diminishing returns and increasing noise. Agents start fresh each time and re-discover adjacent issues. The right workflow: run once at feature freeze, triage into “must fix” and “can defer,” fix the blockers, run once more before tagging. Not a continuous loop.

Specificity matters in prompts. Vague prompts produce vague results. “Review the authentication flow” produces different output than “Review the OAuth callback handler in accounts/views.py for state parameter validation and session fixation.” The more specific the context, the more useful the output. This is just good engineering communication — the same thing that makes a good code review comment makes a good agent prompt.

The template

The project structure, CLAUDE.md patterns, agent definitions, and CI configuration that came out of building Visiban are available as a project template at gitlab.com/macrodream/project-template. It’s abstracted from the specific stack and is intended as a starting point for others building production software with Claude Code.

The twelve-week build produced something I’m genuinely proud of. The audit trail works exactly the way I imagined it should in 2014. The board is fast and the code is clean. Building it solo with Claude Code wasn’t a compromise — it was a different kind of team.