MCS Mobile — SDUI приложение
Web-приложение мобильного клиента для диспетчера BMS. Сервер отдаёт JSON-layout — клиент рендерит виджеты из реестра. Один контракт работает и для phone (stack-навигация + bottom-nav), и для tablet (master-detail с постоянным сайдбаром). Live-обновления через SSE, write-операции с оптимистическим апдейтом.
О продукте
Приложение решает архитектурную задачу: как отдавать UI с сервера, чтобы добавление новой панели или экрана не требовало релиза в App Store / Google Play. Сервер возвращает Layout = массив Widget — клиент проходит реестр и рендерит зарегистрированные компоненты. Неизвестный тип → fallback (forward-compatibility).
Все виджеты адресуют данные через ref-ы вида sites/{site}/equipment/{eq}/points/{name}. В продакшене адаптер резолвит их в Niagara ord или Modbus address. Текущий dev-стенд — runtime-store + симулятор random-walk + ring buffer истории + EventEmitter для SSE; production-эволюция — PostgreSQL с TimescaleDB-расширением для трендов, Redis pub/sub для fanout SSE между нодами.
Управление через writable-ref'ы — toggle и setpoint-control делают оптимистический update + fire-and-forget POST. Сервер подтверждает изменение через SSE-апдейт. Симулятор не дрейфует writable-точки — они меняются только пользователем или внешним планировщиком.
Деплой — Docker Compose на нашем Proxmox VE: app-контейнер (Node 20), Postgres+TimescaleDB, Redis, Caddy reverse-proxy с автоматическими Let's Encrypt сертификатами. От git push до рабочего MVP — 5-10 минут. Та же сборка работает у заказчика on-premise — никакой привязки к облаку.
Ключевые возможности
Server-Driven UI
Layout приходит как JSON — клиент рендерит виджеты из реестра. Новые экраны без релизов в магазинах.
Phone + Tablet shell
Один JSON, две раскладки. Phone: stack-навигация, back-кнопка, bottom-nav. Tablet: master-detail с постоянным сайдбаром.
Live SSE
Server-Sent Events: сервер пушит обновления значений каждые 2с. Один long-lived коннект на сессию, без поллинга.
Тренды + история
Ring buffer на каждую точку (~2000 семплов). Backwards-walk seed даёт ~12 минут истории сразу при старте.
Admin CMS
/admin/sdui — управление sites, equipment, groups, points, alarms, scenes. Freeze-кнопка чтобы зафиксировать значение для отладки.
Cross-platform ready
PointStream абстракция отделяет SSE/EventSource (web) от того, что будет в RN (react-native-sse). Готово к Expo MVP.
AI-объяснение алармов
GigaChat в pipeline алармов: каждый инцидент получает короткое объяснение «что случилось / куда смотреть» на естественном языке. Контекст — соседние точки и тренды.
Технологический стек
- Next.js 16 App Router
- React 19
- TypeScript strict
- Tailwind CSS 4
- Framer Motion
- Phosphor Icons (duotone)
- 3-tier CSS tokens
- data-sdui-theme
- EventSource (SSE)
- PostgreSQL + TimescaleDB
- Redis pub/sub
- Ring buffer history
- GigaChat API
- 11 REST endpoints
- Idempotency-Key
- Optimistic updates
- Docker Compose
- Proxmox VE
- Caddy reverse-proxy
- Let's Encrypt
Что под капотом
- 33+ виджетов в реестре: gauge, kpi, trend-chart, ahu-schematic, vrf-system, parking-floor-map…
- Phone shell (stack + bottom-nav) и Tablet shell (sidebar + main) рендерят один и тот же layout JSON
- Симулятор skip-writable + skip-frozen: уставки не дрейфуют сами, freeze-flag для дебаг-сценариев
- Cross-platform PointStream: web (EventSource) + план под RN (react-native-sse)
- Развёрнут на нашем Proxmox VE одной командой docker compose up — тот же бандл едет on-premise к заказчику
- TimescaleDB hyperchunks для трендов, Redis для масштабирования SSE на N инстансов
- GigaChat в pipeline алармов — натуральные объяснения инцидентов диспетчеру
- 7 ADR-документов в docs/adrs/ — фиксируем архитектурные решения
Посмотреть вживую
Нужна похожая разработка?
Обсудим задачу, соберём команду под стек и сроки, предложим прозрачную оценку.