Перейти к содержанию

Sequence-диаграммы

Основные сценарии обмена. Участники сокращены: СМП — сервер станции, GWfhir-gateway, COREtriage-core, МИС — АИС «Медик», ПУЛЬТ — центральный пульт оператора.

1. Запрос на возможность госпитализации

Единственный сценарий с синхронным содержательным ответом.

sequenceDiagram
  autonumber
  participant SMP as Сервер СМП
  participant GW as fhir-gateway
  participant CORE as triage-core
  participant OP as Оператор
  participant DB as БД

  SMP->>GW: POST transport_request (Bundle)
  GW->>GW: mTLS + валидация FHIR
  GW->>DB: inbound_messages (raw)
  GW->>CORE: запрос решения
  CORE->>DB: профиль отделения, занятость
  alt место есть и профиль подходит
    CORE-->>GW: accepted
  else требуется решение человека
    CORE->>OP: уведомление на пульт
    OP-->>CORE: подтверждение / отказ
    CORE-->>GW: accepted | rejected | conditional
  else таймаут ожидания оператора
    CORE-->>GW: conditional (по умолчанию)
  end
  GW->>DB: bed_requests (решение + основание)
  GW-->>SMP: Bundle с MessageHeader.response

Таймаут обязателен

Бригада стоит у пациента и ждёт ответа. Сценарий «оператор отошёл» не должен приводить к бесконечному ожиданию: по истечении таймаута ([ПР] 30 с) возвращается conditional с пояснением, что решение требует уточнения по телефону. Молчание хуже любого ответа.

2. Направление → регистрация → пульт → (ручная) передача в МИС

Центральный сценарий подсистемы «Триаж».

sequenceDiagram
  autonumber
  participant SMP as Сервер СМП
  participant GW as fhir-gateway
  participant MQ as RabbitMQ
  participant CORE as triage-core
  participant RULES as rules-engine
  participant GEO as geo-worker
  participant PULT as Пульт
  participant OP as Оператор
  participant MIS as МИС «Медик»

  SMP->>GW: POST transport_notification
  GW->>GW: проверка идемпотентности
  GW->>MQ: событие
  GW-->>SMP: 202 Accepted
  MQ->>CORE: доставка
  CORE->>CORE: сопоставление/создание пациента
  CORE->>CORE: transport_notifications + исходные наблюдения
  CORE->>RULES: расчёт рекомендации
  RULES-->>CORE: рекомендуемый цвет + обоснование
  CORE->>GEO: подписка на координаты машины
  CORE->>PULT: карточка пациента (WebSocket)

  Note over PULT,OP: Оператор видит состояние,<br/>диагноз и рекомендацию системы

  alt тяжёлый: нужна бригада встречи
    OP->>CORE: «Передать в МИС»
    CORE->>MIS: request_team (mis_handoffs)
    MIS-->>CORE: подтверждение
    MIS->>MIS: сбор бригады, рассылка врачам
    CORE->>PULT: статус «бригада собирается»
  else обычный пациент
    Note over CORE: в МИС не передаётся,<br/>идёт на общую сортировку
  end

Рекомендация системы ≠ решение системы

rules-engine считает цвет и показывает его оператору с обоснованием («ЧД 28, сатурация 89 % — правило R-12»). Решение о передаче в МИС принимает человек (FR-T-11, ADR-4). Все решения оператора — и совпадающие с рекомендацией, и расходящиеся — протоколируются: расхождения дают материал для настройки правил.

3. Изменение состояния в пути

sequenceDiagram
  autonumber
  participant SMP as Сервер СМП
  participant GW as fhir-gateway
  participant CORE as triage-core
  participant RULES as rules-engine
  participant PULT as Пульт

  loop каждое обновление состояния
    SMP->>GW: POST transport_health_status
    GW->>CORE: наблюдения (дедупликация)
    CORE->>CORE: vital_observations
    CORE->>RULES: пересчёт по новым значениям
    alt цвет ухудшился
      RULES-->>CORE: red (было yellow)
      CORE->>PULT: подсветка карточки + звук
      Note over PULT: «Ухудшение: ЧД 32, SpO₂ 85 %»
    else без изменений
      CORE->>PULT: обновление показателей
    end
  end

4. Опрос координат

sequenceDiagram
  autonumber
  participant GEO as geo-worker
  participant PROV as Сервер координат
  participant DB as БД
  participant PULT as Пульт

  loop по расписанию провайдера
    GEO->>DB: список активных машин
    GEO->>PROV: запрос позиций
    GEO->>DB: location_requests (лог запроса)
    alt успех
      PROV-->>GEO: позиции + source_time
      GEO->>DB: ambulance_locations
      GEO->>PULT: обновление карты
    else отказ или таймаут
      PROV--xGEO: ошибка
      GEO->>DB: location_requests (is_success=false)
      GEO->>PULT: пометка «координаты устарели N мин»
    end
  end

