Stack e confini
| Componente | Tecnologia | Responsabilità |
|---|---|---|
| Backend | Laravel 12 / PHP 8.2 | REST API, autenticazione, pannello admin e regole operative. |
| Database server | MySQL | Dati multi-tenant e transazioni di consegna/stock. |
| Mobile | Flutter | Applicazione agente unica, Android e iOS, bundle it.appteam.panificio. |
| Storage locale | SQLite + secure storage | Snapshot/outbox offline per tenant e token custodito dal dispositivo. |
| Stampa | Bluetooth ESC/POS | Invio testuale veloce, senza rendering PDF o immagini. |
Multitenancy SaaS
Il modello utilizza uno schema condiviso con chiave bakery_id. L’entità bakeries identifica l’ambiente; gli account piattaforma non appartengono a un panificio, mentre amministratori tenant e agenti sì.
| Dominio dati | Isolamento |
|---|---|
| Anagrafiche | customers, products, vans, agents filtrati per panificio. |
| Configurazione | customer_product_prices, routes, route_stops appartengono al tenant. |
| Operatività | turns, van_inventories, orders, deliveries e righe includono bakery_id. |
| Unicità | Codici operativi, numeri ordine e DDT sono unici nel relativo panificio. |
API mobile
Autenticazione agente
POST /api/v1/auth/login accetta email, password e identificazione dispositivo. Risponde con token Sanctum, utente e panificio. Sono accettati soltanto agenti attivi associati a tenant attivi.
Snapshot mattutino
GET /api/v1/agent/sync?date=YYYY-MM-DD richiede Bearer token e restituisce il solo turno dell’agente nel suo tenant.
{
"bakery": {"id": 1, "name": "Forno Rossi", "slug": "forno-rossi"},
"agent": {"id": 7, "name": "Marco Alba"},
"turn": {"route": {}, "van": {}, "ddt_numbering": {}},
"stops": [{"customer": {}, "price_list": [], "orders": []}],
"van_inventory": []
}
Outbox consegne
POST /api/v1/agent/deliveries/sync riceve massimo 100 bolle per richiesta. Ogni bolla usa un client_uuid idempotente e include le righe con sale_type planned oppure van_sale.
La transazione server verifica appartenenza al tenant, tappa del giro, ordine opzionale, intervallo DDT assegnato, listino valido e stock disponibile prima di inserire il documento e aggiornare il carico.
Offline Flutter
- Il token restituito dal login è memorizzato in
flutter_secure_storage. - SQLite mantiene snapshot e consegne pendenti usando lo slug del panificio come scope locale.
- Un logout azzera la sessione; l’accesso successivo non legge dati offline di un tenant differente.
- Il servizio di sincronizzazione scarica lo snapshot e invia l’outbox quando la connettività è disponibile.
- Il servizio ESC/POS genera bytes latin-1 in memoria e li invia via BLE in chunk da 240 byte senza risposta.
Sicurezza operativa
- L’area amministrativa usa sessione Laravel e middleware distinti per amministratore piattaforma e tenant.
- Le API app sono protette da Sanctum; il login emette un token dedicato con abilità di sincronizzazione agente.
- Il document root protegge file applicativi e configurazioni server tramite regole Apache.
- Questa documentazione pubblica non contiene password né valori di configurazione riservati.