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".
Identical behaviour comes first
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 the live 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 →