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

Архитектурные решения (ADR)

Каждое решение — с обоснованием и последствиями. Формат сжатый: контекст → решение → почему → чем платим.

# Решение Обоснование
ADR-1 Приём данных от СМП — push, сервер-сервер, минуя ЦИСЗ Опрос сервера СМП недоступен; ЦИСЗ наполняется ретроспективно и для realtime непригодна
ADR-2 Каноническая внутренняя модель на базе HL7 FHIR + ACL-адаптер на каждого вендора Обязательность FHIR по приказу МЗ РБ № 1001 + три оси мультипровайдерности
ADR-3 Идемпотентность по идентификатору сообщения Ретраи и повторные доставки не должны плодить дубли направлений
ADR-4 Ручной шлюз в МИС для сбора бригады; автоматически — только регистрация направления Прямое требование FR-T-11
ADR-5 Разделение «направление» и «обращение»; appeals — центральная сущность Единый ключ для СМП-пациентов и самообращений
ADR-6 Координаты — отдельный воркер-планировщик с pull-адаптерами FR-T-6/FR-T-7: источники разные, темп опроса свой, отказ источника не должен ронять приём сообщений
ADR-7 Правила сортировки — декларативные, в БД, не в коде FR-T-17: правила меняются медперсоналом и подлежат согласованию; перекомпиляция недопустима
ADR-8 Одна подсистема на общей платформе: общий каталог пациентов, аутентификация, аудит, БД Один ПАК по паспорту
ADR-9 Интеграция с ЦИСЗ — только через МИС Прямо следует из паспорта: запрос данных «напрямую из МИС учреждения»
ADR-10 Полевые устройства RS-485 подключаются через шлюз-конвертер, а не напрямую к приложению Изоляция полевой шины от IP-контура; требование сегментирования сети управления
ADR-11 Только свободно распространяемое ПО в составе разрабатываемых подсистем Прямое требование паспорта
ADR-12 On-prem развёртывание в контуре УЗ Заключение о нецелесообразности размещения на РЦОД

ADR-1. Push-модель приёма данных от СМП

Контекст. Данные о пациенте нужны до его прибытия. Есть три теоретических источника: ЦИСЗ, опрос сервера СМП, приём от сервера СМП.

Решение. 3H слушает выделенный порт в контуре УЗ; сервер СМП инициирует соединение и отправляет сообщения. Опрос стороны СМП не выполняется. ЦИСЗ как realtime-источник не используется.

Почему. Данные попадают в ЦИСЗ ретроспективно — к моменту, когда карета уже приехала, что делает её бесполезной для сценария подготовки к встрече. Опрос сервера СМП не согласован вендорами и не масштабируется на несколько поставщиков.

Чем платим. 3H не контролирует темп поступления данных и не может «дозапросить» пропущенное. Отсюда обязательны: идемпотентность (ADR-3), буферизация всплесков, и детектор «тишины» — направление, по которому давно не приходило обновлений, помечается как подозрительное на пульте, а не молча висит.


ADR-2. Каноническая модель на базе FHIR + ACL на каждого вендора

Контекст. Приказ МЗ РБ № 1001 делает HL7 FHIR обязательным. При этом у каждого поставщика ПО СМП свой протокол API, и требуется одновременная поддержка нескольких.

Решение. Внутренняя каноническая модель строится на ресурсах FHIR R4. Для каждого вендора пишется Anti-Corruption Layer — адаптер, переводящий его формат в каноническую модель. Ядро системы о вендорах не знает.

Почему. Иначе особенности формата первого вендора протекут в схему БД и бизнес-логику, и второй вендор потребует переписывания ядра — ровно то, что убивает тиражируемость (см. масштабирование).

Чем платим. Слой перевода — дополнительный код и дополнительное место для ошибок. Компенсируется тем, что каждый адаптер изолирован, тестируется отдельно на фикстурах вендора и не может сломать другие.


ADR-3. Идемпотентность входящих сообщений

Контекст. Push-модель без подтверждений на прикладном уровне означает, что вендор будет ретраить при любой сетевой ошибке.

Решение. Каждое входящее сообщение несёт идентификатор (Bundle.identifier либо заголовок корреляции). Уникальный индекс по паре «провайдер + идентификатор» в таблице входящих. Повтор возвращает тот же результат, что и первая обработка, без побочных эффектов.

Почему. Дубль направления — это дубль пациента на борде, потенциально дубль собранной бригады и испорченная статистика КПЭ.

Чем платим. Требуется, чтобы вендор передавал стабильный идентификатор. Если не передаёт — fallback на хеш канонизированного тела; это менее надёжно и должно логироваться как деградация. Открытый вопрос к вендору.


ADR-4. Ручной шлюз в МИС для сбора бригады

Контекст. Не каждому едущему пациенту нужна бригада встречи. Пациент с высоким давлением и пациент с подозрением на инфаркт требуют разной реакции.

Решение. Регистрация направления и появление пациента на борде — автоматические. Передача в МИС для сбора бригады — явное действие оператора по кнопке.

Почему. Прямое требование заказчика. Автоматическая передача всех подряд обесценит механизм: бригады перестанут реагировать на оповещения.

Чем платим. Качество работы зависит от оператора: он может не заметить тяжёлого пациента. Смягчение: система подсказывает рекомендацию на основе правил (FR-T-17) и визуально выделяет кандидатов, но не решает за оператора. Решения оператора протоколируются — это даёт данные для последующей настройки правил.


ADR-5. Разделение «направления» и «обращения»

