Architektura¶
Pełny obraz systemu — co rozmawia z czym, gdzie żyje stan, którędy idą eventy.
Diagram wysokopoziomowy¶
graph TB
classDef ui fill:#0AD6E8,stroke:#10F3FF,color:#06101A,stroke-width:2px
classDef api fill:#101F33,stroke:#0AD6E8,color:#fff,stroke-width:2px
classDef store fill:#1A2C42,stroke:#5EE6A0,color:#fff
classDef worker fill:#0A1628,stroke:#F5C16C,color:#fff
classDef ext fill:#1A2C42,stroke:#F77B89,color:#fff,stroke-dasharray: 5 5
Panel[Panel operatora<br/>Next.js 15 · App Router]:::ui
Kiosk[Kiosk Flutter<br/>Windows desktop]:::ui
Backend[Backend API<br/>NestJS 10 + Prisma]:::api
Workers[Workers<br/>MachineWorker · ShipmentWorker<br/>NotificationWorker · ErgoflowScheduler]:::worker
Postgres[(Postgres 16)]:::store
Redis[(Redis 7)]:::store
Rabbit{{RabbitMQ 3.13<br/>smartbox.events}}:::store
Keycloak[[Keycloak 26<br/>OIDC realm: smartbox]]:::ext
ErgoFlow[[ErgoFlow upstream<br/>garos.ergoflow.app<br/>OAuth2 password grant]]:::ext
Panel -->|JWT bearer<br/>HttpOnly cookies| Backend
Kiosk -->|X-Machine-Api-Key<br/>HTTPS poll 30s| Backend
Backend --> Postgres
Backend --> Redis
Backend -->|publish| Rabbit
Rabbit -->|consume| Workers
Workers --> Postgres
Backend -.->|JWKS validate| Keycloak
Backend -.->|admin-cli<br/>provision users| Keycloak
Backend -.->|sync employees<br/>+ groups + RFID| ErgoFlow
Panel -.->|password grant<br/>+ refresh| Keycloak
Skrót
Panel + Kiosk to dwa front-endy. Backend jest jedyną prawdą. Postgres trzyma dane, Redis cache, RabbitMQ event bus. Workery konsumują eventy i odpalają cykliczne zadania. Keycloak i ErgoFlow to integracje zewnętrzne (Keycloak dla OIDC, ErgoFlow dla source-of-truth pracowników).
Etapy projektu¶
| Etap | Zakres | Status |
|---|---|---|
| 0 | Infra bootstrap — Traefik + Postgres + Redis + RabbitMQ + Keycloak + Gitea + Portainer + Dozzle | |
| 1 | Backend core — users, machines, shipments, lockers; REST + RabbitMQ events; dual auth | |
| 2 | Web operator panel — Next.js 15 App Router + glass-morphism + i18n PL/EN | |
| 3 | Kiosk UI + OTA — Flutter Windows desktop + PowerShell OTA agent + panel-side upload | |
| 4 | Event-driven workers + offline mode + mobile-parity API | |
| 5 | Modbus / hardware — kiosk locker lifecycle hardening, deposit-into-open guard, PIN-clear-on-fail, latch reopen | |
| 6 | ErgoFlow integration — config + scheduler + mirror tables + JIT user/Keycloak provisioning + RFID credentials | |
| 7 | Analytics, smart assignment, document/rental flows, multi-machine sync | |
| 8 | Hardening — real notifications (email/SMS), monitoring, audit-log retention, rate limits, OIDC code-flow + PKCE, Gitea Actions CI/CD |
Trasy ruchu¶
- User loguje się przez Keycloak password grant.
- Cookies
sb_access(~5 min) isb_refresh(~1 tydz) ustawiane HttpOnly. - Każdy
/dashboard/**przechodzi przezmiddleware.ts— sprawdzaexp, refresh-uje gdy trzeba. - Server Components wołają
api<T>()z JWT w nagłówku.
- Maszyna posiada per-instance
machineApiKey(bcrypt-stored po stronie serwera). - Każdy request niesie
X-Machine-Api-Key. - Identyfikacja użytkownika (PIN/RFID) jest weryfikowana po stronie serwera.
- Offline cache ($SyncService$ co 2 min) trzyma
cached_users/cached_credentialslokalnie.
- Admin konfiguruje
baseUrl+ login podSystem → Integracje → ErgoFlow. ErgoflowSchedulercointervalMinuteswołarunFullSyncWork.- Pull users/groups/members → upsert do
ErgoflowUser/Group/GroupMember. - JIT-create
User+ Keycloak account +Credential(RFID, bcrypt(userNumber))dla aktywnych pracowników. - Event
ergoflow.sync.completedna RabbitMQ.
Domeny publiczne¶
| Subdomena | Serwis | Auth |
|---|---|---|
smartbox.ergoflow.app |
Panel (Next.js 15) | Keycloak |
api.smartbox.ergoflow.app |
Backend + Swagger /docs |
JWT + API key |
auth.smartbox.ergoflow.app |
Keycloak 26 | — |
git.smartbox.ergoflow.app |
Gitea 1.22 | własna |
docs.smartbox.ergoflow.app |
Ta dokumentacja (MkDocs Material) | publiczna |
ops.smartbox.ergoflow.app |
Portainer CE | basic auth |
logs.smartbox.ergoflow.app |
Dozzle | basic auth |
traefik.smartbox.ergoflow.app |
Traefik dashboard | basic auth |
rabbit.smartbox.ergoflow.app |
RabbitMQ management | basic auth |
Ścieżka deploy¶
Ręczny deploy — bez CI
Dziś deploy to tar | ssh + docker compose build. CI/CD (Gitea Actions) jest planowane na etap 8. Wszystkie zmiany backend/panel trafiają na produkcję ręcznie z workstation operatora.
```bash
Z lokalnego checkoutu (workstation):¶
cd /c/Projekty && tar czf - -C SmartBox \ --exclude='.env' --exclude='node_modules' --exclude='.git' --exclude='.next' --exclude='dist' \ backend frontend-web infra | ssh smartbox 'tar xzf - -C /opt/smartbox' && \ ssh smartbox 'cd /opt/smartbox/infra && docker compose build backend frontend-web && docker compose up -d backend frontend-web' ```
Migracje Prisma uruchamiają się automatycznie w entrypoincie kontenera backendu.
Pełny runbook → Infrastruktura.