0006. Il RunReport è il prodotto; servizio stateless e agnostico
- Stato: Accettata
- Data: 2026-06-03
- Decisori: Team BI/ETL
Contesto
Il servizio deve restare molto semplice e agnostico: eseguire una pipeline e restituire un risultato con tutti i dettagli del caso. Non deve possedere un database, né essere accoppiato a una destinazione specifica per metriche/audit.
Decisione
Il RunReport è il risultato (il "prodotto") di ogni esecuzione e il servizio è stateless:
- Nessuna persistenza lato servizio (niente
run_history, niente DB interno). - Contratto di I/O:
stdout= il RunReport in JSON (un oggetto),stderr= log umani, exit code = esito (0success/partial,≠0failed). - Report garantito anche in errore: l'entrypoint cattura l'eccezione e produce un RunReport
status: "failed"con dettagli e conteggi parziali. - Report auto-descrittivo e sicuro: identità, tempi, topologia (solo nomi), parametri, volumi, categorie di scarto, errore — senza segreti né payload/PII.
- Payload degli scarti → al dead-letter sink scelto dal chiamante, non nel report.
- Nessun push integrato (webhook/S3/DB): chi invoca il servizio decide cosa fare del report.
- Versionato con
reportSchemaVersionper evolverlo senza rompere i consumatori.
Alternative considerate
- Persistenza in
etl.run_history(DB) — comoda per audit/alerting ma accoppia il servizio a un DB e ne rompe l'agnosticità. Scartata: l'audit lo fa il chiamante archiviando il JSON. - Webhook/notifiche integrate — stessa obiezione: responsabilità del chiamante.
- Report solo via log — meno consumabile a macchina; lo stdout-JSON è parsabile e componibile.
Conseguenze
- Positive: servizio semplice, portabile e testabile (funzione pura
pipeline+config → report); l'output si integra con qualsiasi orchestratore (redirezione stdout,jq, archiviazione a scelta). - Costi/limiti:
- Storico/aggregazioni delle run sono responsabilità del chiamante (es. salvare i JSON).
- Per i dettagli completi degli scarti serve configurare un dead-letter sink.

