KDS Phase 2 — Hardware и Architecture Research

Цель документа

Собрать индустриальные практики (Toast, iiko, Square, YumaKitchen) и предложить целевое архитектурное решение для нашего KDS — что ставить физически на кухнях/барах, какой клиент (тонкий/толстый), как работать без интернета. Это research перед ADR, не план реализации.


Контекст

Что у нас уже есть

СлойСостояние
Бизнес-объект «Кухонная станция»✅ Реализовано в Catalog Service. У товара есть kitchen_station_id (если requires_kitchen=true)
POS Desktop✅ Tauri 2 + React, Windows-приложение, скелет (bootstrapped)
POS BFF✅ Node.js + Fastify, контейнер на VPS
KDS-экран❌ Не реализован (отложено на Phase 2 — см. Кухонные станции §«Что НЕ входит»)
Принтеры per-станция❌ Не реализовано
Offline-first POS❌ Сейчас POS требует онлайн (POS BFF → backend)

Будущее требование (явно от пользователя)

«Мы там в будущем сто процентов захотим без интернета работать»

Значит: архитектура KDS должна быть offline-first с самого начала, иначе перепиливать дважды.


Что делает индустрия

Hardware: что физически ставят на кухне

Тип устройстваЦена / экранПлюсыМинусыГде применяется
Потребительский планшет (Android/iPad)$400–600Дёшево, лёгкое крепление, есть 4G/LTEЖара/жир убивают за 2–3 года; capacitive touch не работает в перчаткахМаленькие кафе, бары, мобильные ТТ
Commercial touchscreen monitor (15–22”)$600–1200Защита IP54+, рассчитан на 24/7 жару/влагу; больше площадь экранаДорого; нужен mini-PC или Android BoxBurger King / McDonald’s / средние и крупные кухни
Industrial-grade touchscreen (21.5”+)$800–2000Усиленная защита, resistive touch (работает в перчатках)ДорогоBig chains, fine dining
Non-touch monitor + bump bar200–500 (bump bar)Тактильная навигация (повар не моет руки), быстрое переключениеНужен mini-PC/Android Box; повар учится на кнопкахHigh-volume kitchens (фастфуд, столовые)

Что выбирают наши конкуренты:

  • iiko KDS — Android tablet/phone (рекомендуют Android 7+), любое устройство
  • YumaKitchen — Android tablet/phone, Google Play приложение
  • Toast KDS — собственный hardware на Android, plus partner ELO touchscreens
  • Oracle MICROS — собственные сертифицированные monitors + bump bars
  • Square — iPad

Вывод: для МСБ-сегмента наша целевая аудитория — планшет на Android выигрывает по цене и простоте. Для крупных кухонь — опция «mini-PC + commercial monitor + bump bar».

Архитектурные паттерны

Паттерн A: «Local hub» (Toast)

  • Один POS-терминал в ТТ через Ethernet работает как hub (relay в облако + LAN-координатор)
  • Остальные POS / KDS / handheld подключаются к hub по LAN (Wi-Fi)
  • При отключении интернета — hub координирует работу всех устройств в ресторане
  • Только один hub на ресторан, обязательно hardwired ethernet
  • Минус: hub — single point of failure (без UPS — всё лежит)

Паттерн B: «Локальный сервер» (iiko)

  • В ТТ ставится iikoServer (отдельный PC/мини-сервер) с локальной БД (MS SQL Server)
  • POS, KDS, handheld — все клиенты iikoServer
  • iikoServer синхронизируется с iikoCloud (облако) асинхронно
  • Полностью работает без интернета (только аналитика отстаёт)
  • Минус: дорого (нужен сервер в каждой ТТ), сложная настройка

Паттерн C: «Cloud-only с failover» (Square, YumaKitchen)

  • Все устройства напрямую с облаком (без локального hub)
  • Каждое устройство держит локальный кэш (SQLite)
  • При отключении интернета — каждое устройство работает изолированно с кэшем
  • Минус: KDS не получит свежих заказов с POS, если оба офлайн
  • Плюс: простота развёртывания

Паттерн D: «Local-first / CRDT»

  • Каждое устройство — равноправный peer с полной репликой данных
  • Sync через CRDT (Conflict-free Replicated Data Types) — нет single source of truth
  • Облако опционально, для аналитики
  • Полная работа без интернета и без hub
  • Минус: сложнее реализовать, нужна экспертиза CRDT

