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

+9 -2
View File
@@ -68333,6 +68333,10 @@ components:
anyOf:
- type: string
- type: "null"
analyteKey:
anyOf:
- type: string
- type: "null"
hasContext:
type: boolean
context:
@@ -68352,6 +68356,7 @@ components:
- lowerBound
- upperBound
- panel
- analyteKey
- hasContext
- context
- hidden
@@ -68359,8 +68364,10 @@ components:
- updatedAt
additionalProperties: false
description: A user-scoped catalog marker. `context` is the decrypted per-marker note (or null); `hasContext` flags its
presence. `hidden` drops the marker from the active catalog list and the lab-entry pickers without deleting it
(its readings and unit/range survive). A `LabResult` linking this marker resolves its unit + reference bounds
presence. `analyteKey` is the analyte the marker was recognised as (the unit-conversion registry's key, e.g.
`fasting-glucose`), or null when its name matches none; a reading in another unit is converted only for a marker
that has one. `hidden` drops the marker from the active catalog list and the lab-entry pickers without deleting
it (its readings and unit/range survive). A `LabResult` linking this marker resolves its unit + reference bounds
from here.
CreateBiomarkerResponse:
type: object