“We’ll fix it later.”
This wasn't in plan. When the project began, everyone agreed we'd begin with a quick prototype, later cleaning it up into a more maintainable solution. With startling ferocity, your team burns through each phase of development and whips up a prototype the likes of which the world has never seen, leaving you equal parts proud as well as uneasy. Everyone shares their excitement for the wonderful features they envision will take this to the next level. The product is a success. Wait, product? Isn't this just a prototype? Oh no.
Let's clarify something for a moment - the issue here isn't the prototype. That sensation you're feeling is fear. You've suddenly become painfully aware of all the technical debt you have accrued, which you have no strategy to deal with.
“Fine. We’ll fix it now.”
Now that the problem is clear, it's time to address it. First - communicate. Code quality is everyone's problem. Acting in good faith and bringing light to these issues is your responsibility. Just saying there's an issue isn't enough, though. You need to quantify and communicate it. Why is technical debt even an issue? How will this affect you and your team? Users sure aren't aware of it, so how do you communicate that this code quality issue is more than cosmetic?
Code analysis tools are indispensable in providing insights into the health of your project. Metrics such as feature turnaround time and regression frequency also communicate issues, perhaps even more effectively since they have a direct impact on your relationship with stakeholders.
“Plug yourself into the problem.”
Work with your team on a plan to repay your debt to the project. One strategy is to split time each cycle between feature work and paying down tech debt. The ideal ratio depends on your team. Pick one, see how it goes, and adjust each cycle. A nice bonus to this strategy is that, by padding cycles with time to spend on managing code quality, you've given yourself a buffer in case something urgent requires your immediate attention.
Log your debt as you create it. It's difficult if not impossible to avoid incurring debt as you write code. Acknowledge debt as soon as you see it: file an issue, document it. You'll save time by being able to simply reach for an issue from that catalog instead of sifting through code trying to identify one.
Technical debt isn't always obvious. If you don't already have one, set up a code review process with your team. The extra eyes will expose issues that might otherwise slip through. You can't catch every issue alone.
A solid code review process has the added benefit of disseminating knowledge throughout the team that might otherwise end up siloed in an individual. Your team is your most valuable resource. Capitalize on that and you will fly.
The impact of tech debt is real and measurable. Even the best engineering teams struggle. The difference between highly successful teams and average ones is that the best teams have been bitten hard in the past and learned from that experience. Maybe you've felt that pain, maybe this is still just a hypothetical to you. Whatever the case, the problem is as inevitable as it is manageable so long as you keep yourself honest about the impact of the technical decisions you've made along the way.