Legacy migration

College ERP: Delphi to Python and React, with no downtime

Client: Under NDA 2023 Delphi · Firebird 2.5 · FastAPI · React · Firebird 3.0

A college ran its admissions, enrolment and academic records on a Delphi desktop application backed by Firebird 2.5. It worked. It had worked for years. The problem was everything around it: the application only ran on Windows machines inside the building, the original developer was long gone, and nobody could add a screen to it without a Delphi environment nobody had set up any more.

The usual advice would have been a rewrite. That would have meant a year of parallel work, a cutover weekend, and a data migration with real risk of losing records that a college is legally required to keep.

What we did instead

We kept the database.

The Firebird schema held decades of academic records, and it was — as is often the case — the most carefully designed part of the system. The business rules that mattered were already expressed there, in constraints and stored procedures. Throwing it away would have meant re-deriving rules nobody had written down anywhere else.

So the migration replaced the layer above it. A FastAPI service was put in front of the existing database, and a React application was built against that API, screen by screen. Firebird was upgraded from 2.5 to 3.0 in place.

Screen by screen, not all at once

The Delphi client and the new web application ran against the same database at the same time. Staff kept using the desktop application for the screens that had not been migrated yet, and moved to the browser for the ones that had.

That is the part that made it safe. There was no cutover day, no weekend where the system was down and the migration either worked or did not. Each screen was its own small release, and each one could be reverted on its own.

What was added on the way

The original application had the security posture of a desktop program written for a trusted network — which is what it was. Moving it to the browser changed the threat model, so the new layer added:

  • Modern authentication, replacing the application’s own user table
  • Rate limiting on the API
  • Server-side input validation, rather than relying on the desktop form controls

Outcome

  • Downtime: none. The system was never taken offline for the migration.
  • Records re-entered by hand: none. The database was never exported and re-imported.
  • The database stayed. Same data, same constraints, upgraded engine.

The result is a system a normal web developer can now maintain, sitting on a schema that did not have to be re-litigated.

Running something like this?

Twenty minutes, no slides. If it’s a legacy system, the honest first step is usually a codebase audit — fixed price, two weeks, and yours to take anywhere.