erp-kds — BR 5.1
Новый репозиторий
Создаётся в Шаге 6. Имя:
nearbyErp/erp-kds. Структура — копияerp-pos-desktop(monorepo:apps/,packages/).
Контракты
- Бизнес-спека: Кухонный экран
- Frontend specs: Overview + 5 экранов
- API: Order, Catalog, User (через pos-bff)
Стек
- Фреймворк: Tauri 2 (Rust + React + TypeScript)
- Targets: Android (production) + Windows (для разработки)
- Frontend: React 18 + TypeScript, без UI-фреймворка (vanilla CSS/CSS Modules — как в
erp-pos-desktop) - State: React useState + custom hooks
- Хранилище: SQLite через
tauri-plugin-sql - Транспорт: native
fetch+WebSocketчерезIKdsTransportinterface - Updater:
@tauri-apps/plugin-updater - Менеджер пакетов: pnpm + workspaces
Структура репо
erp-kds/
├── apps/
│ └── kds/
│ ├── src/ ← React UI
│ │ ├── pages/
│ │ │ ├── RegistrationPage.tsx
│ │ │ ├── PinLoginPage.tsx
│ │ │ ├── StationSelectPage.tsx
│ │ │ ├── OrderListPage.tsx
│ │ │ ├── OrderDetailPage.tsx
│ │ │ └── SettingsPage.tsx
│ │ ├── components/
│ │ ├── hooks/
│ │ │ ├── useTransport.ts
│ │ │ ├── useSession.ts
│ │ │ └── useOrders.ts
│ │ ├── lib/
│ │ │ ├── colors.ts
│ │ │ ├── audio.ts
│ │ │ └── deviceId.ts
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── src-tauri/ ← Rust + SQLite
│ │ ├── src/
│ │ │ ├── main.rs
│ │ │ └── lib.rs
│ │ ├── Cargo.toml
│ │ └── tauri.conf.json ← targets: android + windows
│ ├── package.json
│ └── vite.config.ts
├── packages/
│ ├── api-client/ ← KdsTransport + impls
│ │ ├── src/
│ │ │ ├── types.ts
│ │ │ ├── KdsTransport.ts (interface)
│ │ │ ├── CloudTransport.ts
│ │ │ ├── MockTransport.ts
│ │ │ └── index.ts
│ │ └── package.json
│ ├── domain/ ← бизнес-типы
│ │ ├── src/
│ │ │ ├── Order.ts
│ │ │ ├── KitchenStation.ts
│ │ │ ├── KdsSettings.ts
│ │ │ └── index.ts
│ │ └── package.json
│ └── ui/ ← переиспользуемые компоненты
│ ├── src/
│ │ ├── OrderCard.tsx
│ │ ├── StatusChip.tsx
│ │ ├── SoundBanner.tsx
│ │ └── index.ts
│ └── package.json
├── pnpm-workspace.yaml
├── package.json
├── tsconfig.base.json
└── README.md
Что делаем
Bootstrap (этап C — 0.5 нед)
- Создать репо
nearbyErp/erp-kds(пользователь делает руками, я скаффолжу) -
pnpm create tauri-app apps/kds— Tauri 2 + React + TypeScript template -
cd apps/kds/src-tauri && cargo tauri android init— добавить Android target - Настроить
tauri.conf.json:productName: "ERP KDS"identifier: "ru.nirbi.erp.kds"bundle.android.minSdkVersion: 29(Android 10+)
-
pnpm-workspace.yaml— настройка monorepo - Создать packages/api-client, packages/domain, packages/ui (skeleton)
- Скопировать
bff-client.tsпаттерн изerp-pos-desktopдля основы транспорта - Базовый App.tsx с роутингом (react-router) и одной заглушкой страницы
KdsTransport (etap E — параллельно с D)
-
packages/api-client/src/KdsTransport.ts— интерфейс из BR 5.1 §3.3:interface KdsTransport { login(pin, deviceId): Promise<{ jwt, employee, availableStations }>; listKitchenStations(): Promise<KitchenStation[]>; listOrders(stationIds): Promise<Order[]>; subscribeOrderStream(stationIds, onEvent): Unsubscribe; setItemStatus(orderId, itemId, status): Promise<void>; setKdsStatusForStation(orderId, stationId, status): Promise<void>; getRecipe(productId): Promise<Recipe | null>; getKdsSettings(): Promise<KdsFranchiseSettings>; checkForUpdate(): Promise<UpdateInfo | null>; registerDevice(adminCreds, storeId, name): Promise<void>; } -
CloudTransport.ts— реализация черезpos-bffREST + WebSocket- HTTP-клиент с
keepAlive: false(как admin-bff fix) - WebSocket с auto-reconnect (exponential backoff 5s → 30s)
- JWT в
Authorization: Bearerheader,X-Device-Idв каждом запросе
- HTTP-клиент с
-
MockTransport.ts— in-memory data + симулятор новых заказов- Время-симулятор:
setIntervalсоздаёт случайные тестовые заказы каждые 30 сек - Используется в dev-режиме (Windows
cargo tauri dev) - Активируется через env
VITE_USE_MOCK_TRANSPORT=true
- Время-симулятор:
Экраны (этап D — 2 нед)
- RegistrationPage — admin-login + выбор ТТ + имя устройства, генерация device_id (SQLite)
- PinLoginPage — 4 цифры + цифровая клавиатура + anti-bruteforce
- StationSelectPage — multi-select станций после PIN
- OrderListPage — главный экран с карточками/списком, цвет, звуки, WS
- OrderDetailPage — карточка заказа с per-station блоками + кнопки Готово + модалка техкарты
- SettingsPage — звук/layout/transport/updater/logout/смена ТТ
Hooks
-
useTransport()— инициализация transport (CloudTransport или MockTransport) -
useSession()— JWT, user, selected_stations из SQLite + auto-logout таймер -
useOrders(stationIds)— initial REST + WebSocket subscribe, optimistic updates на статусы
Tauri SQLite
-
src-tauri/migrations/01_init.sql:config— key-value store (device_id, transport_mode, локальные оверрайды настроек)session— JWT, expires_at, user_id, last_activity_at, selected_station_ids (JSON)
-
src/lib/deviceId.ts—ensureDeviceId(): при первом запуске генерирует UUID, сохраняет в SQLite
Audio
-
src/lib/audio.ts—AudioManagerкласс:- Loop sounds через HTML Audio API
- Управление volume
- Метод
playRepeating(soundFile, intervalSec),stop()
-
apps/kds/src-tauri/icons/sounds/— встроенные mp3-файлы (bell.mp3,chime.mp3,buzzer.mp3,marimba.mp3,digital.mp3,alarm.mp3,siren.mp3,bell-loud.mp3) — упакованы в APK
In-app Updater
- Включить
tauri-plugin-updaterв Cargo.toml + tauri.conf.json - Manifest endpoint:
https://erp-test.nirbi.ru/api/v1/kds/updates/latest(через pos-bff) - В SettingsPage — кнопка «Проверить обновления»
- Background timer (24h) — auto-check + toast уведомление при новой версии
CI/CD (этап F3)
-
.github/workflows/build-android.yml:- Trigger: push на
main, manual - Steps:
- Checkout
- Setup Node 22 + pnpm + Rust + Android SDK
pnpm installcargo tauri android build --apk --target aarch64- Подписать APK через secret keystore (GitHub Secrets:
ANDROID_KEYSTORE,KEY_ALIAS,KEY_PASS) - Загрузить APK в наш MinIO bucket (или GitHub Releases)
- Обновить manifest
latest.json(новая версия + URL + signature)
- Trigger: push на
-
.github/workflows/build-windows.yml(опц.):- Build для разработчика — Windows .exe для тестов
Тесты
- Unit:
MockTransportтесты симулятора- Hook
useOrders— обработка WS-событий
- Manual smoke:
- Установить APK на тестовый планшет, прогнать сценарии из BR 5.1 §10 «Verification»
Pilot чек-лист (этап F4)
- Установить APK на тестовый планшет в demo-coffee
- Зарегистрировать устройство (
demo@nirbi.ru/admin123→ ТТ demo) - Создать сотрудника-повара с PIN и
kds.access - Привязать товары в catalog к станциям
- Пробить заказ на POS Desktop → убедиться что появляется на KDS за ≤2 сек
- Прогнать все сценарии из спеки §3
- Тестировать неделю реального использования
Зависимости
- ⛔ pos-bff endpoints должны быть готовы до KDS экранов (иначе только MockTransport)
- ⛔ Бэкенд миграции применены на VPS
- ⛔ Android-планшет для тестирования (модель уточняется)