Чуйгун
Техническая документация

Архитектура

Технологический стек, роли и RBAC, условный UI, потоки данных заказа и ключевые модули приложения Чуйгун.

Стек

Подтверждён решениями #57 и #58.

  • Frontend: Next.js 15.5.20 (App Router) + React 19 + TypeScript. Апгрейд с Next 14.2.15 / React 18 сделан ради Cloudflare-адаптера OpenNext (#57).
  • UI: shadcn/ui + Tailwind + Framer Motion. Иконки — Lucide React, графики — Recharts, drag&drop — @dnd-kit.
  • State: Zustand + persist (корзина работает offline). Валидация — Zod (клиент + сервер).
  • i18n: next-intl, локали ru (default) / en / uz. Конфиг apps/web/src/i18n/routing.ts, переводы apps/web/messages/{locale}.json.
  • Backend: Supabase (Postgres + Auth + Realtime + Storage). Своего бэка нет — всё из коробки за 20 дней (#1).
  • Realtime: Supabase Realtime (Postgres CDC → WebSocket), бесплатно до 200 connections.
  • Печать: локальный Node.js print-agent на ноутбуке кассы (см. Печать).
  • Hosting: Cloudflare Workers (фронт) + Supabase (бэк) + Cloudflare DNS.

Роли и RBAC

Роли: admin, manager, waiter, cook. Роль waiter заменила cashier (#22, migration 044 мигрирует данные + RLS + JWT).

Матрица доступа (middleware apps/web/src/lib/auth/rbac.ts):

МаршрутКто имеет доступ
/admin/orderswaiter / manager / admin
/admin/menu, /admin/tablesmanager / admin
/admin/usersadmin
/kitchencook / manager / admin

Три независимых слоя защиты (defence in depth):

  1. middleware RBAC — проверка роли на маршруте.
  2. RLS policies — построчная защита в Postgres.
  3. SECURITY DEFINER RPC — ре-проверка роли на сервере (current_is_order_staff).

stripLocale() нормализует путь до канонического перед проверкой RBAC-матрицы.

Условный UI по ролям

Решения #47, #48, #52.

  • ConditionalHeader / ConditionalFooter: официант видит WaiterHeader с табами столов, гость — стандартный хедер.
  • Отдельная страница /menu-waiter для официанта (не адаптация /menu — попытка адаптации давала бесконечные редиректы). Middleware редиректит waiter с /menu на /menu-waiter (только роль waiter, без QR-параметров).
  • После логина: waiter → /menu (→ /menu-waiter), остальные → /admin/orders.

Потоки данных

Заказ со стола (QR)

Гость → QR /menu?table=N&token=UUID → middleware валидирует через RPC validate_table_qr → HttpOnly-cookie table_session → корзина (Zustand persist) → /checkout → RPC create_order → Realtime CDC → кассир принимает (status accepted) → print-agent печатает + кухня видит карточку.

Онлайн-заказ (доставка / самовывоз)

/menu без table → корзина → /checkout (source delivery / pickup, имя / телефон / адрес) → create_order → кассир.

Статусы заказа

new → accepted → cooking/preparing → ready → closed, плюс cancelled. Переход только через RPC update_order_status (forward-only в UI, но есть откат ready → preparing, #26).

Ключевые модули

Каталог apps/web/src/:

МодульНазначение
lib/cart/Zustand-стор корзины с persist
lib/orders/бизнес-логика заказов, канбан
lib/auth/RBAC, сессии, middleware-хелперы
lib/qr/валидация QR, table sessions
lib/reports/агрегации для отчётов
lib/api/обёртки над Supabase RPC
components/admin/, components/menu/админ-панель, карточки блюд и категории

На этой странице