Back to Journal
operationsen

ERP migration in eight weeks for a 12-person manufacturer

8 weeks, 12 people, 4,200 BOMs, one rollback, and the training lesson we already know but keep forgetting to apply.

Early in 2026 we kicked off an ERP migration with a 12-person Hungarian custom-electronics manufacturer onto the Netorigo platform. The old system was an 11-year-old on-prem Microsoft Dynamics NAV 2015 installation with 137 custom reports. The migration was scoped for 8 weeks. It shipped in 8 weeks. One rollback. One lesson about training that we keep relearning.

How the time broke down

8 weeks, roughly 320 Netorigo engineering hours plus another 80 from the client's IT lead. The time was not evenly distributed:

  • Weeks 1-2: discovery and data analysis. What is in NAV? What do the 137 reports actually do? Which are critical (3-4 of them), and which are not used (94 of them, where last_executed_at was more than two years old).
  • Weeks 2-5: data model design and Prisma migration scripts. 11 modules: customers, products, BOMs, work orders, inventory, purchases, sales, invoices, payments, users, roles.
  • Weeks 5-7: delta-migration against a staging environment plus user acceptance testing.
  • Friday of week 7 to Monday of week 8: the cutover.
  • Week 8: post-go-live support and fine-tuning.

The data shape that took three weeks

BOM (Bill of Materials) versioning was the hardest. In the old NAV, a BOM version was stored in a single JSON-string field (yes, JSON inside a NAV column, not a joke), and we had to reconstruct the versioned hierarchical BOM structure where a top-level product (product.code='ELECTRONICS-CORE-V3') decomposes into 47 sub-components, and any sub-component could itself sit at the top of another BOM.

In our Prisma schema we ended up with three tables:

  • bom - the parent BOM record (productId, versionNumber, validFrom, validTo)
  • bom_component - one BOM line with its child component (bomId, componentProductId, quantity, unitOfMeasure)
  • bom_history - audit log of BOM changes

The migration script (migrate-bom.ts in prisma/scripts/) took three weeks to reach 'utility' state: of 4,200 BOMs, 4,184 migrated cleanly and 16 had to be touched by hand because the old JSON used 'ts' instead of t s (extra space) as a separator.

The data shape that took thirty minutes

The easy part: customers. From the old NAV, 1,847 customer records, only name, address, tax_id, phone, email fields. We migrated them into a Prisma customer table with a direct SQL INSERT ... SELECT in 30 minutes. The customer-facing indexes (tax_id unique, functional index on lower(email)) came in a follow-up migration script.

The contrast is instructive: complex data shape (BOM) three weeks, simple data shape (customers) 30 minutes. If the team had known this distribution during planning, they would have shaped sprint priorities differently.

The Friday-to-Monday cutover

We scoped a cutover window from Friday 18:00 to Sunday 22:00. We stopped the BullMQ workers, took a final dump from the old NAV, and turned on 'silent migration' mode on the Netorigo platform (read-only, API calls return 503). 18:00 to 22:00 ran the CSV import. 22:00 to 02:00 ran delta validation (row-by-row comparison of the old NAV dump against fresh Netorigo data). At 02:00 we slept. At 09:00 we woke up.

On Sunday a quiet bug surfaced: some of the legacy NAV reminder subscriptions (an inherited NAV 'reminder' module) had not made it onto the migration list. A six-hour hotfix added the notification_subscription table, and by Monday 08:00 everything was in place.

One rollback did happen: the payment_method.gateway_credentials field was re-encrypted slightly too fast, and six partner payments were broken for five minutes. We rolled back to the previous payment_method table, decrypted with the old key, re-encrypted with the new key. 14 minutes, zero data loss.

What we learned about training

The biggest mistake: we deferred user training until after the cutover. On Monday morning at 08:00, users picked up the Netorigo UI basics in eight to ten hours, but the advanced features (custom report editing, custom BOM editing) took two weeks to land.

The forward-looking recommendation: training should start in week 7, in parallel with UAT, not in week 8 after go-live. That single change would have saved the client a week of 'partial productivity'.