Staff — Architecture

How the Staff POS is structured end to end.

Bootstrap

main.tsx
  QueryProvider          # TanStack Query client
    App
      BrowserRouter
      AuthProvider       # token + GET /auth/me/ gate
      Routes             # role login + POS tabs
      Sonner Toaster
      ChunkLoadRecovery
File Role
src/main.tsx createRoot, StrictMode, global CSS
src/providers/QueryProvider.tsx Shared QueryClient
src/providers/AuthProvider.tsx Session restore; blocks UI with loading screen until ready
src/app/App.tsx Router tree, lazy POS page, toasts

Routing model

Routes are flat (no /app prefix). Tab URLs map to an internal PosTab in src/lib/auth/paths.ts.

URL Internal tab Shell
/masalar orders PosShellHostPosShell + lazy AdminPage
/urunler products same
/checks checks same
/reports reports same
/islem-gecmisi logs same
/rezervasyon rezervasyon same
/mudavim mudavim same
/ayarlar settings same

Other routes:

Path Behavior
/ Role picker (StaffIndexPage); if already logged in → /masalar
/garson, /barkasa, /patron PinGate login for that role
/login Password login (same auth API)
/app, /app/:page, /admin, /admin/:page Legacy redirects → flat POS URLs
/staff, /staff/:role Legacy → / or /:role
* Not found

AppAuthGate requires a user and that the tab is allowed for the role; otherwise redirect to / or /masalar. Details: Auth & roles.

Source layout

Area Purpose
src/app/ Root router
src/features/auth/ Login, gates, legacy redirects
src/features/staff/ Role index + role PIN entry
src/features/pos/ AdminPage (all tabs), Müdavim feature
src/components/ui/ shadcn / Radix primitives
src/components/layout/ POS chrome, errors, chunk recovery
src/components/pos/ Tables, products, reports, settings UI
src/components/staff/ PinGate
src/lib/api/ HTTP client, auth API, POS fetch helpers
src/lib/auth/ Path helpers
src/lib/query/ QueryClient, keys, domain hooks
src/lib/orders/ Payments, merge, status, chimes, types
src/lib/menu/ Catalog, pricing, option groups
src/lib/reservations/ Types, overlap, prep, auto-activate
src/lib/reporting/ Day bounds, export PDF/Excel, KPIs
src/lib/tables/ Areas / numbering
src/lib/*.functions.ts Zod-validated write APIs (orders, products, staff, accounts, reservations, push)
src/hooks/ Mobile, back-close, auth-ready
src/providers/ Auth + Query
src/config/ API origin, poll interval
src/data/ Branding / static leftovers

API layer

Piece Location / behavior
Client src/lib/api/client.tsapiFetch / Get / Post / Patch / Put / Delete
Base API_URL = {origin}/api from src/config/app.ts
Auth header Authorization: Bearer <localStorage.auth_token>
Cookies credentials: "include"
Errors ApiError with HTTP status + JSON detail when present
Validation Zod schemas in *.functions.ts for mutating calls

Endpoint groups used by Staff

Domain Endpoints (under /api)
Auth /auth/login/, /auth/logout/, /auth/me/
Orders /orders/active/, /orders/submit/, /orders/:id/patch/, /orders/move-table/, /orders/move-items/, /orders/:id/charge-account/
Products /products/ (+ create / update / price / reassign / patch)
Availability /product-availability/…
Tables /table-groups/
Settings /restaurant-settings/, /restaurant-settings/warn/
Day / reports /day-closures/, /reports/orders/, /reports/calendar/, /reports/business/
Staff users /staff/
Reservations /reservations/…
Accounts /accounts/…, /account-transactions/
Audit /operation-logs/
Push /push/subscriptions/, /push/subscriptions/delete/, /push/vapid-public-key/, /push/notify-order/

State management

Layer Use
TanStack Query Server cache: orders, products, settings, table groups, reports, auth me, staff list. Default stale/refetch ~10s; refetch on window focus; retry once
React Context AuthProvider, PosShellHost, time-format and various UI contexts
Local useState Heavy in AdminPage, Müdavim, settings drafts, dialogs
Zustand / Redux Not used

Important hooks: useActiveOrdersQuery, catalog/availability queries, useRestaurantSettingsQuery, useTableGroupsQuery, report/business-day hooks, useAuthMeQuery, useStaffQuery.

Live updates (no WebSockets)

Mechanism Detail
Polling ~10s React Query refetchInterval on active floor/report queries when relevant
Timers Reservation auto-activate (~15s), end-of-day warning, MasaGrid reservation wake, order dialog clock
Web Push public/sw.js + src/lib/push-notify.ts — VAPID subscribe; SW can notify when tab is backgrounded; backend /push/notify-order/
Chime Audio cue on new / additional orders (src/lib/orders/chime.ts)
WebSockets Not used

Push subscription is skipped in iframes / preview contexts.

POS shell UX

PosShell / PosShellHost provide:

  • Role-filtered navigation (dock / sidebar)
  • Header actions (logout, day controls where allowed, live indicator)
  • Mobile-oriented gestures (covered by unit tests for swipe behavior)
  • Outlet for the active tab content rendered by AdminPage (or MudavimPage for müdavim)