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<br/>nadzór: Kiosk Helper]:::ui
SmartConf[Agent SmartConf<br/>127.0.0.1:8800 · /v1<br/>sterownik sprzętu]:::ext
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
Kiosk -->|HTTP /v1<br/>open / jobs / status| SmartConf
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¶
Pełna mapa → roadmapa
Projekt ma 22 etapy (0–22). Poniżej skrót; szczegóły, statusy i lista „co do zrobienia" na stronie Roadmapa i status. Najważniejsza zmiana architektoniczna: od etapu 9 kiosk nie steruje sprzętem bezpośrednio (Modbus) — komunikuje się z agentem SmartConf po lokalnym API 127.0.0.1:8800 (Komunikacja kiosk ↔ agent).
| 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 + panel-side upload |
|
| 4 | Event-driven workers + offline mode + mobile-parity API | |
| 5 | ||
| 6 | ErgoFlow integration — config + scheduler + mirror tables + JIT user/Keycloak provisioning + RFID credentials | |
| 7 | Wydawanie + raporty — DISPENSE end-to-end, limity, transakcje magazynowe | |
| 8 | DynaBox — prymitywy — kiosk hardware primitives (LockerBox-safe) + bramka walidacji | |
| 9 | SmartConf + serwis — agent SmartConf jedyną drogą do sprzętu, tryb serwisowy, auto-maintenance | |
| 10 | Kiosk Temrex — szablony UI (Temrex/ErgoFlow/Neon), bespoke ekrany | |
| 11 | KioskKit + OTA/Helper — design system + single-instance + tray + nadzorca | |
| 12 | DynaBox — drzwi fizyczne — bęben: 13 drzwi vs 364 komórki, macierz, fault→wyłącz wiersz | |
| 13 | Inwentaryzacja + OTA — inwentaryzacja skrytek + dokumenty | |
| 14 | MachineApiLog — log /v1 (kiosk↔agent) w panelu + diagnostyka bębna |
|
| 15 | Realna mapa skrytek — kiosk pokazuje mapę jak na webie | |
| 16 | Job API — masowe — uzupełnianie/inwentaryzacja przez agenta (job + poll) | |
| 17 | Job API — pojedyncza — pojedyncze otwarcie przez job + pre-check awarii | |
| 18 | Pre-flight + zgłaszający — gotowość maszyny przed jobem + tożsamość zgłaszającego | |
| 19 | 1 skrytka = 1 funkcja — NONE domyślnie, egzekwowane wszędzie | |
| 20 | Nazwy + drop Modbus — czytelne nazwy + usunięcie pola adresu Modbus z bazy | |
| 21 | Tryby serwisowe — komunikat vs zamknij kiosk (dostęp do Windows) | |
| 22 | Kiosk Helper + hasła — nadzorca C#/.NET 8, generator instalatora per-maszyna, hasła userów |
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.