← Back to blog
engineeringPublished April 28, 2026

We Shipped a Full SaaS in 30 Sessions with One Developer and One AI

We Shipped a Full SaaS in 30 Sessions with One Developer and One AI

You enter your birthday, birthplace, time of birth, and a belief statement. The system runs natal chart calculations through Kerykeion and Human Design, feeds everything to Claude for brand synthesis, generates six images through FLUX Pro, compiles a PDF brand book, and emails you a complete brand identity package. $47 to $97 to $19/month. Real Stripe, real payments, real customers.

We built this from an empty repo in 30 evening sessions at a desk in Bangkok. One founder, one AI agent (Claude Code), zero employees.

The stack

Three independent services share a PostgreSQL database and a Redis queue:

  • Next.js 14 handles auth, payments, the API layer, and the UI. Deploys to Vercel.
  • A Node.js BullMQ worker runs the generation pipeline: Claude synthesis, image generation, PDF compilation, email delivery. Deploys to Railway.
  • A Python FastAPI service does the astrology math through Kerykeion. Runs in Docker on Railway.

Cloudflare R2 stores files. Stripe processes payments. Resend sends emails. Claude writes brand copy and translations. FLUX Pro, Ideogram, and Recraft generate images.

At V.1: 17 Prisma models, 53 API routes, 46 components, 25 database migrations, 5 locales, 496 automated tests, 3 pricing tiers live on Stripe.

The sessions that mattered

Most sessions were unremarkable. Install dependencies, wire up routes, write migrations, seed data. The kind of work where Claude Code earns its keep by doing in 20 minutes what takes a solo developer 3 hours.

Five sessions changed the product.

Session 12: The generation engine overhaul

We compared lifestyle photos from two different brands and noticed something wrong. The modular prompt system we'd built was producing worse output than the hacky inline prompts it replaced. Every coffee brand got the same kitchen. Every fashion brand got the same concrete loft.

We traced 5 root causes and fixed them over two days. The biggest change: we stopped hardcoding scenes per industry and started generating a visualDirection per brand. Claude writes a one-sentence creative brief during synthesis, and that sentence appears in every image prompt. Two coffee brands now look completely different because their cosmic data is different.

We also added anti-slop anchors to every prompt: "Understated, human, grounded," "Nothing symmetrical, nothing perfect," "not commercial." We named specific photographers and film stocks instead of saying "professional photography." We made the person's gesture match the brand's voice descriptors instead of the industry.

The generation engine is the product's moat. We extracted it into packages/generation-engine/ as a standalone package.

Session 19: 11 bugs in one checkout flow

We implemented 3-tier pricing: Spark at $47, Origin at $97, Alive at $97 plus $19/month. Then we ran a systematic debug pass and found 11 bugs in a single payment flow.

The worst one was this line:

if (brand.status === 'paid') return { alreadyFulfilled: true }

This prevented every tier upgrade from working. If you bought Spark, you could never upgrade to Origin because the status was already paid. The fix:

const isUpgrade = brand.status === 'paid' && brand.tier !== tier
if (brand.status === 'paid' && !isUpgrade) return { alreadyFulfilled: true }

One line. Blocked every upgrade path. TypeScript didn't catch it. The build didn't catch it. Only walking every checkout path caught it.

Session 22: 5 parallel agents, 209 tests

We launched 5 Claude Code agents simultaneously. Agent 1 descoped Alive pricing across 7 files and 5 locales. Agents 2, 3, and 4 wrote Playwright E2E tests in parallel, each owning a different domain (payments, auth, gifts/referrals/gallery). Agent 5 built the cashout page.

Combined output: 209 new tests in one session. Each agent finished in about 7 minutes.

The next session we ran all 496 tests together and found 6 classes of bugs that only appear at scale: rate limit state bleeding between test runs, networkidle timeouts on pages that poll every 2 seconds, strict-mode locator collisions where $47 matched two elements on a pricing page.

Session 25: Going live

We aligned the entire UI to the Dark Editorial design system. Created Stripe live products. Provisioned Railway, Vercel, DNS, Google OAuth. Pushed 24 commits. Ran migrations on prod. Cleaned the database.

Time from "let's deploy" to health check passing: one session.

Session 30: Emails never worked

We ran the production smoke test and discovered emails had never sent in production. Four separate root causes, four separate fixes:

  • Templates missing from Docker build. The worker imported from ../../emails/ but those files only existed in the web app.
  • JSX transform mismatch. The worker used "jsx": "react" but templates were written for Next.js's "react-jsx".
  • Broken entry point. Changing rootDir moved compiled output to dist/src/index.js. Our cp command broke relative imports. Replaced with a one-line shim.
  • Missing i18n files. The worker had no messages/ directory for email translations.
  • Four commits, four fixes, emails flowing.

    What Claude Code is good at

    Parallel agents. 5 agents writing tests at the same time, each with a clear scope. Combined output that would take a solo developer a week.

    Systematic debugging. Walking every checkout path, every webhook event, every edge case. Finding 11 bugs that a human would miss because humans don't test the unhappy paths.

    Boilerplate at scale. i18n across 5 locales, 17 email templates, admin CRUD, Prisma migrations. Work that's straightforward but takes hours by hand.

    Reading the whole codebase. It holds 50+ files in context and traces the connection between a webhook handler and a fulfillment function and a gift slot query. Humans lose track after 3 files.

    What Claude Code is bad at

    Visual judgment. We asked it to generate 8 blog cover images. They all looked the same: "dark desk with object." It followed every constraint but missed that the images needed to look different from each other.

    Knowing when to stop. It adds error handling, type annotations, fallbacks, and abstractions that nobody asked for. "That's enough" is a sentence you'll say often.

    Production environment gotchas. The __Secure- cookie prefix. The echo -n for Vercel env vars. The jsx: react-jsx vs react distinction. These bugs eat hours and can't be anticipated from code alone.

    The economics

    Total cost to build: ~$300 (Claude API ~$200, fal.ai ~$50, Railway ~$20/mo, domain $12/yr)

    Cost per brand generated: ~$0.59 (Claude ~$0.26 + fal.ai ~$0.30 + PDF ~$0.02 + email ~$0.01)

    At $97 for Origin, that's 97% gross margin. Break-even at 4 sales.

    V.1 is a checkpoint

    We tagged v1.0-origin with a code snapshot and a database backup.

    The product works. Real brands generate in ~93 seconds. Real payments process. Real emails arrive with working links. The gallery shows 12 unique brands.

    What comes next: 10 to 20 real founders testing the product. Then the $10k MRR gate: 526 Alive subscribers at $19/month, held for 60 days. We don't build anything else until that number is real.

    One founder. One AI. Thirty sessions. Live.