Back to Blog
ai12 min read

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.

V
By Ventra Rocket Team
·Published on 7 April 2026
#Claude Code#AI#Enterprise#Legacy Migration#ERP

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