Turning an approved 42-screen prototype into a working multilingual application, then moving from the frontend into clinical-report extraction, scoring and physician validation.
The team already had a prototype approved by the client: 42 screens covering the patient, doctor, clinic, insurer and admin experience in three languages. What it did not have yet was a working product behind those screens.
I started by rebuilding the prototype in Next.js, screen by screen, so we could move quickly without losing what had already been signed off. Once the interface caught up with the backend, I had room to help elsewhere. That meant working in the Python service that reads clinical reports, the scoring logic behind the results and the workflow where a doctor reviews what the system proposes.
Some of the work I am proudest of never appears in a screenshot: choosing a deterministic reader instead of sending sensitive reports to a model, writing a test that reproduced a real concurrency crash, and writing a script to compare three answers to a scoring question the team had been debating.
Confidentiality: the client, consultancy, clinic, physician, country and proprietary medical method are deliberately withheld.
The decisions, mistakes and course corrections behind the work.
Real reports are going through the pipeline now. A patient's blood work arrives as a PDF, the reader pulls the values, the rules turn each value into a reading. The doctor's console, with the original report next to it, is the part I'm building now.
The first real report gave six perfectly healthy values the worst possible reading. The first extraction had kept the lab's unit where the catalogue expected another, and the numbers came out ten and a thousand times off. Nothing crashed and every test passed. We caught it reading the output next to the printed report, line by line, and every new report still gets that line-by-line check.
In early September I returned to the front end, putting those readings into the doctor's console now that the service delivering them exists. The workflow is still being built and checked against real reports, with a physician reviewing results before a patient sees them.
The hardest part of the build has no screen: patient data.
The problem is simple to state. Clinical results have to be linked to a person so a doctor can treat them, and at the same time nobody who reads the clinical data should be able to tell who that person is. Add countries with different regulations and the bar only goes up.
The way I explain it: three baskets and a gatekeeper. One basket holds who the patient is. Another holds the clinical results under an identifier that does not name the patient. The third holds the link between the two, with access to that link tightly controlled. Keeping them apart reduces the risk of connecting a result to a person if one part is exposed. It does not make the clinical data anonymous.
For me, building the screens, it means asking for the information each view needs without treating the combined answer as something to keep. Slower to build, and the first project where I've seen the privacy rule built into the structure itself.
Three tracks, three speeds. The front end moves in days. The backend moves when the data model settles. The method moves at the pace of a physician with a full clinic and our questions somewhere in his inbox.
For a while each of us was waiting on someone else. What fixed it was simple: each of us learned enough of the other two jobs to pick up a task someone else had started and carry it on without them.
I've written extraction rules inside a pipeline a colleague designed. He merged my reader and reran the real report with it the same day, without me in the room. The questions for the physician get drafted by whoever has just read his material, which lately has been me.
I already knew how to delegate. Picking up something half built when the person who started it isn't around is what I've had to learn here.
While the screens caught up with the method, the data model underneath kept changing. Every answer from the physician had a shape our tables didn't have yet.
Some examples. A reading that depends on the patient's age, so the same value means one thing at 25 and another at 58. A test the report prints even when the patient couldn't do it, which loads as a zero if nobody stops it. A value in a unit the catalogue didn't expect, off by a factor of a thousand and still looking perfectly plausible.
Each one means either changing the architecture or a workaround, and two of those three are still open. Every workaround we did got written down as a workaround, so a month later nobody mistakes it for a decision.
The model running today doesn't look much like the first diagram. I've stopped reading that as bad planning. The first diagram was built on what we knew at the start. Most of what we know now came from the physician answering our questions, and the tables moved with each answer.
With enough of the method mapped to start, the next question was how to get the information out of the reports and into the database. And the database is a topic of its own, because clinical data is very sensitive: access has to be controlled, and results should be kept separate from the details that identify a patient. That one gets its own post.
Deterministic extraction or AI? Here we could go deterministic, and in the current fever I think it's worth saying out loud: you don't always need AI. There are methods that already work, do it very well and more reliably. Use AI where it adds something, not AI for the sake of AI.
One day and a few session limits later, the reader was done: a parser that pulls every value from the report the same way every time, so the pipeline can load them without a model in between. We used AI to write it, but it doesn't need one to run. We checked it against the real report we had, value by value, until every number matched the printed page. Each new lab format gets the same check before it counts. That gives us the simple metrics, the ones that go straight to the database. Then come the derived ones, calculated from the simple ones, and the ones derived from those.
I didn't have every formula yet. Some calculations in the method had changed and the update hadn't reached us, so we built everything that could be built and left the rest waiting for the physicians to come back from holiday. The answers arrived while I was writing this post. Next step, closed.
A few weeks in I had screens for the patient, the doctor, the clinic and the insurer. Scores, colours, trends, a treatment plan with steps. All of it running on invented numbers, because the method was not ready to feed any of it.
So understanding the method became the priority and I jumped to that side. The clinical part was the easy bit for me, it's my background. The hard bit is turning it into something a system can run: which values to pull from each report, how to read them, what to calculate from them. But that's for the next post.
I spent the following weeks reading the physician's material, cross-checking the method and listing the questions he still had to answer. On the side I worked with the backend colleague so his tables were ready for the data that was actually going to arrive. Nobody sat idle, and everyone kept an eye on the person next to them to check we were still in sync.
How we run it: one weekly meeting, thirty minutes, and some chat in between. No calendars full of meetings at all hours. Each meeting ends with clear blockers and tasks with an owner, and there is still time to ask how the holidays went. Smart working, señores.
I've spent the past few months as a consultant building a clinical platform with a small team. The plan is for patients to upload their results. AI takes a first pass, but a doctor checks it before the patient sees anything. A wearable helps follow what happens between visits.
Before building anything we had to understand how the clinic works, the client and patient journey, so the system could support every step of it. And then the views, because the patient sees one thing, the doctor another, and the clinic and the insurer something else again.
We split the work three ways. I took the front end, the screens people actually see. A colleague took the backend and the data. A third person took the medical method itself, the one we had to turn into rules.