Yep. It's hard to be romantic when you're trying to get a fix out for customers that really need it, but the fix has to paper over years of ahem diverse approaches to data modeling, the tests you write to help you uncover unknown abominations in your own codebase[0], every fix cascades to new fixes, it's late, dark outside, you're already thinking about how to apologize for the size of your PR tomorrow morning, and then when you finally push your branch to Github to watch the automated tests pass, it notifies you that there are merge conflicts with develop. Complicated merge conflicts.
[0] How's this for an abomination: due to an error using SQLAlchemy, one of our types was being constructed in one way in our code and being constructed in a different way by SQLAlchemy. When we instantiated it directly, you got its properties using methods: organization_id(), last_updated_at(), etc. When we loaded it from the database using SQLAlchemy, organization_id, last_updated_at, etc. were fields, not methods. Somehow people managed to call foo.organization_id(), foo.last_updated_at(), etc. in all the code paths where we handled instances we instantiated directly, and access foo.organization_id, foo.last_updated_at, etc. in all the code paths where we dealt with instances fetched from the database.
That actually could be fun. That's the pressure coming from whomever manages the project that turns it into a nightmare. Allow me however long I need to refactor someone else's mess and I'm having a field day.
I think what makes it not fun for me is seeing users screwed by things that shouldn't happen. Things we should have done right the first time. Things that can only happen because of bad technology choices. Things that take hours to fix for no good reason, things where the only reason a fix takes ten hours instead of two hours is that we're paying for bad decisions.
[0] How's this for an abomination: due to an error using SQLAlchemy, one of our types was being constructed in one way in our code and being constructed in a different way by SQLAlchemy. When we instantiated it directly, you got its properties using methods: organization_id(), last_updated_at(), etc. When we loaded it from the database using SQLAlchemy, organization_id, last_updated_at, etc. were fields, not methods. Somehow people managed to call foo.organization_id(), foo.last_updated_at(), etc. in all the code paths where we handled instances we instantiated directly, and access foo.organization_id, foo.last_updated_at, etc. in all the code paths where we dealt with instances fetched from the database.