Целевое решение для нашего ERP

Рекомендация: гибрид паттернов A + D — «Local hub с CRDT-sync»

┌─────────────────────── Торговая точка ───────────────────────┐
│                                                                │
│   ┌────────────────────┐    LAN     ┌───────────────────┐    │
│   │  POS Desktop (hub) │◄───────────┤ KDS — Кухня (1+)  │    │
│   │  Tauri + SQLite    │            │ Tauri + SQLite    │    │
│   │  + локальный API   │            └───────────────────┘    │
│   │  на :8080          │            ┌───────────────────┐    │
│   │                    │◄───────────┤ KDS — Бар (1+)    │    │
│   │  Hardwired ETH     │            │ Tauri + SQLite    │    │
│   └─────────┬──────────┘            └───────────────────┘    │
│             │                       ┌───────────────────┐    │
│             │                       │ POS Desktop #2    │    │
│             │                       └───────────────────┘    │
│             │                                                 │
└─────────────┼─────────────────────────────────────────────────┘
              │ async, при наличии сети
              ▼
       ┌──────────────────┐
       │  ERP Cloud       │
       │  (наши сервисы)  │
       └──────────────────┘

Ключевые решения

#РешениеОбоснование
1KDS-клиент = Tauri-приложение (новое репо erp-kds)Тот же стек что и POS desktop: переиспользуем bff-client.ts, api-client, домен. Команда учит один стек.
2Hardware: Android-планшет 10–13” или mini-PC + commercial-grade touchscreen 21.5”Зависит от размера ТТ. Дать клиенту выбрать через сертифицированный список.
3Опционально bump bar через USB/Bluetooth — для крупных кухоньHigh-volume повара ценят
4Локальный hub в каждой ТТ — один из POS Desktop работает как координатор, поднимает HTTP+WS на :8080Не требует отдельного сервера. Если hub-POS падает — fallback другой POS становится hub’ом (через выборы)
5SQLite в каждом устройстве — полная локальная реплика заказов/меню/стоповTauri имеет native SQLite через rusqlite/sqlx
6Sync через event-log — все изменения как ordered events, реплицируются в LAN через WebSocketConflict-free через last-write-wins per field (proper CRDT — overkill для P0)
7Cloud sync асинхронный — hub толкает события в erp-pos-bff через очередьCloud — single source of truth для analytics + multi-tenant
8Failover: каждый KDS подписан на 2+ адреса hub’а, при потере — переподключается к запасномуБез single point of failure
9Звуковое + визуальное оповещение для кухни, фильтры по kitchen_station_id (см. Кухонные станции)Стандарт индустрии
10PIN-логин на KDS через JWT (как у POS)Уже есть в auth-service

Толстый/тонкий клиент?

Толстый клиент. Причины:

  • Tauri — толстый клиент по определению (native Rust + WebView)
  • Offline-first требует локальной БД и логики
  • Кухня: пропадание сети не должно ронять отображение заказов
  • Тонкий клиент в кухонной среде = катастрофа при падении интернета

Что положить в hub

POS Desktop, назначенный hub’ом (выбирается админом на этапе настройки ТТ — например, «POS №1 — основная касса с ethernet»):

Hub POS:
├── Tauri окно с UI кассира (как раньше)
├── Background-сервис на :8080 (HTTP REST + WebSocket):
│   ├── /lan/orders         ← KDS читает
│   ├── /lan/orders/:id     ← KDS обновляет статус (готово/в работе)
│   ├── /lan/menu           ← полное меню
│   ├── /lan/stop-list      ← стопы
│   └── /lan/sync (WS)      ← live-обновления
└── Cloud-sync worker — толкает локальные изменения в облако (Kafka топик через REST)

Не-hub POS работают как обычные KDS-clients (только UI кассира + локальная реплика). Хабом могут стать любые из POS-Desktop’ов, чтобы избежать SPOF.


Открытые вопросы (нужны решения с бизнесом)

Q1. Hardware референс-список

Какие устройства мы официально поддерживаем? Нужно сертифицировать 2–3 модели (например):

  • Бюджет: Lenovo Tab M10 (Android 12+, 10”)
  • Mid: Huawei MatePad / Xiaomi Pad
  • Industrial: ELO 1502L 15” с подвесом + Intel NUC

