POS BFF — POS Phase 1
Что сделано
routes/tables.ts — расширен
Было: list / release / reserve / cancel-reservation. Стало:
| Method | Path | Auth | Назначение |
|---|---|---|---|
| GET | /api/v1/pos/tables | requireCashier | List по activeStoreId |
| GET | /api/v1/pos/tables/:id | requireCashier | Single fetch |
| POST | /api/v1/pos/tables | requireManager | Create новый стол |
| PATCH | /api/v1/pos/tables/:id | requireManager | Update position/capacity/number/label |
| DELETE | /api/v1/pos/tables/:id | requireManager | Soft delete |
| POST | /api/v1/pos/tables/:id/release | requireCashier | Release стола |
| POST | /api/v1/pos/tables/:id/reserve | requireCashier | Reserve (с note + until) |
| POST | /api/v1/pos/tables/:id/cancel-reservation | requireCashier | Снять бронь |
| PATCH | /api/v1/pos/tables/:id/waiter | requireManager | BR 3.2 — назначить/снять официанта |
Все запросы проксируются на store-service /internal/tables/... с X-Service-Token. POST / мапится на /internal/tables/by-store/{activeStoreId} (storeId берётся из JWT, в теле не передаётся).
middleware/auth.ts — requireManager middleware
export async function requireManager(request, reply) {
await requireCashier(request, reply);
if (reply.sent) return;
const permissions = (request as any).permissions ?? [];
if (!permissions.includes("pos.settings.edit")) {
return reply.status(403).send({
error: { code: "MANAGER_REQUIRED", message: "Действие доступно только менеджеру ТТ" },
});
}
}Цепочка: токен валидный → pos.access есть → pos.settings.edit есть. Если хотя бы что-то нет — 403.
Stub-режим уже даёт
pos.settings.editDev-стаб с
dev-cashier-*токеном получает все permissions (включая settings.edit), что позволяет тестировать manager-флоу без настоящей роли. Для prod нужно настроитьpos.settings.editдля нужных permissions-ролей.
Файлы
bff/src/routes/tables.ts— full rewrite (старые endpoints сохранены 1-в-1, добавлены новые)bff/src/middleware/auth.ts— добавленrequireManagerфункция
Тесты
- TypeScript:
tsc --noEmit— pre-existing error в catalog.ts не от нас, новые файлы чистые - Smoke после деплоя через UI desktop-pos