Лог пишется до получения ответа

Запись в location_requests создаётся на каждый запрос независимо от исхода — это требование группы данных 4 (лог запросов, а не лог координат). Неуспешные запросы важнее успешных: по ним разбирается, почему машина пропала с карты.

5. Отмена транспортировки

sequenceDiagram
  autonumber
  participant SMP as Сервер СМП
  participant GW as fhir-gateway
  participant CORE as triage-core
  participant GEO as geo-worker
  participant MIS as МИС «Медик»
  participant PULT as Пульт

  SMP->>GW: POST transport_cancel
  GW->>CORE: событие отмены
  CORE->>CORE: status = cancelled, причина
  CORE->>GEO: отписка от координат
  CORE->>PULT: снятие карточки с борда
  alt бригада встречи уже собиралась
    CORE->>MIS: cancel_notice
    MIS->>MIS: роспуск бригады, уведомление врачей
    Note over MIS: иначе специалисты ждут<br/>пациента, которого не будет
  end
  CORE->>CORE: освобождение резерва места

6. Доставка и приём пациента

sequenceDiagram
  autonumber
  participant SMP as Сервер СМП
  participant GW as fhir-gateway
  participant CORE as triage-core
  participant NURSE as Медработник приёмника
  participant DB as БД

  SMP->>GW: POST transport_complete
  GW->>CORE: событие доставки
  CORE->>DB: deliveries.delivered_at (отсечка СМП)
  CORE->>CORE: status = delivered
  CORE->>NURSE: карточка «прибыл, ожидает приёма»

  Note over NURSE: физическая передача пациента

  NURSE->>CORE: подтверждение приёма
  CORE->>DB: deliveries.accepted_at, accepted_by
  CORE->>DB: appeals (создание обращения)
  CORE->>DB: triage_queue (постановка в очередь)
  Note over DB: разница accepted_at − delivered_at =<br/>время ожидания машины у приёмника

7. Самообращение: терминал → анонимная очередь

sequenceDiagram
  autonumber
  participant PAT as Пациент
  participant KIOSK as Терминал самообращения
  participant CORE as triage-core
  participant NURSE as Медсестра сортировки
  participant PRN as Принтер талонов

  PAT->>KIOSK: «ЗАРЕГИСТРИРОВАТЬ ОБРАЩЕНИЕ<br/>В ПРИЕМНЫЙ ПОКОЙ»
  KIOSK->>CORE: создание обращения
  CORE->>CORE: appeals (source=self, patient_id=NULL)
  Note over CORE: паспортная часть НЕ заполняется —<br/>анонимная очередь (FR-T-15)
  CORE-->>KIOSK: номер в очереди на сортировку
  KIOSK->>PRN: печать номера

  Note over PAT,NURSE: вызов на сортировку

  NURSE->>CORE: оценка: пол, температура,<br/>состояние, вес, дыхание
  CORE->>CORE: rules-engine → цвет
  CORE->>CORE: triage_assessments + triage_queue
  CORE->>PRN: печать талона К43 / В34 / П45
  PRN-->>PAT: талон с цветом и кодом

8. Оформление и передача обращения в МИС

sequenceDiagram
  autonumber
  participant CORE as triage-core
  participant REG as Регистратор
  participant MIS as МИС «Медик»
  participant DB as БД

  CORE->>REG: вызов по талону<br/>(красные → жёлтые → зелёные)
  alt пациент доставлен СМП
    CORE->>REG: форма с ПРЕДЗАПОЛНЕННЫМИ данными
    Note over REG: паспортная часть и данные<br/>транспортировки из данных СМП (FR-T-19)
  else самообращение
    CORE->>REG: пустая форма паспортной части
  end
  REG->>CORE: заполнение и подтверждение
  REG->>CORE: подписание ЭЦП
  CORE->>DB: appeals.status = registered
  CORE->>MIS: push_appeal (mis_handoffs)
  alt МИС доступна
    MIS-->>CORE: mis_reference
    CORE->>DB: handoff acknowledged
  else МИС недоступна
    CORE->>DB: handoff pending, retry с backoff
    CORE->>REG: индикатор «ожидает передачи в МИС»
    Note over CORE: обращение НЕ теряется,<br/>работа приёмника не блокируется
  end

Недоступность МИС не должна останавливать приём пациентов

Если передача в МИС выполняется синхронно и блокирующе, отказ МИС останавливает работу приёмного отделения целиком. Обращение сохраняется локально и ставится в очередь на повтор; регистратор видит индикатор, но продолжает принимать следующих пациентов.