case study
From Vibe Code to Production: A SaaS Migration
Taking a prototype built with AI-assisted coding and transforming it into enterprise-grade production software.
Problem Statement
A solo founder had built a working SaaS prototype using AI-assisted coding (Cursor + Claude). The product had paying customers and real traction, but the codebase was fragile. No tests, no error handling, hardcoded secrets, SQL injection vulnerabilities, and a deployment process that involved manually copying files to a VPS.
Context & Constraints
The founder was a domain expert, not a software engineer. They'd built something genuinely useful using AI tools, but the technical debt was accumulating faster than revenue. Two production outages in one month. A customer reported seeing another customer's data. The founder needed the product stabilized without a full rewrite, because they couldn't afford to stop shipping features for more than 3 weeks.
Approach & Architecture
We treated this as a stabilization project, not a rewrite. Priority order: (1) fix the security vulnerabilities immediately, (2) add error boundaries and monitoring, (3) set up proper CI/CD, (4) add tests to the critical paths, (5) refactor the most fragile modules. Each phase shipped independently so the product stayed live throughout.
Implementation
Week 1: Rotated all secrets, moved them to environment variables, parameterized all SQL queries, added row-level security in Supabase, and fixed the data isolation bug. Week 2: Added Sentry for error tracking, implemented proper error boundaries in React, set up GitHub Actions for CI/CD deploying to Cloudflare Workers. Week 3: Wrote integration tests for the payment flow and core CRUD operations, refactored the three modules that caused the most production errors.
Results & Metrics
Zero production outages in the 6 weeks following stabilization. Deployment went from manual file copies to automated CI/CD on every merge. The SQL injection and data isolation vulnerabilities were eliminated. The founder could now ship features with confidence because the test suite caught regressions before deployment.
What Broke
The Supabase RLS policies were initially too restrictive and locked out admin users from their own dashboard. One of the CI/CD pipeline steps had a race condition that caused intermittent deployment failures on the first day.
What We'd Do Differently
We'd run the RLS policies against a copy of production data before applying them, not just test data. The CI/CD pipeline should have been tested in a staging environment before being applied to production deployments.
Key Takeaways
- AI-assisted prototypes can have real value. The goal is stabilization, not condescension about the code quality
- Security fixes come first, always. A product with customers and security holes is an active liability
- Incremental stabilization beats full rewrites when the product has traction
- The founder's domain expertise was the real asset. Our job was to protect it with proper engineering