I Built a $2M Platform With One Architect and AI — Here's How
Last year, we shipped a platform valued at $2 million. The entire engineering team? One senior architect and Claude Code. No offshore team. No army of contractors. Just one person who knew what they were building, paired with an AI that could actually write production code.
I'm not writing this to hype AI. I've been burned by the hype cycle enough times. I'm writing this because what happened on this project fundamentally changed how I think about team composition, project estimation, and what's actually possible when you pair deep architectural knowledge with AI-assisted development. The numbers don't lie — we hit milestones that would've taken a traditional team of 6-8 engineers roughly 18 months, and we did it in under 5 months.
Let me walk you through exactly how.
Table of Contents
- The Project: What We Were Actually Building
- Why One Architect Instead of a Full Team
- How Claude Code Actually Fits Into a Real Workflow
- The Tech Stack and Architecture Decisions
- What Claude Code Did Well
- Where Claude Code Failed and What We Did About It
- The Economics: Cost Breakdown and ROI
- Lessons for Teams Considering AI-Accelerated Development
- FAQ
The Project: What We Were Actually Building
I can't name the client — NDA territory — but I can describe the platform. It's a B2B SaaS product in the logistics space. Multi-tenant architecture. Real-time tracking dashboards. Complex role-based access control spanning organizations, teams, and individual users. Integration with 14 different third-party APIs (carriers, payment processors, customs databases). A customer-facing portal and an internal admin system.
The kind of project where, in a typical agency setting, you'd staff up with a tech lead, 2-3 senior devs, a couple mid-levels, a dedicated DevOps person, and maybe a QA engineer. The client's original estimate from another agency was $3.2M over 20 months with a team of 9.
We proposed $2M, 5 months, one architect. They thought we were insane. Honestly? So did I, a little.
Why One Architect Instead of a Full Team
Here's the counterintuitive thing about small teams: the communication overhead on a 9-person project is enormous. Fred Brooks wrote about this in 1975 and it's still true. With 9 engineers, you have 36 potential communication channels. Meetings multiply. Merge conflicts become a daily ritual. Someone's always blocked waiting on someone else's PR review.
With one architect, the entire system state lives in one person's head. There's no context-switching tax from explaining your approach in a pull request. No design-by-committee. No two-hour sprint planning sessions.
But one person can only type so fast. One person can only hold so many files in working memory. One person gets tired at 6pm and makes mistakes by 8pm.
That's where Claude Code comes in. Not as a replacement for the architect, but as a force multiplier. The architect makes every decision. Claude Code executes at a speed that would require 4-5 developers otherwise.
The Architect's Role
Our architect — let's call him Marcus — has 15 years of experience. He's built systems at this scale before. His job on this project was:
- System design and architecture decisions
- Defining module boundaries and data contracts
- Writing the critical path code (auth, payment processing, data pipeline orchestration)
- Reviewing and refining everything Claude Code produced
- Infrastructure and deployment architecture
- Security audits
What he didn't do: write boilerplate CRUD endpoints, build out UI components from designs, write unit tests for straightforward logic, create database migrations, or scaffold new services. Claude Code handled all of that.
How Claude Code Actually Fits Into a Real Workflow
Let me be specific about what "using Claude Code" actually looked like day-to-day, because the marketing materials don't capture the reality.
Marcus would start each morning by defining the work for the day in a structured way. Not vague prompts like "build me a user management system." Instead, he'd create what we started calling "architecture briefs" — detailed documents that specified:
- The module's responsibility and boundaries
- Data models with exact field types and relationships
- API contract (endpoints, request/response shapes)
- Business rules and edge cases
- Error handling expectations
- Which existing modules it needed to integrate with
Then he'd feed these to Claude Code in chunks. A typical session looked like this:
# Marcus would work in the project directory with Claude Code CLI
# First, establishing context
claude "Read through /src/modules/shipment/ and /src/lib/database/schema.ts.
I need you to understand the existing patterns before we build the
invoicing module."
# Then, the actual build instruction with the architecture brief
claude "Build the invoicing module following the architecture brief in
/docs/briefs/invoicing.md. Follow the exact same patterns as the
shipment module for service layer, repository layer, and route handlers.
Use the existing error handling middleware. Write tests for all
business logic in the service layer."
Claude Code would then generate the module — typically 15-30 files including types, schemas, services, repositories, route handlers, middleware, and tests. Marcus would review the output, make corrections, and iterate. The whole cycle for a medium-complexity module took about 2-3 hours instead of the 2-3 days it would take a senior developer.
The Iteration Loop
Here's what nobody tells you about AI-assisted development: the first output is rarely production-ready. It's maybe 70-80% there. But that remaining 20-30% is where the architect's expertise matters most.
Marcus developed a rhythm:
- Generate — Claude Code produces the initial implementation
- Review — Marcus reads through every file, flagging issues
- Refine — Specific corrections fed back to Claude Code
- Harden — Marcus manually handles security-critical sections
- Test — Run the generated tests, add edge cases Claude missed
This loop typically went through 2-3 cycles per module. By the third month of the project, Claude Code was producing first-pass code that was closer to 85-90% production-ready, because the codebase had enough patterns established for it to follow.
The Tech Stack and Architecture Decisions
We chose the stack deliberately to maximize AI-assisted productivity:
- Next.js 14 (App Router) — for the customer portal and admin dashboard
- Node.js with Fastify — for the API layer (separate from Next.js)
- PostgreSQL — primary database
- Redis — caching, session management, real-time pub/sub
- Drizzle ORM — type-safe database access
- Turborepo — monorepo management
- Vercel — frontend deployment
- AWS (ECS Fargate) — API and background workers
We went with Next.js specifically because the patterns are well-established and Claude Code has deep training data on App Router conventions. This matters more than people think. If we'd chosen something exotic like a Rust-based backend with HTMX, the AI output quality would've dropped significantly. You can learn more about how we approach Next.js development at scale.
Drizzle ORM was a deliberate choice over Prisma for this project. Claude Code generates better Drizzle schemas because they're just TypeScript — no custom DSL to get wrong. Plus, the migration story is simpler when you're generating lots of schema changes quickly.
// Example: Claude Code generated this invoice schema
// on first pass with minimal corrections needed
import { pgTable, uuid, varchar, decimal, timestamp, pgEnum } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
import { shipments } from './shipments';
import { organizations } from './organizations';
export const invoiceStatusEnum = pgEnum('invoice_status', [
'draft', 'pending', 'sent', 'paid', 'overdue', 'cancelled', 'refunded'
]);
export const invoices = pgTable('invoices', {
id: uuid('id').primaryKey().defaultRandom(),
organizationId: uuid('organization_id').notNull().references(() => organizations.id),
shipmentId: uuid('shipment_id').references(() => shipments.id),
invoiceNumber: varchar('invoice_number', { length: 50 }).notNull().unique(),
status: invoiceStatusEnum('status').notNull().default('draft'),
subtotal: decimal('subtotal', { precision: 12, scale: 2 }).notNull(),
taxAmount: decimal('tax_amount', { precision: 12, scale: 2 }).notNull().default('0'),
totalAmount: decimal('total_amount', { precision: 12, scale: 2 }).notNull(),
currency: varchar('currency', { length: 3 }).notNull().default('USD'),
dueDate: timestamp('due_date', { withTimezone: true }).notNull(),
paidAt: timestamp('paid_at', { withTimezone: true }),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
});
export const invoiceRelations = relations(invoices, ({ one, many }) => ({
organization: one(organizations, {
fields: [invoices.organizationId],
references: [organizations.id],
}),
shipment: one(shipments, {
fields: [invoices.shipmentId],
references: [shipments.id],
}),
lineItems: many(invoiceLineItems),
}));
What Claude Code Did Well
Let's get specific. Here's where Claude Code genuinely accelerated development:
Boilerplate and CRUD Operations
This is the obvious one. Generating REST endpoints, request validation schemas (we used Zod), response serializers, basic service methods — Claude Code knocked these out in minutes. Across the project, we estimate there were roughly 180 API endpoints. Maybe 140 of them were standard CRUD or query operations that Claude Code generated with minimal revision.
Test Generation
Claude Code wrote roughly 2,400 tests across the project. Were they all perfect? No. About 15% needed significant rework. But having 85% of your test suite generated and working is a massive time saver. Marcus focused his testing energy on integration tests and the gnarly edge cases that Claude Code couldn't anticipate.
UI Component Development
The customer portal had about 60 unique page views. For each one, Marcus would provide the Figma design reference and the API contract, and Claude Code would generate the React components, hooks for data fetching (we used TanStack Query), form handling with React Hook Form + Zod, and loading/error states. The output was consistently good — maybe 75% pixel-accurate on first generation.
Database Migrations and Schema Evolution
As requirements evolved (and they always do), Claude Code handled schema migrations smoothly. Describe the change you need, and it generates the migration file, updates the schema, updates affected queries, and adjusts the TypeScript types. What used to be a 45-minute careful-refactoring session became a 10-minute review-and-approve cycle.
Documentation
Claude Code generated API documentation, inline code comments, README files, and even runbook documents for operations. Marcus would review and adjust, but the baseline output was genuinely useful. We ended up with better documentation than 90% of projects I've seen, simply because the cost of generating it was so low.
Where Claude Code Failed and What We Did About It
This section matters more than the success stories. If you're planning to use AI this way, you need to know where the walls are.
Complex Business Logic With Multiple Dependencies
The shipment routing engine — which needed to consider carrier availability, cost optimization, customs requirements, delivery windows, and capacity constraints simultaneously — was beyond what Claude Code could handle well. It would generate something that looked plausible but had subtle logic errors that could cost real money.
Marcus wrote this module by hand. Took about two weeks. This is exactly the kind of work that justifies having a senior architect rather than trying to AI your way through everything.
Security-Critical Code
We never trusted Claude Code with auth flows, payment processing, or encryption without line-by-line review. And good thing — it occasionally generated JWT validation that was technically functional but missed edge cases like token expiration clock skew, or didn't properly sanitize inputs before database queries despite using an ORM.
Rule of thumb: if a bug in this code could lose money or expose data, a human writes it and another human reviews it.
Long-Range Architectural Consistency
By month three, the codebase was large enough that Claude Code would sometimes "forget" patterns established earlier, even with context provided. It might use a different error handling approach in one module versus another. Marcus had to be vigilant about catching these inconsistencies.
We mitigated this by maintaining a living "conventions" document that got included in every Claude Code session. Think of it as a style guide, but for architectural patterns.
Performance Optimization
Claude Code generates code that works but doesn't always generate code that's fast. Database queries that do N+1 fetches. React components that re-render unnecessarily. API endpoints that load more data than needed.
Marcus spent roughly 20% of his review time on performance optimization. Not a dealbreaker, but something to budget for.
The Economics: Cost Breakdown and ROI
Here's the part everyone wants to see. Real numbers.
| Cost Category | Traditional Team (Est.) | AI-Accelerated (Actual) |
|---|---|---|
| Engineering salaries (18 mo / 5 mo) | $1,890,000 | $175,000 |
| Claude Code API / subscription | $0 | $12,400 |
| Infrastructure (dev/staging) | $48,000 | $8,200 |
| Project management | $216,000 | $0* |
| QA / Testing | $180,000 | $22,000** |
| Design (contracted) | $120,000 | $95,000 |
| DevOps / Infrastructure setup | $96,000 | $35,000 |
| Total | $2,550,000 | $347,600 |
Marcus self-managed using Linear for task tracking. No PM overhead.
*Contracted a QA specialist for the final 6 weeks.
The Claude Code costs break down to roughly $2,500/month. That's the Max plan ($100/month for the subscription) plus API costs for extended sessions. Some days Marcus would burn through $150-200 in API calls during heavy generation sessions. Most days it was $40-80.
The project billed at $2M. Our total delivery cost was under $350K. I'll let you do the margin math.
Speed Comparison
| Milestone | Traditional Timeline | AI-Accelerated Timeline |
|---|---|---|
| Architecture & Design | 6 weeks | 3 weeks |
| Core Platform (auth, multi-tenancy, base API) | 10 weeks | 3 weeks |
| Feature Development (all modules) | 32 weeks | 10 weeks |
| Integrations (14 third-party APIs) | 12 weeks | 4 weeks |
| Testing & QA | 8 weeks | 3 weeks |
| Deployment & Hardening | 4 weeks | 2 weeks |
| Total | 72 weeks | 25 weeks |
Lessons for Teams Considering AI-Accelerated Development
After this project, I've been thinking a lot about what this means for how we build software going forward. Here's what I'd tell any team or agency considering this approach.
You Still Need a Senior Architect. Maybe More Than Ever.
AI doesn't eliminate the need for expertise — it amplifies whatever expertise (or lack thereof) you bring. A junior developer using Claude Code will ship junior-quality code faster. A senior architect using Claude Code will ship senior-quality code at a velocity that was previously impossible.
The worst possible scenario is a mid-level developer who thinks they're senior using AI to generate code they can't properly evaluate. That's how you get a codebase that looks good on the surface but crumbles under load.
Convention Over Configuration, Everywhere
The more predictable your codebase's patterns are, the better AI performs. We used the same file structure, naming conventions, and code organization in every module. This consistency paid massive dividends as Claude Code learned to match existing patterns.
If you're working with a headless CMS architecture, having strict conventions for content types, API routes, and component structures makes AI-generated code dramatically more reliable.
Invest in Architecture Briefs
The quality of Claude Code's output directly correlated with the quality of Marcus's architecture briefs. Vague instructions produced vague code. Detailed briefs with explicit data models, business rules, and integration requirements produced code that was close to production-ready.
We estimate Marcus spent about 30% of his time writing architecture briefs and reviewing output, and 70% of the time that a traditional team would have spent on actual implementation was handled by Claude Code.
AI-Assisted Development Changes Pricing Models
If you're an agency, this is the uncomfortable conversation. When one architect can deliver what used to require a team of 8, how do you price? We believe in value-based pricing — the client pays for the outcome, not the hours. The platform is worth $2M regardless of whether it took 1 person or 10 to build it.
If you're interested in how this kind of approach might work for your project, our pricing page breaks down how we think about project scoping in this new reality.
Not Every Project Fits This Model
This worked because:
- The requirements were well-defined (logistics is a mature domain)
- We had a genuinely senior architect available
- The tech stack was mainstream (great AI training data)
- The client trusted us to deliver without micromanaging the team size
Projects with ambiguous requirements, heavy R&D components, or specialized domains (medical devices, financial instruments with regulatory requirements) need more human judgment and should be staffed accordingly.
For projects built with frameworks like Astro where the ecosystem is newer and AI training data is thinner, you'll see less acceleration from AI tools compared to React/Next.js projects.
FAQ
How much does Claude Code actually cost per month for heavy development use?
On this project, we averaged $2,500/month all-in. The Claude Max subscription is $100/month (or $200/month for the higher tier as of early 2025), and API usage for Claude Code's agentic sessions adds up depending on how much code you're generating. Heavy days hit $150-200 in API costs. Light review-and-refine days were $40-80. Anthropic has also introduced the Max plan at $200/month which includes significant usage that could reduce variable costs.
Can a junior developer use Claude Code the same way?
No, and this is important. Claude Code amplifies your existing skill level — it doesn't replace architectural knowledge. A junior developer using Claude Code will generate code faster, but they won't catch the subtle bugs, security issues, performance problems, or architectural inconsistencies that a senior engineer spots immediately. You need someone who can evaluate the output, not just accept it.
What about code quality — is AI-generated code maintainable?
It depends entirely on the constraints you give it. Our generated code passed the same linting rules, type checking, and code review standards as human-written code. The trick is establishing strong patterns early in the project so the AI has good examples to follow. We maintained a conventions document that was included in every Claude Code session. Six months post-launch, the team maintaining the platform hasn't reported any unusual maintenance burden.
Does this approach work for frontend-heavy projects?
Yes, with caveats. Claude Code is excellent at generating React components, form handling, data fetching hooks, and state management code. It's less reliable at producing pixel-perfect CSS layouts from designs — you'll need more iteration cycles for visual polish. We found it was about 75% accurate on first-pass UI generation compared to 85-90% for backend code.
How do you handle code review when there's only one developer?
Marcus reviewed every line of AI-generated code himself. We also brought in a contracted security specialist for two focused audit sessions during the project (week 12 and week 22). For the final phase, a QA specialist joined for six weeks. The lack of peer code review is a genuine risk — we mitigated it with automated tooling (TypeScript strict mode, ESLint with aggressive rules, Vitest with coverage thresholds) and external audits.
What happens when Claude Code generates buggy code?
It happens regularly. The first pass is rarely perfect. We built this expectation into the workflow — generate, review, refine, harden. Most bugs were caught during Marcus's review cycle. The automated test suite (also largely AI-generated but human-reviewed) caught regression issues. The key insight is that debugging AI-generated code is faster than writing correct code from scratch, because you're starting from something that's mostly right.
Is this only viable for greenfield projects, or does it work with existing codebases?
Claude Code actually works well with existing codebases because it can read and understand existing patterns. On this project, the later modules benefited from having earlier modules as reference. We've since used Claude Code for feature additions on existing client projects with good results. The key is giving it enough context about existing conventions and patterns. If your codebase is inconsistent or poorly documented, AI-generated additions will inherit that inconsistency.
Would you do this again?
Absolutely. We're already doing it. Two more projects are running with this model right now — one with a single architect, another with two engineers for a more complex system. The economics are too compelling to ignore. But I want to be clear: this isn't about replacing developers. It's about changing the ratio of senior architects to output. You still need the human expertise. You just need less of the human typing. If you're considering a project and want to explore what this model could look like, reach out to us — we're happy to talk through whether it's a fit.