Ресурс для записи произведённой процедуры — операции, эндоскопии, диализа, физиотерапии, психотерапии. От ServiceRequest (запрос на процедуру) и CarePlan.activity (план процедуры) отличается тем, что Procedure — это зафиксированный факт что процедура была выполнена.

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

  • Источник — narrative-to-FHIR pipeline. LLM extracted entities → ExtractedProcedureSchemabuildProcedure() в narrative-to-fhir/fhir-builders/procedure.ts.
  • Данные обычно из выписок (история операций) или patient-reported анамнеза («гастроскопия в 2018»).
  • Resource не emit’ит category — gap для иконок Timeline.

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

  • subjectPatient/{id}
  • code — что за процедура (CodeableConcept). SNOMED CT когда coder нашёл (см. snomed), иначе только text. SNOMED coder Артура с May 2026 audit — fixed wrong-concept bugs (например 30242009 был для «hyperplastic polyp» а это «scarlet fever»).
  • status — у нас всегда "completed" hardcoded (ну narrative не сообщает про in-progress / not-done процедуры).
  • performedDateTime — когда сделана. Если LLM extracted дата parse’ится — performedDateTime (ISO). Если фраза вроде «5 years ago» / «May 2024» / «2018» которая не parse’ится в strict date — performedString (R4-compliant free-text alternative).
  • bodySite — необязательно (LLM extracted)
  • outcome — необязательно (LLM extracted, как text)
  • note[]details + findings если LLM extracted
  • category — НЕ выставляется (gap). Стандартные значения SNOMED-based, broad:
    • 387713003 Surgical procedure
    • 103693007 Diagnostic procedure
    • 409063005 Counselling
    • 409073007 Education
    • 410606002 Social service procedure

Date handling — performedDateTime vs performedString

LLM из narrative часто даёт нечёткие даты («5 лет назад», «в начале 2024», «около 2018»). GCP Healthcare API rejects malformed dateTime values. Поэтому мы делаем fallback:

if (extracted.date) {
  const iso = sanitizeFhirDateField(extracted.date);
  if (iso) {
    resource.performedDateTime = iso;
  } else {
    resource.performedString = extracted.date;  // R4-compliant free-text
  }
}

Это означает что для clinical timeline некоторые процедуры будут с точной датой, некоторые с string — Timeline UI должен handle оба.

Failure modes

  • Singular 0..1 category — одна категория на ресурс. Если процедура одновременно «surgical + diagnostic» (например, биопсия — surgical procedure с diagnostic intent), приходится выбрать одну.
  • performedString не сортируется — если процедура с string-date («5 лет назад»), на timeline её положить не на чёткую точку. Решение TBD: вычислять из performedString относительно recordedDate?
  • SNOMED coder может не найти код — fallback на text-only. Это normal для редких процедур.

Открытые вопросы

  • Какой default category ставить если LLM не классифицирует? Варианты: вообще не выставлять (текущее поведение — gap), default 103693007 Diagnostic procedure (большинство наших случаев), или extract из LLM в новый schema field.
  • Добавлять ли category в ExtractedProcedureSchema чтобы LLM сам классифицировал (как для Observation/AllergyIntolerance)?

Связанные решения

  • [[../domain/category-coverage]] (TBD) — рамки category coverage
  • [[../domain/fhir-resource-origin-and-lifecycle]] — origin (user-uploaded vs document-extracted)

Связано

  • [[fhir-resource-categories]] — общая концепция (включая gap)
  • [[fhir-condition]] — Procedure может быть reason для Condition или vice versa
  • [[fhir-careplan]] — CarePlan.activity описывает планируемые procedure’ы; Procedure — выполненные
  • snomed — coding system для Procedure.code

Источники

Источники: 1 2.

Сноски

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

  2. ValueSet procedure-category (example, SNOMED-based), accessed 2026-05-17, https://hl7.org/fhir/R4/valueset-procedure-category.html.