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 Box | Burger King / McDonald’s / средние и крупные кухни |
| Industrial-grade touchscreen (21.5”+) | $800–2000 | Усиленная защита, resistive touch (работает в перчатках) | Дорого | Big chains, fine dining |
| Non-touch monitor + bump bar | 200–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 │
│ (наши сервисы) │
└──────────────────┘
Ключевые решения
| # | Решение | Обоснование |
|---|---|---|
| 1 | KDS-клиент = Tauri-приложение (новое репо erp-kds) | Тот же стек что и POS desktop: переиспользуем bff-client.ts, api-client, домен. Команда учит один стек. |
| 2 | Hardware: 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’ом (через выборы) |
| 5 | SQLite в каждом устройстве — полная локальная реплика заказов/меню/стопов | Tauri имеет native SQLite через rusqlite/sqlx |
| 6 | Sync через event-log — все изменения как ordered events, реплицируются в LAN через WebSocket | Conflict-free через last-write-wins per field (proper CRDT — overkill для P0) |
| 7 | Cloud sync асинхронный — hub толкает события в erp-pos-bff через очередь | Cloud — single source of truth для analytics + multi-tenant |
| 8 | Failover: каждый KDS подписан на 2+ адреса hub’а, при потере — переподключается к запасному | Без single point of failure |
| 9 | Звуковое + визуальное оповещение для кухни, фильтры по kitchen_station_id (см. Кухонные станции) | Стандарт индустрии |
| 10 | PIN-логин на 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 разъехалось после reconnect | Event-log с lamport timestamp, deterministic reconcile |
| Кухня не видит заказ из-за зависшего WS | Heartbeat каждые 5с + auto-reconnect; визуальный indicator «связь жива» |
| Обновление KDS-приложения сломает кухню в час пик | Tauri auto-update только в окно «после закрытия ТТ» |
Что нужно выяснить и согласовать перед началом реализации
Эти вопросы — для разговора с владельцами франшизы и техническими специалистами
- Бюджет на hardware на одну ТТ — определит, идти на путь Android-планшета (1500/экран)
- Сколько станций в типичном заведении нашей ЦА — 1 (просто кухня) / 2 (кухня + бар) / 3+ (горячий цех + холодный + бар + мангал)
- Готовы ли клиенты тянуть Ethernet до hub-POS — определяет надёжность
- Принтеры per-станция нужны в P0 — или KDS-экраны вместо принтеров (и старые ресторанные принтеры списываем)
- Bump bar нужен — для high-volume кухонь
- UPS обязателен в требованиях к ТТ — 5 минут работы при отрубе электричества (не упустить заказы в БД)
- Цвет/звук логика — как Yuma (по времени до готовности) или своя
- Поддерживаем ли «курсы подачи» (горячее, холодное, десерт) с точки зрения KDS
Фазовый план реализации (черновой)
| Phase | Что делаем | Срок |
|---|---|---|
| 2.1 — KDS MVP | erp-kds (Tauri), подключение к POS BFF напрямую (без локального hub), показ заказов с фильтром по kitchen_station_id, статусы «в работе / готово» | 2–3 недели |
| 2.2 — LAN hub | POS Desktop поднимает HTTP+WS на :8080, KDS подключаются к LAN-API. Тест на одной ТТ. | 2 недели |
| 2.3 — Offline-first | SQLite в каждом устройстве, event-log sync, full offline-режим | 4 недели |
| 2.4 — Принтеры per-станция | Поддержка ESC/POS принтеров через USB/Ethernet, конфиг в админке | 1–2 недели |
| 2.5 — Bump bar | Поддержка USB HID bump bar | 1 неделя |
| 2.6 — Hub failover | Auto-promotion второй POS в hub при падении первого | 2 недели |
Источники
- Tablet or Monitor? — Choosing the Best Kitchen Display Screen (Fresh.Technology)
- Kitchen Display Systems Guide 2026 (Delivety)
- KDS Hardware Cost Guide 2026 (TCANG)
- Toast Platform Guide — Offline Mode with Local Sync
- Toast — Offline KDS Devices
- iiko KDS — Multi-bit
- iiko KDS — kabus.ru
- SkyTab — POS Network with LTE Backup & UPS
- SpotOn — POS Offline Mode
- TwoFish — Restaurant Internet Backup
- Tauri 2.0 Documentation
- Building a Local-First Tauri App with Drizzle ORM (DEV)
- TypeScript CRDT Toolkits for Offline-First Apps
- [_reference/yumapos/install-kitchen-app.md|YumaKitchen — установка]
- [_reference/yumapos/processing_kitchen_orders.md|YumaKitchen — обработка заказов]
- [_reference/yumapos/yumakitchen-app-settings.md|YumaKitchen — настройки]
Связанные документы
- Кухонные станции — текущая бизнес-спека (только справочник)
- Repositories — где будет лежать
erp-kds - System Overview — общая архитектура
- Tech Stack — технологии (Tauri упомянут в POS Desktop)