Skip to main content

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}.

ServizioCollectionDescrizione
cash-registerscash_registersRegistratori di cassa fisici
cash-sessionscash_sessionsSessioni di lavoro operatore
cash-movementscash_movementsLedger movimenti (append-only)
cash-reason-codescash_reason_codesCausali movimenti
cash-reports(cross-collection)Report aggregati
cash-alertscash_alertsAlert 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:

  1. POST /cash-sessions/startCounting -- Blocca nuovi movimenti
  2. POST /cash-sessions/submitCount -- Invia conteggio e denominazioni
  3. POST /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:

EndpointDescrizione
GET /x-report/:sessionIdSnapshot 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 registrato
  • cash.movement.voided -- Movimento stornato
  • cash.transfer.completed -- Trasferimento tra registri completato
  • cash-session.variance.alert -- Varianza oltre soglia alla chiusura
  • cash.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

Questa pagina ti è stata utile?