feat(labs): link a marker to its analyte for the unit conversion

Slice 1 of phase 3 of #1095. A Biomarker row keeps only its name, so nothing
said which analyte it was. This adds the explicit alias list in the catalog the
issue settled on, including the registry-only keys (urea, blood urea nitrogen,
uric acid, total calcium, total bilirubin), and sets biomarkers.analyte_key
(from migration 0385) from it.

matchAnalyteKey equals a marker's folded name against the localised names of the
catalog seeds the registry knows and against the alias list. It matches the
whole name only, so "Calcium (ionisiert)" is not "Calcium"; a name two analytes
claim matches neither; and the marker's own unit must be one the analyte reaches,
so a marker called "Glucose" in a unit the registry cannot convert stays
unlinked.

The key is set when a marker is created (the biomarker route, the mint used by
lab writes, the legacy backfill) and, for an existing marker, by
ensureAnalyteKey the first time a reading needs it. It never overwrites a key
that is set. There is no boot job for the existing markers: the conversion that
uses the key fills it on first use, and a sweep can be added later if wanted.

The key is returned on the biomarker API and in the OpenAPI schema.

Refs #1095
This commit is contained in:
BernhardBuckel committed 2026-10-11 20:04:43 +02:00
1 parent c2be166f72
commit 52ea3b9c2f
13 files changed
+660 -3

No files matched your search

+5
View File
@@ -60,6 +60,11 @@ export interface BiomarkerDto {
lowerBound: number | null;
upperBound: number | null;
panel: string | null;
/**
* Which analyte the marker is, for converting a reading in another unit
* (the unit-conversion registry's key), or null when it is none that is known.
*/
analyteKey: string | null;
hasContext: boolean;
context: string | null;
/** v1.22 — a hidden marker drops from the active list + lab-entry pickers. */