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 |
PosShellHost → PosShell + 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.ts — apiFetch / 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(orMudavimPagefor müdavim)