Clinical document в FHIR — это структурированный документ с medical-семантикой: набор разнородных утверждений о пациенте, организованный в иерархию секций, с явным авторством и статусом. Аналог — как если бы заключение врача или выписку оформить в виде FHIR-ресурса. В отличие от отдельной Observation (одно измерение) или CarePlan (план действий), Composition — это законченный документ-снимок с разделами и nested структурой, который можно отдать целиком клиенту/партнёру.

Composition группирует контент в иерархию section[], в каждой секции может быть произвольное содержимое — текст, ссылки на FHIR-ресурсы, sub-секции. Плюс metadata об авторе, статусе, типе документа.

Использование в BloodGPT

  • Test-level AI overviewTestOverview BloodGPT-таблица маппится на Composition с nested секциями: Interpretation, Patterns, Health Considerations, Pay Attention, Panel Overviews, Trends (последняя добавлена в session 065369a0, sub-sections per parameter с trendAnalysis). Реализация: fhir-composition-builder.ts. См. fhir-modeling-ai-content.

  • Subject — Patient, не DiagnosticReport. Composition.subject ссылается на пациента, не на test-сущность. Связь с DiagnosticReport — опциональная, через section.entry. Это enabler для snapshot-центричной архитектуры (health-report-vision) — Composition уже привязан к пациенту, может жить без теста. Сейчас в коде test-attribution идёт через identifier (см. ниже), не через subject.

  • event для триггера (потенциал, не используется). Composition.event[] — built-in поле “что послужило триггером для документа”. Сейчас не заполняется. Если перейдём на snapshot-центрик — это место для ссылки на trigger (DiagnosticReport / Condition / MedicationStatement / time-event).

  • Концептуально совместимо с IPS Patient Summaryips-standard использует Composition как root для IPS Bundle. У нас собственного IPS-документа сейчас нет — мы используем Composition только для test-level overview. Концептуально могли бы добавить Patient-level Composition на базе IPS-стандарта, но пока такого ресурса не существует.

Ключевые поля для нас

  • section[] — массив секций. Поддерживает nested sub-sections — секция может содержать дочерние секции (через рекурсивный section.section[]). У нас это используется для иерархии TestOverview: pattern → biomarkers, recommendation → category. По спецификации в section можно положить что угодно через section.entry[] (см. ниже) или прямо текст через section.text.

  • section.entry[] — массив Reference на FHIR-ресурсы. Это стандартное FHIR-поле, не наша придумка. Семантика: “эта секция документа основана на следующих ресурсах”. У нас supporting biomarkers в pattern-секции → entry-references на соответствующие fhir-observation. То есть когда документ говорит “у пациента признаки железодефицита”, он ссылается через entry на конкретные Observations с низким ferritin/hemoglobin как доказательство.

  • subjectPatient/{id}, ссылка на пациента-владельца документа.

  • identifier — обратная ссылка на нашу систему. { system: "bloodgpt.com/.../test-id", value: "bloodtest-xyz" } — это наш внутренний ID конкретного теста (в Prisma BloodTest). Используется для search: когда фронтенд хочет найти AI-overview по конкретному тесту, он ищет по identifier. Без этого пришлось бы искать по subject + type + date — менее точно. Identifier = “обратная ссылка на наши сущности из FHIR-ресурса”.

  • author[x] — choice type, см. fhir-annotation для механики. У нас fhir-device (исторически) → fhir-organization Organization/bloodgpt (после 2026-02-17, см. authorship-organization-not-device). Vendor-limit: Healthcare API не принимает Device в author[x].

  • extension — единственный custom-extension у нас: requiresDoctorPreparation (см. ниже).

requiresDoctorPreparation — что это

Boolean-флаг, который AI выставляет когда считает что результаты теста требуют подготовки врача перед обсуждением с пациентом. Например: серьёзные отклонения, неоднозначные паттерны, найдены маркеры требующие медицинского контекста. Сигнализирует UI/workflow что этот тест нельзя просто показать пациенту “как есть” — врач должен предварительно посмотреть и сформулировать explanation.

В FHIR это реализовано как extension на Composition:

{
  "extension": [{
    "url": "http://bloodgpt.com/fhir/StructureDefinition/requires-doctor-preparation",
    "valueBoolean": true
  }]
}

Стандартного FHIR-аналога нет, поэтому это единственный custom extension во всей нашей FHIR-модели (см. zero-extensions-fhir). Зеркалится в Prisma как TestOverview.requiresDoctorPreparation Boolean — флаг используется и для UI вне FHIR-context.

Поиск

GET Composition?subject=Patient/{id}&type=test-overview&identifier={testId}

Один Composition на тест (не один на пациента — у пациента может быть много тестов и для каждого свой test-overview Composition).

Связано

  • fhir-careplan — параллельный ресурс для follow-up рекомендаций
  • fhir-observation — supporting biomarkers ссылаются обратно
  • fhir-bundle — Composition хранится внутри Bundle для transactional create
  • fhir-organization — author target (Organization/bloodgpt)
  • ips-standard — IPS использует Composition как root (в нашей системе concept-fit, не реализован)
  • fhir-modeling-ai-content — overview маппинга
  • health-report-vision — exploratory direction где Composition становится snapshot-центричным
  • zero-extensions-fhir — почему 1 extension вместо многих

Источники

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

Сноски

  1. HL7 R4 spec, accessed 2026-05-17, https://hl7.org/fhir/R4/composition.html.

  2. Реализация, accessed 2026-05-17, https://github.com/Realai-plus/bloodgpt-for-business/blob/main/packages/analysis-core/src/lib/fhir-composition-builder.ts.

  3. Prisma schema, accessed 2026-05-17, https://github.com/Realai-plus/bloodgpt-for-business/blob/main/packages/database/prisma/schema.prisma — модель TestOverview, поле requiresDoctorPreparation).

  4. Сессия ildar/18d2aef8, 2026-01-30 — (origins).

  5. Сессия ildar/871a7608, 2026-02-13 — (маппинг design).

  6. Сессия ildar/065369a0, 2026-03-14 — (Trends section + subject=Patient + event как trigger placeholder).