I wanted to write this post for a long time. I have first drafts from Q3 of 2018, yet I never had the chance to crystallize my thoughts on that matter. Because how you demystify a legacy project? And not only in Rails but in general? I guess the answer is the same as for many other similar questions - it depends.
Technical debt is unavoidable. One split there, another over there. Your team has a worse day, requirements are unclear, you have no better idea, you’re annoyed, frustrated, business requirements changed, you pivoted. Bam, a few months later you wonder who wrote this pile of crap? Oh yeah - it was you. Or blame the other guy/gal. Because it’s a tradition.
Instead of trying to form my thoughts into nice words I will put a list of bullet points for future references - hoping that at least some of them will be still useful and valid.
are there any long-running pull requests? Is there a chance those will be finished at all? If not close, delete, move on
delete old unmerged branches, old issues from a few years back - at this point it’s probably just noise. I’m not saying some of them are not valid, but the chance is it’s just too much information at this point - you will have a chance to get back to it if it’s truly important
how the process looks like on Trello/Jira/other issue tracking software - does it make sense?
do you receive any notifications about deployments/exceptions that are happening in the system?
is there some sort of monitoring? At least will you be informed if your app(s) is(are) down?
is infrastructure written as code? Is it fragmented? (different PaaS services or even different hosting providers on top) Do you have some documentation? If not start documenting moving parts - it will come in handy later
having a test suite is the key; otherwise, it’s really hard to move forward. I would start with adding integrations specs (assuming there are none) and take it from there - you will have chance to ask a lot of business-behavior related questions while you’re at it
at the same time I wouldn’t be afraid to remove old, poorly written tests - especially when those tests are testing the implementation instead of the outcome - the only way to deal with it is to rewrite the test itself - and again at the beginning I would favor integration specs; if you’re unsure what is safe to delete you can at least separate legacy tests from new one
on of the worse thing that you might encounter is some undocumented behavior deeply hidden in the system - some process glued together between two different apps, or some cryptic cron job running in the background that exports excel sheets once a month that was set up 5 years ago - and usually you will find out about it once it breaks; but check crontabs, Heroku schedulers and similar stuff for your own sanity
refactor while introducing new features or bugfixes only - in my experience refactoring for the sake of refactoring never works as you will lack clear vision where you want to end up as you have no idea how the whole system is running and is connected at this point
accept the fact it will most likely take a freaking long time to get it straight 🤷♂️