Case

Making a platform that could only be maintained ready for development again.

The software worked, but changing it was risky. The previous development partner no longer did regular development and only stepped in when something broke. We did not start by rebuilding everything. First we had to understand what was there, what was good and where the real technical blockers were.

The case in brief

Result

From maintenance mode to active development

Test coverage

From around 10% to 92%

Delivered

Refactoring, tests, monitoring and technical control

Follow-up

Years of further development on the same foundation

Where did it get stuck?

The platform consisted of several apps, web environments and an extensive backend. The existing software held a lot of value, but technical debt made new development increasingly difficult. Before changing anything, we therefore first systematically examined the existing code and architecture.

See the approach
App interface with demo data · Enlarge imageApp interface with demo data

New development had practically stopped

The previous development partner no longer did regular development. They only intervened when something actually broke. The platform ran, but technically it was hardly moving forward.

The backend was hard to understand

Functionality was spread over several Elixir apps within an umbrella structure. Names like old, new, v2 and v3 lived side by side, documentation was missing in important places, and different development styles and conventions made it hard to see which code was still leading.

Critical code was barely covered

In one important backend component we measured about 10% line coverage on around 3,400 lines of code at the start. Other components also had limited or virtually no test coverage. As a result, a change could silently break existing functionality.

How did we approach it?

  1. 01

    First understand the system

    We mapped the architecture, active functionality, databases, parsers, integrations and infrastructure. Not on the assumption that everything had to be replaced, but to determine what was good and where change was really needed.

  2. 02

    Organise feedback and monitoring

    Among other things, we set up coverage measurement, error monitoring and an acceptance environment. This made it visible sooner what changes did, so problems no longer had to be discovered through users or manual checks.

  3. 03

    Targeted refactoring and testing

    We removed unused code, introduced more structure and conventions, and improved components as soon as we understood them well enough. At the same time, we systematically expanded the automated tests.

  4. 04

    Then continue development

    As the codebase became better known, tested and manageable, we could develop features again and carry out larger technical improvements without treating every change as a gamble.

What did we build?

The most important result was a professional technical foundation under an existing product. We made the backend more explicit, more testable and easier to manage without needlessly replacing working parts.

App interface with demo data · Enlarge imageApp interface with demo data

A backend we actually understood

We examined and improved the code until it was clear which components were responsible for what. Old, duplicate or unclear implementations could then be removed or improved in a targeted way.

Tests as a safety net

Test coverage became part of the normal development workflow. The relevant backend code grew from around 10% coverage at the start to 92%, with tests on the parts where they actually added value.

Professional engineering around the code

Besides the code itself, we also improved the environment around it, including error monitoring, coverage tooling, acceptance, infrastructure and the technical management needed to responsibly keep developing a production platform.

What changed?

From around 10% to 92% test coverage

The most important backend code started with about 10% line coverage. During the professionalisation we brought test coverage to 92%. Changes could therefore be verified much faster and with considerably more certainty.

New development got going again

The platform did not stay stuck in maintenance. In the years that followed we developed a lot of new functionality and made larger technical improvements on the same codebase.

The foundation became strong enough for new technology

The technical foundation became stable and understandable enough to keep innovating. Later, for example, we trained our own machine learning model to automatically recognise offers in PDFs of store flyers.

Proof

The progress was not only visible in cleaner code. We could measure it and then prove it in practice for years by further expanding the platform. The original analysis also showed that not everything was bad. Parts of the infrastructure, scalability and performance were already in decent shape. That is why we chose targeted professionalisation instead of automatically rebuilding everything.

View cases
App interface with demo data · Enlarge imageApp interface with demo data

10% → 92% line coverage

At the start, an important backend component had around 3,400 lines of code and barely 10% line coverage. In the end, the relevant backend code reached 92% test coverage.

From break-fix to years of new features

Before the takeover, the agreement was that the previous development partner would only intervene when something broke. After the professionalisation we developed the platform for years with new functionality and technical improvements.

Later even our own machine learning

One of the later developments was a self-trained model for recognising offers in PDF store flyers. A good example of how much technical room had opened up again after the takeover and professionalisation.

Related AI challenges

Matching offer

Vibe Code Rescue Audit

We examine what is there, where the real technical risks are and what should be kept, repaired or replaced.

View offer

€2,950 excl. VAT

Result
Technical analysis with a concrete rescue plan
Duration
Fixed scope
Next step
Afterwards you know whether a Rescue Sprint or a larger approach is needed