GESCON was a municipal management system written in VB.NET, still in daily use, with no realistic way to take it offline for a "big bang" migration. The brief was simple to say and hard to do: move it to Angular and .NET 5 without anyone noticing.
Running two systems in parallel
The approach that worked was incremental cutover, not a rewrite-and-switch:
- Stand up the new stack alongside the old one, sharing the same database where possible.
- Migrate one module at a time, routing only that module's traffic to the new system.
- Keep the old VB.NET system as the fallback until the new module had run cleanly in production for a full billing cycle.
Cleaning up along the way
Once the structure was in place, we used the migration as a forcing function to introduce Clean Architecture — not as a separate initiative, but baked into how each migrated module was rebuilt. Over about a month, that meant removing roughly 900 lines of dead code and adding automated tests to code paths that had never had any.
We also found a sensitive data leak in the old API during this process — the kind of thing that's much easier to spot when you're forced to read every endpoint carefully because you're rebuilding it.
The actual hard part
Technically, none of this is exotic. The hard part is discipline: resisting the urge to "just rewrite it properly this time" and instead shipping in small, reversible steps that never put production at risk. Zero downtime isn't a technology — it's a sequencing decision you make every day of the migration.