Контекст. В приёмник попадают два потока: доставленные СМП и обратившиеся самостоятельно. Дальше они идут по одному маршруту (сортировка → очередь → оформление → выбытие).

Решение. transport_* описывает транспортный эпизод (только для СМП). appealsобращение в приёмный покой, единая сущность для обоих потоков, к которой привязаны сортировка, очередь, оформление и выбытие. Обращение СМП-пациента ссылается на своё направление; самообращение — нет.

Почему. Иначе вся логика очереди и сортировки удваивается под два типа пациентов, а метрики КПЭ («пациентов в час») невозможно посчитать единообразно.

Чем платим. Один лишний уровень косвенности при чтении данных СМП-пациента.


ADR-6. Координаты — отдельный воркер с pull-адаптерами

Контекст. В отличие от данных о пациенте, координаты опрашиваются (FR-T-6). Источники разные: у одного вендора собственный GPS-сервер, у другого — отдельный сервер маршрутизации стороннего ПО.

Решение. Отдельный процесс-планировщик с адаптером на источник, пишущий в ambulance_locations и в лог запросов. Пульт читает из БД и получает обновления по WebSocket.

Почему. Разделение push-приёма и pull-опроса: недоступность GPS-сервера вендора не должна влиять на приём медицинских данных. У источников разные лимиты частоты опроса.

Чем платим. Задержка между реальным положением и отображаемым — в пределах периода опроса. Период конфигурируется на провайдера.


ADR-7. Правила сортировки — декларативные, в БД

Контекст. FR-T-17 требует алгоритмов на основе правил по клиническому протоколу МЗ РБ № 1030. Конкретные пороги на момент проектирования не утверждены.

Решение. Правила хранятся как версионируемые записи в БД: условие по витальным показателям/возрасту/поводу → цвет и приоритет. Движок правил интерпретирует их во время выполнения. Каждое срабатывание протоколируется с указанием версии правила.

Почему. Правила будет менять медперсонал, а не разработчик; изменение обязано быть прослеживаемым и не требовать релиза. Версионирование обязательно: при разборе клинического случая нужно знать, по какой редакции правил был присвоен цвет.

Чем платим. Движок правил сложнее, чем if в коде, и требует UI редактирования и валидации. Оправдано тем, что альтернатива — релиз на каждое изменение медицинского регламента.


ADR-8. Одна подсистема на общей платформе

Контекст. Паспорт финансирует один ПАК.

Решение. Общие: БД-кластер, каталог пациентов, аутентификация/RBAC, аудит, интеграция с МИС, шина уведомлений. Прикладной сервис: «Триаж».

Почему. Выделение общей платформы позволяет тиражировать решение на другие УЗ без дублирования инфраструктурной работы.

Чем платим. Нужен контракт между общими и прикладными сервисами и дисциплина его соблюдения.


ADR-9. Интеграция с ЦИСЗ — только через МИС

Контекст. Паспорт перечисляет ресурсы FHIR для обмена с ЦИСЗ, что можно прочитать как требование прямого подключения 3H к ЦИСЗ.

Решение. Подсистемы ПАК не подключаются к ЦИСЗ напрямую. Контрагент — МИС «Медик»; она уже подключена к ЦИСЗ и владеет ЭМК.

Почему. Паспорт указывает способ взаимодействия как «использование API для запроса данных из ЦИСЗ напрямую из МИС учреждения», а отправку — «посредством интеграционной шины центральной платформы». Прямое подключение продублировало бы функцию МИС, потребовало бы отдельной аттестации канала и создало бы второй источник истины по ЭМК.

Чем платим. Зависимость от полноты API МИС. Если «Медик» не отдаёт нужные данные, потребуется её доработка — а паспорт фиксирует, что доработка МИС не требуется. Это риск, вынесенный в R-4.


ADR-10. Полевые устройства через шлюз-конвертер

Контекст. Полевые устройства работают с RS-485/RS-232.

Решение. Полевая шина заводится в IP-контур через преобразователи интерфейсов (паспорт предусматривает 8 шт.). Приложение общается со шлюзом по IP; драйвер протокола конкретного устройства изолирован в отдельном модуле.

Почему. Требование сегментирования сети управления объектами ИС от сети передачи данных.

Чем платим. Шлюз — точка отказа для сегмента. Нужен мониторинг доступности шлюзов.


ADR-11. Только свободно распространяемое ПО

Контекст. Прямое требование паспорта с обоснованием: свободная установка без лицензионных отчислений и возможность модификации исходного кода.

Решение. Все компоненты разрабатываемых подсистем — под свободными лицензиями. Каждая позиция стека сопровождается указанием лицензии. Проприетарные компоненты в составе разрабатываемого ПО не используются.

Почему. Требование паспорта; кроме того, тиражирование на ≥6 УЗ делает per-seat лицензирование экономически несостоятельным.

Чем платим. Отказ от коммерческих FHIR-серверов и интеграционных платформ с готовыми коннекторами. Часть работы, которую они бы закрыли, придётся написать самим — это учтено в оценках эпиков E2 и E3.


ADR-12. On-prem развёртывание в контуре УЗ

Контекст. Указ № 46 и Постановление СМ № 182 требуют оценки целесообразности размещения на РЦОД.

Решение. Развёртывание на серверной платформе в УЗ. Паспорт предусматривает закупку сервера (2 × Xeon Silver 4314, 64 ГБ, 4 × 960 ГБ SSD, RAID, 1U).

Почему. Подготовлено ТЭО с заключением о нецелесообразности размещения на РЦОД, направленное в ОАЦ и оператору РЦОД.

Чем платим. Резервирование, бэкапы и обновления — забота УЗ.