La conciliation médicamenteuse
On admission, two medication lists exist side by side: what the patient takes at
home (MedicationStatement) and what the stay has prescribed
(MedicationRequest). The clinical question is short and specific — what did we
fail to carry over, and what changed dose on the way in? — and it is one of the
places where errors are both common and consequential.
The ehr-lab answers it with layout, not alerts.
Why not an alert
An alert would have been the cheaper thing to build: compare the two lists, fire one warning per divergence. The reason we don't is measured, not aesthetic.
Twinlist (Plaisant et al., JAMIA 2015 — 20 practising clinicians, 80 trials, counterbalanced order) tested exactly this task with a two-column aligned presentation instead of a list-plus-warnings interface. It found 18 % less time, 40 % fewer clicks, 60 % less scrolling — and, the result that matters here, 12 serious errors against 31. Alignment outperformed the alternative on the outcome, not merely on comfort.
That fits the constraint recorded in the clinical alert doctrine: interruptions are a fixed budget, and every alert added to a screen reduces the acceptance of the ones already there. Reconciliation divergences are frequent and mostly benign individually, so they are precisely the class of finding that would exhaust the budget without buying safety. Rendering them as an aligned diff adds information and spends nothing.
So domain/reconciliation.ts emits no advice, declares no severity, and is not
registered in ADVICE_REGISTRY. It returns paired rows; the component renders
them.
What the view shows
Rows are ordered by what the prescriber has to decide, not alphabetically:
| Status | Meaning | Why it ranks there |
|---|---|---|
only-home |
taken at home, absent from the stay | the possible omission — the question asked |
similar |
same drug, different code (dose, form, brand) | the dangerous class a code diff would miss |
only-current |
added during the stay | expected, worth seeing |
identical |
carried over unchanged | nothing to decide |
The two paired columns sit on a subgrid, so a matched pair is on one visual
line and an unmatched entry leaves its column visibly empty. Identical rows are
deliberately quiet: they carry no note and the lightest rule, because their job
is to be scanned past.
Only active prescriptions count. A line that was prescribed and then stopped
is not "carried over" — the patient's home drug reappears as only-home, which
is the honest reading.
The limit of nominal matching
Matching runs in two passes: first on the drug code (system|code), then on the
nominal name — the first significant token of the label, accents and leading
numbers stripped. Each entry is paired at most once.
This is enough for the case that matters: RAMIPRIL ZENTIVA 5 mg against
RAMIPRIL ZENTIVA 10 mg pairs as similar and the dose difference is on screen.
It is not enough for two generics sold under different brand names — those
will show as one only-home and one only-current rather than a single
similar row.
That gap is a consequence of the data on the line, not of the algorithm: neither side currently carries a clinical-level code. Production reconciliation would match on the BIM's clinical level (the same level the dosage suggestions already query for), which groups brands and generics under one concept. The view states the limitation in place, under the table, rather than letting a reader assume completeness it doesn't have.
Where it lives
The section appears in the patient chart's Anamnèse tab, and only when both lists are non-empty — with nothing to reconcile there is nothing to show. It is a server component: it reads and aligns, it does not act. Deciding to resume or stop a treatment stays in the existing chart actions, where the audit trail already records who decided what.