I did once work on such a thing, deep in the rotten heart of finance in a life insurance company. The design was more than 20 years old and was the result of a port of a previous codebase to a new language. The previous codebase was also a port from an even older language. And legend had it that the thing started out as a Paradox database in the 1980s. Along the way, the code had been translated without significant refactoring, so idioms from the older systems had been brought forward without consideration as to whether they were sane in the new one. The overall flow of the process was still based on the original design, even though you would do it entirely differently in the modern toolset (for example, intermediate results were written out to files, then read back in in the next step because the original system didn’t have the concept of functions that could pass data around).
Subtle bugs had crept in over the years, usually relating to the different sort orders or rounding rules of the different platforms. Some minor bugs had become features (the users didn’t want the bugs fixed because they had become reliant on the incorrect version and didn’t want to have to restate their results with the correct version - the idea being that having to explain and account for the change was more trouble than accepting the minor defect).
The codebase had been altered regularly with minor changes over the years, by a succession of contractors whose names appeared like biblical king lists in program headers. The changes were usually minor, and the approach had always been to graft on some new functionality or extra edge case, rather than redesign anything. Many of the contractors had been actuaries rather than professional programmers, so there were hair-raising sections of code that achieved the required result in extremely obtuse ways. Real outsider art.
There were huge vestigial sections of code and redundant outputs that nobody ever used, but because it was part of a bigger end-to-end process that was also poorly understood and onerous to test, those sections and outputs were always kept just in case they were significant.
In a way, this was a relief. It meant you didn’t need to understand a lot of the code, as long as it kept producing the outputs everyone expected it to.
I was part of a project to migrate all this code onto yet another new platform. Did I take the opportunity to do a grand refactoring? Heck no. The project was already overdue when I arrived, and I had two other projects to work on at the same time. So I did what all those contractors had done before me. I lifted-and-shifted with the least invasive changes possible, ran just barely enough tests to convince the users it was good, and moved on.
I still work for that company. The codebase is now more than 30 years old. It’s had another platform migration since, as well as the same old stream of minor change requests. Bolt-ons on top of bolt-ons on top of tactical kludges.
The thing is ugly and horrifying. Ramshackle and arcane. Congealed, not designed. And yet... it’s managed to carry on producing the outputs that this business needs it to. So is it really all bad?