Технологический стек¶
[ТЗ] Ограничение: разрабатываемые подсистемы строятся только на свободно распространяемом ПО (см. «Требование свободного ПО»). Поэтому у каждой позиции указана лицензия — это не украшение, а предмет проверки при приёмке.
Серверная часть¶
| Слой | Выбор | Лицензия | Альтернативы |
|---|---|---|---|
| ОС сервера | Debian 12 / Astra Linux SE | GPL / — | Ubuntu Server LTS |
| Веб-сервер, TLS, mTLS | nginx | BSD-2-Clause | Traefik (MIT) |
| Backend API | Node.js 22 / NestJS | MIT | Java 17 / Spring Boot (Apache-2.0); Python / FastAPI (MIT) |
| Runtime | Node.js 22 | MIT | — |
| Работа с FHIR | @medplum/fhirtypes (TS-типы R4) + FHIR JSON Schema |
Apache-2.0 | HAPI FHIR (Apache-2.0, Java) |
| СУБД | PostgreSQL 16 | PostgreSQL License | MySQL 8 (GPL-2.0) |
| ORM / миграции | TypeORM + migrations | MIT | Prisma (Apache-2.0) |
| Планировщик | @nestjs/schedule (опрос координат) |
MIT | node-cron (ISC) |
| Брокер / буфер | RabbitMQ или Redis | MPL-2.0 / BSD-3 | без брокера на MVP |
| Realtime на пульт | WebSocket (NestJS Gateway) | MIT | SSE |
| Frontend | Angular 19 + TypeScript | MIT | React 19 (MIT) | | Наблюдаемость | Prometheus + Grafana | Apache-2.0 / AGPL-3.0 | Zabbix (GPL-2.0) | | Контейнеризация | Docker Compose | Apache-2.0 | Podman (Apache-2.0) | | Резервное копирование | pgBackRest | MIT | barman (GPL-3) |
Смена СУБД относительно первоначальной проработки
Операционное требование называет «MySQL, PostGR» как равнозначные варианты. Выбран PostgreSQL по трём причинам, значимым именно для этого проекта:
- Партиционирование по времени из коробки —
ambulance_locations,vital_observationsи журналы событий ИБ растут быстро, а хранить их нужно не менее года (FR-C-2). Декларативные партиции по дате и их отцепление — штатная операция. - JSONB с индексацией — сырые FHIR-Bundle и ответы вендоров хранятся как есть для разбора инцидентов; по ним нужен поиск.
- Лицензия PostgreSQL либеральнее GPL-2.0 у MySQL, что снимает вопросы при тиражировании на другие УЗ.
Миграция на MySQL 8 остаётся возможной: ORM и миграции абстрагированы, специфичные для PostgreSQL конструкции локализованы в партиционировании и JSONB-индексах. Решение — за заказчиком; DDL в data/schema.md приведён в переносимом виде с пометками.
Компоненты по подсистемам¶
flowchart TB
subgraph T["«Триаж»"]
direction LR
GW["FHIR-шлюз<br/>приём от СМП"] --> RULE["Движок правил<br/>сортировки"] --> QUEUE["Очередь<br/>и талоны"]
GEO["Воркер<br/>координат"] --> PULT["Пульт<br/>(Angular)"]
KIOSK["Терминал<br/>самообращения"]
end
subgraph SHARED["Общая платформа"]
direction LR
AUTH["Аутентификация<br/>RBAC · ЭЦП"]
PAT["Каталог<br/>пациентов"]
AUD["Аудит и журнал<br/>событий ИБ"]
MISAD["Адаптер МИС"]
BUS["Шина уведомлений<br/>RabbitMQ + WebSocket"]
end
DB[("PostgreSQL 16 · партиции · JSONB")]
T --> SHARED
SHARED --> DB
Обоснование ключевых выборов¶
NestJS / Node.js. Профиль нагрузки — сетевой ввод-вывод: приём вебхуков, опрос внешних API, обслуживание WebSocket. Асинхронная модель здесь уместнее многопоточной, а объём вычислений мал (движок правил работает на десятках условий, не на моделях). Дополнительно: одна экосистема (TypeScript) и для сервера, и для клиента — Angular, что сокращает порог входа для команды и дублирование типов между бэкендом и фронтендом.
@medplum/fhirtypes + FHIR JSON Schema. Типы FHIR R4 — встроенные TypeScript-определения от Medplum. Валидация сообщений — по официальным JSON Schema HL7 FHIR, что не уступает по строгости HAPI FHIR и не требует отдельного Java-процесса. Весь стек остаётся в единой TypeScript / Node.js экосистеме.
RabbitMQ. Изменение состояния пациента в пути — события, которые нельзя терять при перезапуске сервиса. Брокер с персистентными очередями закрывает это, а также буферизует всплески при массовом поступлении (FR-T-25), когда сообщения от СМП идут пачкой.
Клиентские устройства¶
[ТЗ] Закупаемое оборудование определяет ограничения на клиентскую часть — состав и характеристики в «Аппаратном комплексе».
| Устройство | Платформа | Что на нём работает |
|---|---|---|
| Терминал самообращения | Windows 10 Pro, i3, 23,6″ PCAP | Веб-киоск: кнопка регистрации обращения, печать талона, сканер ШК |
| АРМ тип 2 (44 шт.) | Windows 10 Pro, Ryzen 5600 | Браузер: пульт, сортировка, оформление |
| Планшет (2 шт.) | Android, IP65, сканер ШК | Обход у койки, идентификация по браслету |
Веб-клиент обязан работать в браузере АРМ
44 АРМ и терминал самообращения поставляются с Windows 10 Pro. Целевой браузер и его минимальная версия должны быть зафиксированы в частном ТЗ, иначе на приёмке всплывёт несовместимость. [ПР] Ориентир — Chromium-совместимый браузер последней стабильной версии; поддержка Internet Explorer не предусматривается. См. R-11.
Инструменты разработки¶
| Назначение | Инструмент | Лицензия |
|---|---|---|
| Документация | MkDocs + Material (этот сайт) | BSD-2 / MIT |
| Диаграммы | Mermaid | MIT |
| Сборка клиента | Angular CLI | MIT |
| Тесты | Jest + @nestjs/testing |
MIT |
| Контрактные тесты FHIR | фикстуры вендоров + JSON Schema | — |
| Линт / формат | ESLint + Prettier | MIT |
| CI | GitLab CI (self-hosted) или Woodpecker | MIT / Apache-2.0 |
| Нагрузочное тестирование | k6 (Grafana) | AGPL-3.0 |
Нагрузочное тестирование — не опция
Этап 1 паспорта прямо включает «тестирование созданной информационной системы на предмет быстродействия, уязвимости, отказоустойчивости». Сценарии и целевые значения — в «Нефункциональных требованиях», задачи — в эпике E11.