API Prima Nota: Servizi e Flusso Dati
Panoramica
Il modulo Prima Nota e composto da 6 servizi Moleculer, tutti basati su TenantDbMixin per l'isolamento multi-tenant. Ogni servizio opera su una collection dedicata nel database t_{tenantId}.
| Servizio | Collection | Descrizione |
|---|---|---|
cash-registers | cash_registers | Registratori di cassa fisici |
cash-sessions | cash_sessions | Sessioni di lavoro operatore |
cash-movements | cash_movements | Ledger movimenti (append-only) |
cash-reason-codes | cash_reason_codes | Causali movimenti |
cash-reports | (cross-collection) | Report aggregati |
cash-alerts | cash_alerts | Alert anomalie |
Tutti gli endpoint richiedono autenticazione JWT con tenantId estratto automaticamente dal token.
Numeratori
I codici sequenziali sono generati dal servizio numeratori:
- Registratori:
CR-001,CR-002, ... - Sessioni:
CS-2026-00001,CS-2026-00002, ... - Movimenti:
CM-2026-000001,CM-2026-000002, ...
Endpoint Principali
Apertura Sessione
curl -X POST "https://api.example.com/api/cash-sessions/open" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"registerId": "<REGISTER_ID>",
"operatorId": "op-001",
"operatorName": "Mario Rossi",
"openingFloat": 200.00,
"businessDate": "2026-03-17"
}'
Il servizio verifica che il registratore sia idle e che l'operatore non abbia altre sessioni attive. Crea un movimento FLOAT automatico per il fondo iniziale.
Registrazione Movimento
curl -X POST "https://api.example.com/api/cash-movements/record" \
-H "Authorization: Bearer <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "<SESSION_ID>",
"registerId": "<REGISTER_ID>",
"direction": "OUT",
"type": "MANUAL",
"reasonCode": "VENDOR_PAYMENT",
"amount": 45.00,
"description": "Pagamento fornitore bevande",
"operatorId": "op-001",
"operatorName": "Mario Rossi",
"businessDate": "2026-03-17"
}'
I totali della sessione vengono aggiornati atomicamente via $inc su MongoDB. Il campo expectedCash viene ricalcolato solo per movimenti in contanti.
Chiusura Sessione
La chiusura avviene in tre fasi:
POST /cash-sessions/startCounting-- Blocca nuovi movimentiPOST /cash-sessions/submitCount-- Invia conteggio e denominazioniPOST /cash-sessions/close-- Chiude la sessione
Se la varianza supera criticalVarianceThreshold, lo stato diventa pending_review e il parametro authorizedBy e obbligatorio per la chiusura.
Report
Il servizio cash-reports espone 6 endpoint di aggregazione:
| Endpoint | Descrizione |
|---|---|
GET /x-report/:sessionId | Snapshot sessione corrente |
GET /z-report?businessDate= | Chiusura giornaliera |
GET /daily-summary?businessDate= | Riepilogo cross-registri |
GET /variance?fromDate=&toDate= | Analisi varianze nel periodo |
GET /operator-performance?fromDate=&toDate= | Metriche operatori |
GET /cash-flow?fromDate=&toDate= | Flusso cassa (waterfall) |
Eventi Realtime
I movimenti e le sessioni pubblicano eventi tramite sync-events.publish e ctx.emit:
cash.movement.created-- Nuovo movimento registratocash.movement.voided-- Movimento stornatocash.transfer.completed-- Trasferimento tra registri completatocash-session.variance.alert-- Varianza oltre soglia alla chiusuracash.alert.created-- Nuovo alert anomalia generato
FAQ
D: I movimenti supportano l'idempotenza?
R: Ogni movimento riceve un movementCode univoco dal servizio numeratori. Il ledger e append-only: non esistono update sui campi core del movimento.
D: Come funziona il trasferimento tra casse?
R: L'azione cash-movements.transfer crea una coppia di movimenti collegati: OUT sulla cassa sorgente e IN sulla cassa destinazione, con riferimenti incrociati (counterpartMovementId).
D: Posso esportare i movimenti?
R: Si, tramite GET /cash-movements/export?format=csv con gli stessi filtri dell'elenco. Il CSV include BOM UTF-8 per compatibilita Excel.
Vedi Anche
- Guida Prima Nota -- Guida operatore
- Soglie Varianza e Alert -- Configurazione alert
- API Ordini -- API gestione ordini
- Pattern Mixin Multi-Tenant -- Architettura TenantDbMixin