Skip to content
Rapcsány Krisztián Rapcsány Krisztián
hu
← All articles
2 min read

Rewriting a legacy system while it runs

Legacy Laravel Architecture

I am rewriting a dental practice system gradually, feature by feature, in Laravel. The practices work in the meantime, so I cannot afford a "we will switch over one day".

The goal is identical behaviour, not better

In a rewrite the first instinct is to do everything better. Here that is a bad instinct. The practices are used to how it works, so the new system has to behave like the old one. Where it differs, that has to be written down.

I keep a list of where the new system differs from the old, what is still missing, and what I deliberately do differently. That list is the most important document in the whole rewrite.

Many practices, one database

The system is multi-tenant: every practice is a row, and almost every query filters by the practice ID. You cannot bolt this on later, so in the new code I build it that way from the start.

A log for sensitive data

With health data I need to know who changed what. The change log records every modification of every model at field level, modelled on the old system's log, but with PostgreSQL jsonb, a monthly-partitioned table and written through a queue, so it does not slow the system.

ChangeAuditor.php
/** Temporarily disable logging, e.g. during a bulk import or seeding. */
public static function withoutLogging(callable $callback): mixed
{
    $previous = self::$paused;
    self::$paused = true;

    try {
        return $callback();
    } finally {
        self::$paused = $previous;
    }
}

/** On `updating`, keep the original row in memory, so no extra SELECT is needed. */
public function captureOriginal(Model $model): void
{
    if (! $this->enabled($model)) {
        return;
    }

    $this->originals[spl_object_id($model)] = $model->getOriginal();
}

An excerpt of real code, anonymised.

It takes the original row from memory, so it needs no extra query. During bulk imports or uploads the logging can be paused.

Working on a similar problem?

If you are stuck, or want a second look at your solution, write to me. I am happy to look.

Write to me →
Get a quote →