То, на что ссылается доктор, говоря «у пациента низкий гемоглобин» или «креатинин в норме» — единица медицинского рассуждения. Не молекула (это analyte), не единичный замер (это observation), а уровень, на котором мы интерпретируем значение, поднимаем алерт и предлагаем follow-up. Примеры: гемоглобин, креатинин, глюкоза, ТТГ, ферритин.
Это наш канонический term в продукте, коде и общении. UI показывает «список биомаркеров»; в biomarker graph записи проиндексированы по биомаркеру; actuality service решает per биомаркер, актуально ли значение.
Биомаркер не равен LOINC-коду. Один биомаркер обычно соответствует множеству LOINC-кодов: разные units (mg/dL vs mmol/L глюкозы), разные specimens (Cr в Bld vs Cr в Ser/Plas), разные methods. Сшивка таких кодов в одну сущность — задача trending groups (codification-слой) и biomarker graph (clinical knowledge-слой).
Когда интерпретируем уже сданные тесты — смотрим на них как на список биомаркеров пациента, не как на список observations. Для каждого биомаркера берём latest observation и работаем с ним; дедуплицируем по биомаркеру (через trending_group_id), не по конкретному LOINC-коду и не по дате теста. Эта семантика — практическая причина существования trending groups: без них один биомаркер дробится на параллельные «биомаркеры» по разным LOINC-кодам, и latest на каждом графике перестаёт быть latest самого биомаркера.
Близкие термины
- Analyte — субстанция, которую анализ измеряет (гемоглобин — белок, креатинин — метаболит). Фокус на физико-химической природе вещества, не на клинической интерпретации. На практике в нашем коде различие с биомаркером терминологическое: «analyte» — словарь LOINC и harmonization-сервиса; «биомаркер» — словарь продукта (graph + UI + actuality). Один analyte обычно = один биомаркер; различие появляется когда мы измеряем разные дериваты одной субстанции (свободный T4 vs общий T4 — два биомаркера, один analyte семейства Thyroxine). В этом смысле
trending_group_id≈ analyte-уровневая идентичность: один trending group обычно собирает LOINC-коды, описывающие один analyte в разных представлениях (units / specimens / methods). LOINC сам через native LG-codes (наш L1) делает это для части аналитов; L2-L3 trending groups augment’ят там, где LOINC сам не сгруппировал. - Observation — единичное измерение в FHIR (значение
Xдля analyteYв моментT, у пациентаP), ресурс fhir-observation. Биомаркер — это абстракция «что измеряли»; observation — конкретный замер «что получилось вот в этот понедельник». Несколько observations одного биомаркера у одного пациента = тренд. - Тренд — последовательность observations одного биомаркера во времени. UI рисует график «значение vs дата», вычисляет динамику. Чтобы тренд имел смысл, observations должны быть надёжно сгруппированы — задача trending groups (без неё разные LOINC-коды одного analyte рисуют параллельные графики, динамика не видится).
Legacy: «параметр крови»
В .NET-эпохе (BloodGPT-dotnet) канонический term был «параметр крови» (англ. blood parameter). В коде остались названия таблиц вроде LoincParameters, поля parameter_v2_id, response-shape parameters: [...] в legacy API. Содержательно — то же самое, что биомаркер у нас сейчас.
Term ушёл по двум причинам:
- «Биомаркер» точнее отражает что мы делаем — интерпретируем сигнал, не просто отображаем число. Этим занимается medical-литература; продукт хочет звучать как медицинский, не как лабораторный отчёт.
- Не всё, что мы интерпретируем, — кровь. Моча, специфические биожидкости подпадают под «биомаркер» естественно, под «параметр крови» — натянуто.
В новых местах кода (recognition-pipeline, biomarker-graph, actuality service) используется биомаркер. В legacy-stake (.NET API контракт, b2b clients, которые ещё на нём) — параметр. Полный переход — часть общей миграции legacy-стека (см. legacy-stack-migration).
Где живёт в коде / данных
- Не отдельный ресурс в FHIR. Биомаркер не материализован как отдельная entity в FHIR-store — он подразумевается через коллекцию observations с общим
trending_group_id(или общим LOINC analyte concept). См. trending-groups про механику сшивки. - В graph биомаркер представлен записью с display-именем, доменом (hematology / thyroid / lipids …), и ego-сетью связей (related conditions / medications / parameters). Сейчас ключ — display-имя; обсуждается переход на
trending_group_id(biomarker-graph-key-loinc). - В harmonization биомаркер — implicit, фигурирует как target маппинга
raw lab parameter → LOINC code. На стороне сервиса именуется analyte.
Открытые вопросы
- Terminology в продуктовых текстах нестабильна. «Параметр», «биомаркер», «показатель», «marker», «analyte» используются взаимозаменяемо в созвонах, спецификациях, UI копи. Унификация — параллельная задача с миграцией .NET → новый стек (legacy-stack-migration).
- Биомаркер vs panel. Биомаркер — атомарная единица; panel (липидный профиль, общий анализ крови) — группа биомаркеров. Сейчас понятие «panel» в коде живёт в двух разных значениях: (а) clinical panel — клинически осмысленная группа биомаркеров, которую обычно заказывают вместе (липидный, печёночный, ОАК); используется в actuality как TTL-якорь (newest биомаркер в группе анкорит весь panel); (б) lab order panel — то, что лаборатория физически продаёт как один тест с одним кодом, может не совпадать с clinical panel. В graph и UI panel представлен слабо, first-class сущностью не является. Carry-over: вероятно заслуживает отдельной страницы
domain/panel, которая разнесёт эти два значения. - Биомаркер vs trending_group_id. Два разных слоя на одну сущность: trending_group_id — codification (механическая логика «эти LOINC-коды описывают один analyte, разные представления», производное от LOINC + наш augmentation); биомаркер — clinical entity (то, на что доктор смотрит, что мы интерпретируем). На текущей реальности они в 1:1, но создаются разной логикой: trending group рождается из CSV-генератора и LOINC-таксономии, биомаркер рождается из медицинского решения «вот эта запись в графе = одна clinical entity». Edge case, который сломает 1:1: если LOINC выпустит группу, объединяющую два разных биомаркера (либо разделит один на два) — codification-слой переедет, clinical-слой нет. Не наблюдалось.
Связано
- loinc — стандарт кодирования; источник analyte concept’а
- trending-groups — codification-слой, сшивает LOINC-коды одного биомаркера в один тренд
- biomarker-graph — clinical knowledge-слой; биомаркеры как entry с ego-сетями
- biomarker-actuality-service — TTL-логика per биомаркер (актуально ли значение)
- biomarker-actuality-thresholds — TTL-thresholds, anchor от newest биомаркера
- fhir-observation — FHIR-ресурс, в котором живут single measurements
- reference-ranges — норм-диапазоны per биомаркер (lab-level / region-aware)
- biomarker-graph-key-loinc —
trending_group_idкак канонический ключ графа — draft - legacy-stack-migration — общая миграция legacy-стека (.NET + Python-сервисы) в TS-монорепо (где term был «параметр крови»)