Чтобы саппорт не ловил странности на условном «Walmart-планшете за 99 баксов».

Q2. Bump bar

В Phase 2 поддерживаем или нет? Если да — какой протокол (USB HID / Bluetooth)? Это влияет на формат kds-desktop.

Q3. Локальная БД или нет?

  • Минимальный путь: каждый KDS просто WebSocket-клиент к hub-POS, БД нет. Если hub лёг — KDS показывает «офлайн». Дёшево.
  • Полный offline-first: каждый KDS имеет локальную SQLite-реплику и работает даже если hub лежит. Дорого по разработке.

Нужно решить с пользователем какой путь P0/P1.

Q4. Conflict resolution

Что если два KDS одновременно нажмут «Готово» на одном товаре? Сейчас ничего страшного (статус один). Но если будут поля типа «комментарий повара» — нужен CRDT или явная стратегия (last-write-wins с timestamp).

Q5. Принтеры per-станция

Это отдельная задача от KDS. Можно реализовать сейчас или после KDS:

  • ESC/POS принтеры (большинство кухонных принтеров)
  • Через USB или сетевой Ethernet
  • Зона ответственности — POS Desktop hub (он держит соединения с принтерами)

Q6. Архитектура hub election

Кто становится hub’ом, если основная касса упала? Варианты:

  • Manual: админ переключает hub через бэк-офис (просто, надёжно)
  • Auto: алгоритм выборов лидера (Raft/leader election) — сложно, но self-healing

P0 — manual, P1 — посмотрим потребность.


Риски и их митигация

РискМитигация
Wi-Fi на кухне капризный (микроволновки, воки)Hub обязательно на Ethernet; KDS — на 5GHz Wi-Fi или PoE
Жир/влага убьёт планшет за полгодаСписок рекомендованного hardware с IP-классом ≥ IP54
Hub упал — все KDS лежатManual failover на запасной POS Desktop в Phase 2.1
Состояние KDS и POS разъехалось после reconnectEvent-log с lamport timestamp, deterministic reconcile
Кухня не видит заказ из-за зависшего WSHeartbeat каждые 5с + auto-reconnect; визуальный indicator «связь жива»
Обновление KDS-приложения сломает кухню в час пикTauri auto-update только в окно «после закрытия ТТ»

Что нужно выяснить и согласовать перед началом реализации

Эти вопросы — для разговора с владельцами франшизы и техническими специалистами

  1. Бюджет на hardware на одну ТТ — определит, идти на путь Android-планшета (1500/экран)
  2. Сколько станций в типичном заведении нашей ЦА — 1 (просто кухня) / 2 (кухня + бар) / 3+ (горячий цех + холодный + бар + мангал)
  3. Готовы ли клиенты тянуть Ethernet до hub-POS — определяет надёжность
  4. Принтеры per-станция нужны в P0 — или KDS-экраны вместо принтеров (и старые ресторанные принтеры списываем)
  5. Bump bar нужен — для high-volume кухонь
  6. UPS обязателен в требованиях к ТТ — 5 минут работы при отрубе электричества (не упустить заказы в БД)
  7. Цвет/звук логика — как Yuma (по времени до готовности) или своя
  8. Поддерживаем ли «курсы подачи» (горячее, холодное, десерт) с точки зрения KDS

Фазовый план реализации (черновой)

PhaseЧто делаемСрок
2.1 — KDS MVPerp-kds (Tauri), подключение к POS BFF напрямую (без локального hub), показ заказов с фильтром по kitchen_station_id, статусы «в работе / готово»2–3 недели
2.2 — LAN hubPOS Desktop поднимает HTTP+WS на :8080, KDS подключаются к LAN-API. Тест на одной ТТ.2 недели
2.3 — Offline-firstSQLite в каждом устройстве, event-log sync, full offline-режим4 недели
2.4 — Принтеры per-станцияПоддержка ESC/POS принтеров через USB/Ethernet, конфиг в админке1–2 недели
2.5 — Bump barПоддержка USB HID bump bar1 неделя
2.6 — Hub failoverAuto-promotion второй POS в hub при падении первого2 недели

Источники


Связанные документы