How We Used Claude Code to Rebuild a Legacy ERP in 6 Weeks
A Vietnamese manufacturing company with 500+ employees replaced their outdated VB.NET ERP with a modern TypeScript/Next.js system in 6 weeks instead of 6 months, with a 3-person team and 85% AI-generated code.
When a mid-sized Vietnamese manufacturer came to us with a VB.NET ERP built in 2008, the situation was bleak: 200+ forms, zero documentation, and the original developers had left years ago. The conventional estimate to rebuild it was 6 months with a team of 8. We did it in 6 weeks with 3 people — and Claude Code made it possible.
The Problem: Legacy Code Nobody Understood
The company ran every business operation — production planning, inventory, HR, invoicing — through this ERP. It worked, barely. But scaling was impossible, mobile access did not exist, and any change risked breaking something else.
The specifics were daunting:
- 200+ Windows Forms screens in VB.NET
- ~180,000 lines of code across 400+ modules
- A SQL Server 2005 database with no ERD
- No unit tests, no API layer, no documentation
- Zero engineers on the team who had ever touched VB.NET
The Solution: Claude Code as the Migration Brain
Rather than understanding the legacy system manually — which would have taken months — we used Claude Code as an analytical engine to reverse-engineer the entire codebase.
Phase 1: Codebase Archaeology (Week 1)
We fed the entire VB.NET codebase into Claude Code and ran a systematic analysis. Claude Code produced a 47-page architectural document in 4 hours — mapping every form to its data model, every stored procedure to its business function, and every inter-module dependency.
Output example:
{
"entities": {
"ProductionOrder": {
"fields": ["order_id", "product_code", "quantity", "planned_date", "status"],
"relationships": ["BOM", "WorkCenter", "MaterialRequest"],
"forms": ["frmProdOrder", "frmProdOrderList", "frmProdOrderTracking"],
"stored_procs": ["sp_CreateProdOrder", "sp_UpdateProdStatus", "sp_GetProdSchedule"]
}
}
}
Phase 2: Migration Architecture (Week 1-2)
With the system fully mapped, we designed the target architecture:
| Legacy VB.NET | Modern Stack | |---|---| | Windows Forms | Next.js 14 (App Router) | | VB.NET business logic | TypeScript services | | SQL Server 2005 | PostgreSQL 16 | | Manual reports | React + Recharts dashboards | | No API | tRPC + Zod validation |
Claude Code generated the entire database schema migration from inferred SQL, including foreign keys and indexes that did not exist in the legacy system.
Phase 3: Parallel Code Generation (Weeks 2-5)
With the architecture defined, Claude Code pair-programmed with our 3 engineers simultaneously on different modules. 85% of the final codebase was AI-generated. Human effort focused on reviewing business logic correctness, writing integration tests, and handling edge cases.
export const productionOrderRouter = router({
create: protectedProcedure
.input(z.object({
productCode: z.string(),
quantity: z.number().positive(),
plannedDate: z.date(),
workCenterId: z.string().uuid(),
}))
.mutation(async ({ ctx, input }) => {
const bom = await ctx.db.bom.findFirst({
where: { productCode: input.productCode, isActive: true }
});
if (!bom) throw new TRPCError({
code: 'BAD_REQUEST',
message: 'No active BOM found'
});
return ctx.db.$transaction(async (tx) => {
const order = await tx.productionOrder.create({
data: { ...input, status: 'PLANNED' }
});
await tx.materialReservation.createMany({
data: bom.components.map(c => ({
productionOrderId: order.id,
materialCode: c.materialCode,
quantity: c.quantityPerUnit * input.quantity,
}))
});
return order;
});
}),
});
Phase 4: Data Migration (Week 5-6)
Claude Code wrote the data migration scripts — inferring data types, handling Vietnamese UTF-8 encoding issues (Windows-1258 to UTF-8), and generating rollback procedures.
import uuid
from decimal import Decimal
STATUS_MAP = {
'PL': 'PLANNED', 'IP': 'IN_PROGRESS',
'DN': 'DONE', 'CX': 'CANCELLED'
}
def migrate_production_orders(legacy_conn, modern_conn):
legacy_cur = legacy_conn.cursor()
modern_cur = modern_conn.cursor()
legacy_cur.execute("""
SELECT ord_id, prod_code, qty, plan_dt, status_cd
FROM tbl_prod_order
WHERE del_flag = 0
""")
batch = []
for row in legacy_cur:
batch.append({
'id': str(uuid.uuid4()),
'product_code': row.prod_code.strip(),
'quantity': Decimal(str(row.qty)),
'planned_date': parse_vb_date(row.plan_dt),
'status': STATUS_MAP.get(row.status_cd, 'UNKNOWN'),
})
if len(batch) >= 500:
modern_cur.executemany(INSERT_SQL, batch)
modern_conn.commit()
batch = []
Zero data loss was achieved. Every record was verified by running legacy and modern systems in parallel for 2 weeks.
Results
| Metric | Before | After | |--------|--------|-------| | Time to rebuild | Estimated 6 months | 6 weeks | | Team size required | 8 developers | 3 developers | | Code generated by AI | 0% | 85% | | Data loss during migration | — | Zero | | Mobile access | None | Full responsive | | Page load time | Desktop app only | < 1.2s | | Monthly hosting cost | On-prem server | $180/mo (cloud) |
Key Insights
1. Claude Code's Context Window is a Superpower for Legacy Systems
The ability to load an entire module — 5,000+ lines of VB.NET — and ask "what does this do?" is transformative. Manual reverse-engineering would have taken weeks per module.
2. Define the Target Pattern Before Generating
We spent 2 days defining our TypeScript/tRPC boilerplate patterns before generating anything. Every subsequent Claude Code prompt included those patterns. Output quality was dramatically higher.
3. Humans Review, AI Generates — Do Not Flip This
Our 3 engineers spent 70% of their time reviewing AI output, not writing code. Engineers caught 3 critical business logic errors — edge cases the VB.NET code handled correctly but subtly.
4. Zero Data Loss Requires Paranoid Verification
We ran legacy and modern systems in parallel for 2 weeks, comparing outputs on every transaction. Claude Code helped write the comparison harness. This step cannot be skipped.
Conclusion
A 6-month, 8-person project became a 6-week, 3-person project. Claude Code handled the heavy lifting; engineers handled judgment.
For companies sitting on legacy systems they are afraid to touch: the tools to modernize them now exist. Ventra Rocket runs this playbook for enterprise clients across Vietnam and Southeast Asia. Contact us to discuss your legacy modernization project.
Related Articles
Claude Code + Cursor: How a 2-Person Startup Shipped a SaaS in 30 Days
Two non-technical Vietnamese founders built a full dental clinic management SaaS — booking, patient records, invoicing, SMS reminders — in 30 days using Claude Code and Cursor. 15 paying clinics in month one. Pre-seed raised on traction.
AI Video Generation at Scale: Helping a Marketing Agency Produce 200 Videos/Month
A Vietnamese digital marketing agency serving 30+ e-commerce brands slashed video production cost from $800 to $35 per video and scaled to 200+ videos/month using an AI pipeline built on Claude, ElevenLabs, Runway Gen-3, and FFmpeg.
Gemini for Enterprise: Building a Multi-Modal Knowledge Base for a Hospital Network
A private hospital group in Vietnam with 12 locations unified 50,000+ medical records — PDFs, handwritten notes, X-rays, lab results — into a single AI-powered search system using Gemini 1.5 Pro. Diagnosis lookup time dropped from 15 minutes to 30 seconds.