О проекте RDD (Registry-Driven Development)
RDD — это специализированный веб-регистр для лонгитюдного ведения пациентов с рекуррентным депрессивным расстройством и одновременно полнофункциональное архитектурное портфолио уровня Senior / Staff Engineer. Система решает ключевую проблему медицинских исследований: сбор сложноструктурированных динамических клинических данных с защитой от потери информации и рассинхрона кодовой базы.
1. Клинический контекст и предыстория
В основе модели данных регистра лежит 6-летнее исследование рекуррентного депрессивного расстройства у пациентов позднего возраста, проведённое автором в Национальном медицинском исследовательском центре психиатрии и неврологии им. В.М. Бехтерева (Санкт-Петербург, 2015 г., степень кандидата медицинских наук).
Какую клиническую проблему решает проект?
В психиатрических исследованиях традиционные инструменты (электронные таблицы Excel, универсальные опросники Google Forms, системы типа RedCap) быстро заходят в тупик: они не умеют валидировать временную последовательность аффективных фаз, не связывают смену фармакотерапии с динамикой симптомов и допускают противоречивые данные. RDD переносит врачебную логику непосредственно в архитектуру системы: нормализованный паспорт пациента, динамическая матрица фаз (1..N, поступление, выписка), включающая данные о клинической картине фаз и интермиссий, эффективности лечения, психометрические шкалы.
2. Архитектура: Registry-Driven Core (SSOT)
Главная проблема медицинских систем с десятками клинических признаков — сложность адаптации приложения к изменениям дизайна исследования. При внедрении изменений есть постоянный риск рассинхронизации между схемой базы данных, валидацией на бэкенде, UI-компонентами форм и словарём данных. В RDD реализован подход Single Source of Truth:
Единый декларативный TypeScript-объект (src/shared/config/registry/) описывает каждое поле: тип данных SQLite, UI-компонент, диапазон допустимых значений (min/max), клинические варианты выбора и формулы вычисления.
Из этого реестра генератор gen:d1 автоматически формирует D1-миграции, валидаторы Zod строятся на лету (to-zod.ts), интерфейс карточек рендерится декларативно, а Data Dictionary обновляется без участия разработчика.
Инвариант «Поле = Колонка»: бинарные признаки хранятся как плоские INTEGER 0/1. Это позволило отказаться от непрозрачных JSON-полей и тяжелых EAV-паттернов, обеспечив прямые высокоскоростные SQL-агрегаты.
3. Высокопроизводительная матрица фаз (Matrix Grid)
Часто в подобных приложениях возникают проблемы с удобством заполнения клинических признаков, интерфейс может подтормаживать из-за большого количества данных. Мы разработали "Матрицу фаз" — центральный инструмент врача, одновременно отображающий сотни ячеек признаков заболевания:
Гибридный скролл без JS
Гибридный скролл без JS-синхронизации: строки рендерятся через CSS Grid, где левая колонка наименования признака имеет нативное правило "position: sticky". Это исключило рассинхронизацию независимых слоев прокрутки.
Виртуализация TanStack
Виртуализация TanStack Virtual: рендерятся исключительно строки, попадающие в видимый viewport экрана, что гарантирует мгновенный отклик даже на больших клинических картах.
Атомарный Zustand-стор
Атомарное состояние на Zustand: изменение ячейки обновляет только конкретный DOM-узел через селекторы подписки, исключая перерисовку всей таблицы.
CAS-контроль версий (409)
Защита от потери данных (Compare-And-Swap): одновременные правки нескольких врачей проверяются по версии записи. В случае конфликта (HTTP 409 Conflict) врач видит разницу своего значения и версию коллеги — тихая перезапись исключена на уровне архитектуры.
4. Edge-инфраструктура, аудит и безопасность
Приложение развернуто в бессерверном рантайме Cloudflare (Workers + Pages + D1 Database) на базе Next.js 16 App Router с нулевым cold start:
Шифрование (Web Crypto)
Криптография на Web Crypto API: из-за отсутствия node:crypto на Edge хэширование паролей реализовано через PBKDF2-SHA256 (100 000 итераций) с солью. Токен сессии хранится в HttpOnly; Secure; SameSite=Lax cookie, а в БД — только SHA-256 дайджест.
Разграничение доступа к картам
Разграничение доступа к данным: каждому пользователю назначен объём видимости (data_scope) — «все» (all), «свой центр» (site) или «назначенные пациенты» (assigned). Репозиторий сам добавляет фильтр в каждый запрос, поэтому по прямой ссылке нельзя открыть чужую карту (IDOR).
Журнал изменений
Журнал изменений, который нельзя переписать: каждое изменение пишется в audit_log одной транзакцией с данными, а записи связаны хэшами (prev_hash/entry_hash) — подменить историю незаметно нельзя.
5. Границы демонстрационного проекта и продакшен
Проект создан для демонстрации инженерных подходов системного проектирования и доменной экспертизы. В спеках явно разграничены текущий функционал и требования боевого контура:
Текущий демо-контур
Текущий контур: полностью функциональная бизнес-логика регистра с синтетическими медицинскими профилями на серверах Cloudflare.
Требования для продакшена
Продакшен-эскалация: для эксплуатации с реальными пациентами требуется сертификация (152-ФЗ / HIPAA), Cloudflare WAF, Point-in-Time Recovery бэкапы D1 и интеграция с внешними МИС/ЕГИСЗ через HL7 FHIR.