The horrors of re-using legacy code
I’m currently preparing a horror themed talk for a local JavaScript meet-up and decided to tell the tale of how legacy code was the monster in my own personal horror movie.
In 2019 I started working on a new project at work, moving from my first JavaScript engagement (yay) for a gambling company (not yay) which was wrapping up and onto a project that would give me much more visibility within the company as I’d be Tech Lead for a team on a large new account.
The project involved helping a client migrate their eCommerce solution from using Drupal 7 to a new version as 7 was going end of life. I know enough PHP to be dangerous, having done some Wordpress early in my career but it’s not really an area I’m strong in so when, about a year into the project, there was talk of a new project to move to NodeJS I was really excited.
At this point we were in the second Covid lockdown in the UK so the initial disruption that covid had on businesses was smoothed out and the client wanted to pick up a project that they’d parked when the first lockdown happened, this was to move to a newer tech stack using NodeJS to ensure longevity of their platform.
It was a couple of months later that I heard that I’d be leading a team that would be working to rebuild the eCommerce flow in that new NodeJS tech stack. I was really happy to be doing this as it meant being able to move away from PHP and Drupal and also being able to learn Vue and GraphQL, two technologies I had limited exposure to.
There was also a lot of buzz around the speed of which we’d be able to get the new eCommerce approach ready for launch as that previous effort was around 60% feature complete.
The client’s architect had done some analysis of the codebase and while the solution required some re-work due to a change in front-end framework (from React to Vue) and API approach (from REST to GraphQL) they concluded that there was a lot of existing code that could be re-used.
It was under this wave of optimism that my new team assembled. We weren’t fully free from some of the work doing Drupal so I split the team in two, with two devs that had previous Drupal experience continuing the work there and the two new devs on the team doing the exploratory work for the new NodeJS work.
Not learning anything from horror movies I decided to split the NodeJS-focused sub-team into one dev looking at the new Vue & GraphQL stack and the other dev looking at the existing code we’d be looking to re-use in order to speed up our delivery.
Much to everyone’s surprise the developer who was looking into re-using that existing code was having a hard time working with the code, they weren’t able to find code relating to the business rules that were meant to be ready and they couldn’t see an easy path to adapt the code to the new frameworks to be used.
They thought this was due to a lack of experience working with TypeScript, React and Vue as they were primarily a C# developer and within the team we decided that this was a good enough reason to not be too worried going forward.
An experiment gone awry
It was around this time that the other two devs on the team were free of their Drupal work and we were able to start work on building up an eCommerce solution in Vue and GraphQL that would have parity with the 60% feature completion of the React and REST based approach the client had worked on previously. With the ability to re-use code it would be a simple task.
It was not a simple task.
The reason the developer who took an initial look at the old code struggled was not because they were a C# developer trying to work with React. It was because the old code was undocumented, had minimal testing, wasn’t using any types and it had business logic in it that the business analysts in the team were not aware of.
We lost a lot of time not only refactoring the code but also the logic that was implemented using it, and as we did the initial deadline that was created off the back of the architect’s code re-use analysis crept nearer and nearer.
Seeing the struggles we were having I tried to push back on those deadlines in delivery meetings, looking for help from the delivery management people on the project to relieve the pressure but the architect instead suggested that the team may not have the necessary skills to do the task as their analysis of the code had shown a high level of re-usability.
We of course did not make that initial deadline, we didn’t make the secondary deadline either. We were really struggling to make much progression with getting the old code into a shape that could be used and the team were being flagged as a risk.
This led me to feel powerless as I knew that there were issues but no one was willing to help us and I was also concerned how this reflected on me as a Tech Lead, being unable to motivate a team to solve the problems we were facing.
The team were also burning out, working hard on solving the problem of how to re-use the existing code and the only feedback they were receiving was negative due to deadlines not being met and higher ups questioning why they were struggling.
In order to fight back we had a little regroup and tried to document a list of issues we were having with re-using the old code, namely the lack of documented functionality and the business logic being completely different to expectations.
We would then present this list of issues to the delivery side of the project so they could understand the problems we were facing and -hopefully this time- help buy us more time.
Unfortunately this didn’t work as expected and instead the question of the skills and confidence in working with certain frameworks and languages was put to the team. We had to complete a skills matrix to show how competent we were at working with the old code as they were convinced that re-using the old code was the correct plan.
A couple of weeks later the C# developer quit the team due to burn out and not enjoying themselves, feeling that they didn’t have the skills or support from higher ups to solve the problems they were asked to solve. It really sucked to see them go.
With the departure of a team member from a team that is already flagged as “at risk” there was a lot of attention from delivery management on us. This really made it hard to enjoy working on the project, I was close to admitting defeat myself and asking for a project move because it was not a fun time.
A helping hand
There was a ray of hope in the darkness however, the extra attention from delivery management meant they pulled in some more technical people to help evaluate the situation.
These technical people looked at the old code and the list of issues we were having with it and suggested giving us some time to try and reach feature parity building up the Vue and GraphQL code from scratch in a “Greenfield” manner and then measuring the speed of progress made between the two approaches.
The greenfield approach worked really well, we could have the client define the business logic and build that instead of having to understand what the old code did, ensure that it was doing what the business wanted and then find a means to adapt it between frameworks.
After a couple of weeks we presented the metrics around velocity, developer happiness and adherence to code standards of delivery management and we were finally able to get them to acknowledge that trying to re-use the existing code was causing more harm than good.
We were still really behind schedule on the expected delivery but feeling more in control of the approach we were going to take helped to rebuild the morale the team had lost and this translated into the team being able to get close to being back on-track after a couple of months.
Seeing the progress being made by the revitalised team, the delivery side of the project looked at the other areas of the project that needed help and split the team up. The idea being that being able to seed a set of teams with members from the original team would allow those team members to help the other developers of those new teams to understand the approach.
The developers who were leaving my team were happy to move into these positions as it meant being a Tech Lead themselves which was good for them but it meant that a lot of brain drain happened to my team and I had a new set of developers to transform into a perfect feature delivery machine.
But we managed to make a lot of progress, the new teams made a lot of progress building up their respective parts of the end-to-end eCommerce journey using the new tech stack and we finally hit our deadlines.
As we progressed towards launch of the new eCommerce platform it was decided to reshuffle the teams once more in order to boost the number of developers working on an area with a lot of complexity.
This reshuffle led to my team not only continuing to build the basket functionality but to take on the product selection, account creation and authentication, payment processing and order fulfilment functionality too.
And with the intake of all that functionality I found myself yet again being told I could re-use code written months before by people outside of my team — I was the LEGACY CODE RE-ANIMATOR.