Tracker: BG-876, BG-1023.
Куда движемся: один TS-сервис маппинга биомаркеров (объединяющий normalization-service и loinc-harmonization-service) с Dictionary-First lookup-layer + admin UI поверх. Старая нормализация → fallback внутри LOINC-сервиса для случаев когда стандартного LOINC-кода нет.
Контекст
Два отдельных сервиса в текущей production:
- normalization-service — старый Python сервис. Появился первым, когда команда не знала про LOINC и придумывала свои canonical-имена для биомаркеров.
- loinc-harmonization-service — Python сервис, переработка первого на стандартные LOINC-коды. Часть функционала осталась в нормализации (например, кейсы где стандартного LOINC-кода для параметра не существует — придётся свои придумывать).
Третий путь — Mastra TS port алгоритма LOINC mapping в bloodgpt-for-business/apps/analysis-worker/src/mastra/. Scoring/search parity с production Python достигнут (sessions 833ec924 / 82806132).
Проблемы:
- Drift между Python и TS (пока порт не закончен)
- Два пути в тренды (
ParameterV2Idlegacy +TrendingGroupIdLOINC) → дублирует data ownership - Lookup и pipeline coupled в Python service (pipeline лежит — lookup недоступен)
Рассматривали
- Mar 3 video (session c8967f27): TS Dictionary + Python Pipeline shared DB. Dictionary fast lookup (TS), Pipeline остаётся на Python (LLM SDK / ucumvert / TF-IDF). Dual-key Redis (canonical_hash + simple_hash).
- Apr 1+ shift: полный TS-порт алгоритма. Python pipeline retention отброшен.
Выбрали: full TS + Dictionary-First + service unification
Mar 20 1:1 Ильдар + Артур consensus:
- Один сервис вместо двух — нормализация → fallback внутри LOINC service
- Полный TS-порт workflow (Ильдар портирует normalization workflow с Python на TS; LOINC mapping algorithm уже at parity)
- Dictionary-First lookup layer + admin UI поверх TS — концепт Mar 3 сохраняется, substrate меняется на TS
Артур (Mar 20): «Нам достаточно одного, по идее, лаинки. Нормализация — это то, что было родилось первым, когда мы не знали про лаинки.»
Почему
- Availability decoupling. Pipeline на обслуживании или упал → lookup продолжает отвечать из dictionary.
- TS-substrate унифицирует с UI. UI prototype уже TS (BG-864 session fd4858f8). Full-stack TS = natural fit, нет cross-language drift в API.
- Один источник правды для трендов.
ParameterV2Id(legacy) иTrendingGroupId(LOINC) сейчас параллельны → unification закрывает.
Текущая архитектура (на 2026-04-26)
Что Артур уже сделал в Python LOINC service (база, на которую опирается TS-port):
- TTL кэша Redis убран — инвалидация автоматическая при изменениях (см. dictionary-first-paradigm)
- Override-таблица с supersede механизмом (см. override-storage-design)
- Endpoint warmup для prefill verified pairs (Claude Code наполняет базу заранее)
- Поле reasoning audit в обе таблицы
- Flag
benchmarkдля clean testing (skip cache + skip save) — Ильдар использует для Python ↔ TS comparison
Что Ильдар сейчас делает:
- Портирует normalization workflow с Python на TS (in progress)
- Mastra LOINC mapping at parity (82806132 closeout, Apr 5-7)
Следствия
- normalization-service → TS-port в работе, target merge as fallback (не полный phase-out)
- loinc-harmonization-service → постепенный phase-out, замена TS-имплементацией
- loinc-harmonization-pipeline — production локация переезжает в TS Mastra
- UI прототип
loinc_harmonization_service/ui/→ переезд в монорепуbloodgpt-for-business - Inngest становится event/queue subsтратом — см. inngest про “уход от ad-hoc queue логики”
- agent-vs-workflow design philosophy сохраняется в TS-port
Открытые вопросы
Развёрнутые открытые вопросы вынесены отдельными decision-страницами:
- dictionary-first-paradigm — превратить decision cache в управляемый справочник как часть продуктового value — proposed / основная идея Ильдара
- override-storage-design — отдельная override-таблица vs единая с историей — contested
Малые TBD остаются inline:
- Маппинг наших codes ↔ LOINC: Ильдар хочет таблицу соответствий; Артур: расхождения неизбежны (один LOINC ↔ несколько наших), majority vote.
- Маппинг наши panels ↔ LOINC panels: LOINC panels — нечитаемые tags (
панель X2008); наши 10 фиксированных — приближение. Не приоритет. - Cutover criteria: ~100 валидированных пар input/output от Артура — критерий equivalence Python ↔ TS на момент переключения. Текущий результат TBD.
- Storage shape (Redis source vs PG source): TTL убран, финальное распределение responsibility отложено.
- Связь с Data Quality Dashboard (RFC-022) — отдельная тема, см. → data-quality-dashboard (placeholder)
- Recognition multi-date / multi-page PDF — соседняя тема, активная сейчас, см. → recognition (placeholder)
Связано
- loinc-harmonization-pipeline — алгоритм
- loinc-harmonization-service — текущий Python service (target → retire)
- normalization-service — старая нормализация (target → fallback)
- inngest — substrate для queue/orchestration вместо ad-hoc Python
- loinc — стандарт
- agent-vs-workflow — design philosophy для TS-port
- dictionary-first-paradigm — связанное decision (idea)
- override-storage-design — связанное decision (storage)
Источники
Сноски
-
Mar 20 1:1 transcript (primary), accessed 2026-05-17, https://github.com/Realai-plus/meeting-digests/blob/main/data/digest/2026/03/2026-03-20T13%3A09%3A00.000Z_Про_портирование_нормализации_01KM5NSEK9TYP3QZM5YYNDSF7Q.md. ↩
-
Apr 1 group transcript, accessed 2026-05-17, https://github.com/Realai-plus/meeting-digests/blob/main/data/digest/2026/04/2026-04-01T11%3A07%3A08.000Z_портирование_loinc_01KN4BKJSP8PSGBSN23VFZ25M0.md. ↩
-
Mar 18 stack debate (Mastra vs LangGraph vs Python), accessed 2026-05-17, https://github.com/Realai-plus/meeting-digests/blob/main/data/digest/2026/03/2026-03-18T08%3A59%3A18.000Z_Обсуждаем_прогресс_по_бенчмарку_FHIR_01KM02QE1QSR5SAZP6YE2NP9Z1.md. ↩
-
Сессия
ildar/c8967f27, 2026-03-02 — ` (Mar 3 architecture). ↩ -
Сессия
ildar/fd4858f8, 2026-03-02 — ` (UI prototype BG-864). ↩ -
Сессия
ildar/833ec924, 2026-03-24 —+82806132+fc708f24` (Mastra-port progression). ↩ -
Сессия
ildar/82806132, 2026-04-05 —+fc708f24` (Mastra-port progression). ↩ -
Сессия
ildar/fc708f24, 2026-03-26 — ` (Mastra-port progression). ↩ -
Linear BG-876, accessed 2026-05-17, https://linear.app/realai/issue/BG-876 — , BG-1023, BG-864, BG-848. ↩