Декомпозиция POS Phase 1 — Tables Canvas + order_type
Источник
План
desktop-pos: «Точка управления заведением»— Phase 1 (см. план в~/.claude/plans/jolly-crunching-lighthouse.md). Превращает desktop-pos из чистой кассы в HoReCa-точку управления.
Цель
Кассир выбирает тип заказа (takeaway / dine_in / delivery); для dine_in — открывает план зала с расположенными столами и привязывает заказ к столу. Менеджер может перемещать столы и редактировать вместимость/номер/подпись.
Затронутые сервисы / репозитории
| Слой | Репо | Задачи |
|---|---|---|
| desktop-pos | erp-pos-desktop | Desktop POS |
| POS BFF | erp-pos (bff/) | POS BFF |
| Store Service | erp-store-service | Store Service |
Backend готов на 95% до Phase 1
ZalTable entity, StoreService с CRUD/reserve/release/assignWaiter, public API под
requireEdit, internal endpoints для list/get/lifecycle — всё уже было в составе ранее закрытых задач (пра-родитель — BR 2.5 dine-in flow + BR 3.2 waiter assignment). Phase 1 добавляет только internal CRUD + waiter (для POS BFF) и полностью новый фронт.
Последовательность выполнения
- Store Service — расширить
InternalZalTableController(POST/PATCH/DELETE/PATCH waiter). Сервисный слой уже умеет всё. Деплой первым. - POS BFF — новые routes (CRUD + waiter), новый middleware
requireManager(требуетpos.settings.edit). Деплой после Store Service. - desktop-pos — domain types, api-client endpoints, ui-components (OrderTypeSwitcher, TableTile), TablesScreen с canvas+drag-edit, мock endpoints, расширение cartStore + MainScreen.
Decision points
- Plan layout: canvas + drag-and-drop сразу, не grid (по запросу пользователя).
- Halls/zones: отказ — плоский namespace столов на ТТ.
- Manager permission: используем существующий
pos.settings.edit(был в списке для cashier-stub), не вводим новый. Если в будущем понадобится точечный — заведёмpos.tables.manage. - Mock: 6 seed-столов разных статусов для проверки UI без backend (free / occupied / reserved / VIP).
- Coordinate system:
position_x/y— пиксели от верхнего левого угла канваса (ограниченоcanvas.width - TILE_SIZE). Не нормализуем в 0–1000 — Tauri окно фиксированного размера, проще хранить пиксели. - Auto-release: уже работает через Kafka
order.status.changedconsumer (BR 2.5) — Phase 1 ничего не делает.
Acceptance criteria (PASS)
- ✅ Кассир открывает
/tables, видит план: столы расположены поposition_x/y, цвет зависит от статуса (free=зелёный, occupied=красный, reserved=жёлтый). - ✅ Tap по свободному столу → action sheet → «Открыть заказ» →
MainScreenс предзаполненнымorder_type=dine_inиtableId. - ✅ Auto-release при закрытии заказа (Kafka consumer уже работает).
- ✅ Manager входит в режим «Редактировать план» → drag стола → PATCH сохраняет → перезагрузка показывает новую позицию.
- ✅ Бронь со временем —
reserved_untilсохраняется, статусreservedна UI. - ✅ Tap на занятый стол → action sheet → «Открыть заказ» (deep-link на
/orders/:id). - ✅ Manager edit-mode: создание / редактирование / удаление столов через TableEditModal.
Прогресс
- Store Service —
InternalZalTableControllerextended: POST/by-store/{storeId}(create), PATCH/{id}(update position/capacity/number/label), DELETE/{id}(soft delete), PATCH/{id}/waiter(BR 3.2 assign/unassign waiter) - POS BFF —
routes/tables.tsextended (5 новых endpoints),middleware/auth.tsrequireManager (требуетpos.settings.editповерхrequireCashier) - desktop-pos:
- domain types
ZalTable,TableStatus,Create/Update/Reserve/AssignWaiterRequest - api-client
createTablesEndpoints(9 методов) - UI:
OrderTypeSwitcher(segmented),TableTile(canvas-positioned) tablesStore(load/CRUD/lifecycle, auto-reload 30 сек)TablesScreen(canvas с drag-edit manager-only)- Components:
ReservationModal,TableActionSheet,TableEditModal cartStoreextended:orderType,tableId,tableNumber,setOrderType,setTableMainScreen— OrderTypeSwitcher в чеке + индикатор стола + dine_in блокирует checkout безtableId- Mock endpoints + 6 seed-столов (для VITE_USE_MOCK_BFF=true)
App.tsx/tablesroute +AppShell.tsxnav-item «Столы»
- domain types
Verification
- TypeScript desktop-pos: zero errors (
pnpm typecheck) - Vite build: passing
- POS BFF tsc: новые правки без ошибок (pre-existing ошибка в
catalog.tsне связана) - Store Service: maven build в Docker (Java 21) — passing на VPS
- VPS deploy:
store-service+pos-bffhealthy послеdocker compose up -d --force-recreate
Out of scope (отложено в следующие фазы)
- Phase 2: dine-in append-items («Добавить позиции» в существующий заказ),
WaiterPickerModal,TableOrderScreen(детали активного заказа стола) - Phase 3: Customer attach по телефону, Manager-PIN approval, ручная скидка
- Phase 4: Aggregator inbox в POS, авто-снятие истёкших броней (cron в Java)
- Phase 5: Tips Нетмонет, KDS by stations
- Phase 6: Reports в POS, Printer config, hotkeys, kiosk mode
Ссылки
- Store Service API (раздел
Internal API— extended Phase 1) - Store Service Data Model (zal_tables — без изменений)