Replacement isn’t always available

The system may be certified, contractually mandated, or simply too central to risk. That is a legitimate constraint, and treating it as a temporary state that never ends is what makes everything built around it worse.

Put a boundary in front of it

A small service of your own that everything new talks to, translating between your domain model and its quirks. That contains the strangeness in one place instead of letting it spread — the argument for modelling the domain rather than the storage.

You cannot stop the legacy system being awkward. You can stop its awkwardness reaching everything you build next.

Own the data flow explicitly

Whatever moves data in and out needs a named owner, monitoring, and reconciliation — otherwise it becomes the integration nobody owns, which is where legacy quietly corrupts new systems.

Copy for reading, not for writing

A read-only replica for reporting and new features removes load and risk from the original without changing it. Two systems both writing the same records is where reconciliation nightmares begin.

Strangle where you can

Move one capability at a time behind the boundary, so each step is reversible and the business keeps running — the same incremental approach as any rewrite worth doing.

Document what it actually does

Legacy systems are usually undocumented and the people who knew have left. Writing down its behaviour as you discover it is the cheapest insurance available, and it is documentation someone will genuinely read.