Mind the gap…
r prepare to climb out of a refactor hole

By Juan Martinez
Thursday, September 10th 2020

It’s mid 2019, and the Boost team at District M develops a normal web Application: React on the Frontend, Symfony on the back. The App is a bridge between a complex ad exchange, and Publishers, who use it to set or update configurations, review metrics and generate reports.

But the backlog calls for ambitious new features, and the Boost team decides to:

  • Upgrade Symfony to a newer version
  • Move from using some Symfony components to using the full Symfony Framework
  • Use Scheduled jobs
  • Use an ORM
  • Refactor the data structure to comply with industry standards
  • Refactor back and frontend code to use the new data structure and naming scheme

So a new version is forked from the previous one, and a new database is created, with hourly “Sync Jobs” that keep it up to date with the previous database, because the App in production still writes to it. A hybrid. A mutant! But caged. It’s only temporary, right?

The Boost team is now stuck in the process of migrating tables, creating Doctrine entities, new Controllers, new Services, new Repositories, and doing code refactoring. The process takes longer than anticipated. Sprints go by, and the new version is not launched.

It’s December and the situation becomes critical: the App in production is maintained but not improved. New features are implemented on the version in development, but nobody can use them yet. The team is questioned: “when will the refactor be finished?”. The answer is hard to determine and harder to communicate: “we’re not sure, but not soon”. 

Also, team members recognize refactoring is boring, and it’s bringing them down. Somewhere, something went wrong. The mutant escaped from its cage.

In January, with help from one of the most senior developers in the Tech Area, sketches a plan. It’s not perfect, but it will work. It looks broadly like this: 


The new version of the App will be rolled out as soon as possible, for internal users only.


New Controller endpoints will write to both databases, by first calling both new services, and then transforming data and calling the old ones.


The “Sync Jobs” will be left on, while the new version can be rolled out for external users.

At the end of February 2020 the plan has been executed, and a clearer path out of trouble appears. The team continues refactoring, but in the background, while pushing out new features. The mutant, still out, has been tamed.

In retrospective analysis the Boost team discovers they went into 2 different refactors at once:


They upgraded Symfony, and introduced an ORM.


They refactored the data model..

What could they have done differently?

The team recognizes they should have prioritized only one refactor. For example, they could do #1 during a single Sprint, and immediately release a new version with updated Symfony, ORM, Job Scheduler and many other niceties.

Then, map Doctrine entities to their existing tables, without creating a second database. From then on, new tables would comply with industry standards. And, in the background, they could refactor the old data model, and perform single migrations. With no hourly “Sync Jobs” moving data between 2 databases.

This approach would not have made all the refactoring work go away. But it would have given the team all the power of an updated, full Symfony framework, while allowing them to do the data refactor in the background from day 1.

Check out our solutions in action

Get in touch to schedule a live demo of our platforms with one of our dedicated experts.

Get in touch with one of our experts

If you’re interested in learning more about how we can help your business, reach out to us!