API Ordini: Endpoints e Flusso Dati
Panoramica
Il servizio orders gestisce in modo centralizzato tutti i tipi di ordine della piattaforma: sala (DINE_IN), asporto (TAKEAWAY) e delivery. Il servizio utilizza TenantDbMixin("orders") per l'isolamento multi-tenant, AnalyticsPublisherMixin per la pubblicazione eventi di vendita e OrdersQueueMixin per la coda affidabile basata su Redis Streams.
Base URL: GET/POST /api/orders
Tutti gli endpoint richiedono autenticazione JWT e l'header x-tenant-id viene estratto automaticamente dal token.
Flusso Ordine
Il ciclo di vita di un ordine segue questa sequenza:
- Creazione (
POST /orders) -- stato inizialeSENT - Conferma -- lo staff accetta l'ordine, stato
confirmed - Preparazione -- la cucina prende in carico, stato
preparing - Pronto -- piatto pronto per il servizio, stato
ready - Completamento (
POST /orders/:id/complete) -- pagamento effettuato, statocompleted
In alternativa, un ordine puo essere annullato in qualsiasi momento (PUT /orders/:id/status con stato cancelled).
Endpoint Principali
Elenco ordini
curl -X GET "https://api.example.com/api/orders?page=1&pageSize=50&sort=orario_desc" \
-H "Authorization: Bearer <JWT_TOKEN>"
Parametri query: page (default 1), pageSize (default 50), sort (orario_asc, orario_desc).
Dettaglio ordine
curl -X GET "https://api.example.com/api/orders/<ORDER_ID>" \
-H "Authorization: Bearer <JWT_TOKEN>"
Accetta sia _id MongoDB sia il campo orderId generato dalla coda.
Creazione ordine
curl -X POST "https://api.example.com/api/orders" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"tipo": "DINE_IN",
"tavoloId": "t12",
"numeroTavolo": 12,
"coperti": 4,
"items": [
{
"productId": "margherita",
"name": "Pizza Margherita",
"quantity": 2,
"price": 8.50,
"notes": "senza basilico"
}
],
"note": "Allergia ai latticini tavolo 12"
}'
Il servizio accetta sia formato inglese (items, tavoloId) sia italiano (prodotti, tavolo_id). La risposta include l'ordine completo con _id e totalAmount calcolato.
Aggiornamento stato
curl -X PUT "https://api.example.com/api/orders/<ORDER_ID>/status" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "nuovoStato": "preparing" }'
Valori consentiti: new, confirmed, preparing, ready, delivered, cancelled.
Completamento con pagamento
curl -X POST "https://api.example.com/api/orders/<ORDER_ID>/complete" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"payments": [
{ "amount": 17.00, "method": "Cash" }
]
}'
Supporta pagamenti multipli (split) tramite l'array payments. Alla chiusura viene pubblicato un evento analytics e, se l'ordine ha un tableId, il tavolo viene liberato via NATS.
Sincronizzazione (Delta Sync)
curl -X GET "https://api.example.com/api/orders/sync?status=open&lastSync=2026-03-17T08:00:00Z" \
-H "Authorization: Bearer <JWT_TOKEN>"
Parametri: status (open, completed, cancelled), lastSync (ISO date per delta), tableId, limit (default 500). Ritorna il formato mappato per Flutter con serverId, orderId, items, firedCourses.
Gestione Uscite (Courses)
Il sistema supporta la gestione per uscite, fondamentale per la ristorazione:
POST /orders/:id/fire-course-- Lancia la preparazione di un'uscitaPOST /orders/:id/advance-course-- Avanza all'uscita successivaPOST /orders/:id/item-status-- Aggiorna lo stato di singoli articoli
Eventi Realtime
Ogni operazione sugli ordini pubblica messaggi NATS per la sincronizzazione in tempo reale:
tenant.{tenantId}.restaurant.orders.created-- Nuovo ordinetenant.{tenantId}.restaurant.tables.status-- Cambio stato tavolo (occupied/free)
Le app Flutter (cassa_ui, waiter_ui) sottoscrivono questi subject per aggiornare l'interfaccia istantaneamente.
FAQ
D: Come funziona l'idempotenza nella creazione ordini?
R: Il servizio supporta chiavi di idempotenza tramite OrdersQueueMixin. Quando la coda e attiva (ORDERS_QUEUE_ENABLED=true), ogni ordine riceve un token di tracking univoco e i duplicati vengono scartati automaticamente.
D: Posso creare ordini senza autenticazione in sviluppo?
R: Si, impostando SKIP_AUTH=true e DEV_TENANT_ID=demo nel file .env del backend. L'API Gateway usera il tenant di default.
D: Qual e la differenza tra crea e createFromWaiter?
R: crea (endpoint italiano POST /ordini) e il formato legacy usato dall'app cliente. createFromWaiter (endpoint POST /orders) e ottimizzato per waiter_ui con supporto Redis queue.
Vedi Anche
- API Prodotti e Categorie -- Gestione catalogo articoli
- Architettura Cassa -- Dettagli frontend Flutter
- Panoramica Architettura -- Visione d'insieme della piattaforma