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 (пока порт не закончен)
  • Два пути в тренды (ParameterV2Id legacy + TrendingGroupId LOINC) → дублирует 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)

Связано

Источники

Источники: 1 2 3 4 5 6 7 8 9.

Сноски

  1. 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.

  2. 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.

  3. 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.

  4. Сессия ildar/c8967f27, 2026-03-02 — ` (Mar 3 architecture).

  5. Сессия ildar/fd4858f8, 2026-03-02 — ` (UI prototype BG-864).

  6. Сессия ildar/833ec924, 2026-03-24 — +82806132+fc708f24` (Mastra-port progression).

  7. Сессия ildar/82806132, 2026-04-05 — +fc708f24` (Mastra-port progression).

  8. Сессия ildar/fc708f24, 2026-03-26 — ` (Mastra-port progression).

  9. Linear BG-876, accessed 2026-05-17, https://linear.app/realai/issue/BG-876 — , BG-1023, BG-864, BG-848.