Skip to content

ADR-0024: server HTTP dei grafi delle pipeline (etl serve)

  • Stato: Accettata
  • Data: 2026-07-21

Contesto

Fino a questa decisione la topologia dei grafi delle pipeline (i PlanSpec prodotti da getSpec()) veniva materializzata a build-time dalla UI: noeva-etl-ui lanciava etl plan, catturava il JSON e lo congelava in src/data/plans.generated.json, importato in modo sincrono. La generazione dei dati viveva quindi nel repo sbagliato (la UI), e i grafi erano un artefatto di build statico: aggiungere o cambiare una pipeline richiedeva rigenerare e ricommittare il JSON nella UI.

Volevamo ribaltare la responsabilità: i grafi devono essere generati da noeva-etl (che possiede il registro PIPELINES) ed esposti via API HTTP, così che la UI li consumi a runtime senza artefatti di build.

Decisione

Introdotto un server HTTP read-only in src/server/, avviato dal nuovo comando etl serve (src/cli.ts), stack Express 5 + cors (coerente con noeva-server-api):

  • buildGraphCache() (src/server/graph-cache.ts) itera PIPELINES, chiama getSpec() e costruisce una cache immutabile nome → PlanSpec una sola volta all'avvio. getSpec() è puro/deterministico (nessuna credenziale, nessun I/O), quindi la generazione al boot è sicura e a costo trascurabile.
  • createServer() (src/server/http-server.ts) espone:
    • GET /health{ status: "ok" };
    • GET /graphs{ name, description }[] (lista per il selettore pipeline);
    • GET /graphs/:namePlanSpec (dettaglio), 404 { message } se sconosciuto.
  • startServer() (src/server/run-server.ts) legge ETL_HTTP_PORT (default 3005, distinta da noeva-server-api = 3002) e ETL_HTTP_CORS_ORIGIN (default *).
  • Lifecycle SIGTERM/SIGINT come etl worker.

Nessuna autenticazione sull'API: espone solo topologia + descriptor non sensibili (ADR-0020), gli stessi dati che erano già pubblici nel bundle della UI. In produzione la protezione è la restrizione dell'origine via ETL_HTTP_CORS_ORIGIN.

etl plan (stampa su stdout) resta invariato per uso da CLI/debug.

Conseguenze

  • La UI passa da import statico a fetch async (VITE_ETL_API_BASE_URL), con stati loading/error; scripts/generate-plans.mjs e plans.generated.json vengono rimossi.
  • Il container etl deve ora esporre una porta e girare etl serve come servizio distinto dal worker — aggiornamento di Dockerfile/docker-compose.yml/ deploy-ecr.sh (follow-up operativo, vedi runbook).
  • Il contratto PlanSpec è invariato: la sincronizzazione manuale col contratto Zod della UI (ADR-0020) resta valida.

Noeva è un marchio registrato di 4D S.R.L.