Rewriting a legacy system while it runs
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.
/** 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 →More articles
Uploading large files in Laravel without breaking
How I solved uploading large videos so that one interrupted request does not take the whole upload with it.
Read →How not to send the wrong email to the wrong person
Sending is the easy part of email campaigns. These are the safeguards I built into my own system.
Read →