node-orchestrator

Coordinamento di workflow inter-servizio.
orchestration
/orchestratorauth: nginx

node-orchestrator

In sintesi

Motore di workflow inter-servizio: registra moduli esterni che dichiarano i propri task, persiste i workflow (grafi diretti di task con connessioni e mapping dati), distribuisce le esecuzioni tramite NATS e tiene traccia in PostgreSQL dello stato di ogni step. Adotta il pattern thin modules, smart hub: la logica orchestrale (retry, parallelismo per livelli, propagazione errori, sagas) sta nell'hub; i moduli si limitano a esporre i propri handler. È il cuore dell'automazione del tenant ditta.

Funzionalità principali

  • Registry di moduli con heartbeat, healthcheck periodico e marcatura automatica come "unhealthy" quando un modulo smette di rispondere
  • Persistenza workflow versionata su PostgreSQL, con clone, import/export, validazione strutturale (cicli, task orfani, schemi I/O incompatibili) e cambi di stato (draft/active/archived)
  • Esecuzione asincrona dei workflow su NATS: dispatching dei task ai moduli per nome, attesa reply, calcolo del livello successivo eseguibile in parallelo
  • Data mapping tipizzato fra step (template {a} {b}, concat, condizioni, dot-notation per campi annidati)
  • Trigger pluggabili: schedulati (via node-scheduler), webhook esterni, eventi NATS interni
  • Audit completo delle esecuzioni: timeline degli eventi, log strutturati, statistiche di durata per task/livello, progress in tempo reale via SSE
  • Sagas per compensazione su fallimento di task non idempotenti
  • Cache distribuita Redis opzionale per i dataset di modulo più richiesti

Architettura

Stack: Fastify v5 · Inversify (DI con constructor injection) · PostgreSQL via driver pg · NATS (con JetStream opzionale) · Redis · @pzeta/fastify-utils (auth, security, healthcheck, OpenAPI plugins) · @pzeta/log per logging strutturato.

Layout DDD (src/):

LayerContenuto
domain/Workflow (aggregate root), value object, errori, factory, eventi di dominio
application/Servizi orchestrali (WorkflowService, ExecutionService, RegistryService, ExecutionLoggerService), sagas, trigger manager
infrastructure/DatabaseService, MessagingService (NATS), CacheService (Redis), WebhookNotifier, SSEBridge
presentation/Controllers, route plugins (WorkflowRoutes, ExecutionRoutes, RegistryRoutes, WebhookRoutes, DiagnosticsRoutes), middleware RBAC

Pattern adottati: thin modules / smart hub, Repository, Saga, Circuit Breaker sul dispatching NATS, Event Sourcing parziale per la timeline delle esecuzioni.

RBAC: ogni route dichiara uno scope minimo (viewer, operator, admin) via requireScope(). Gli scope vengono letti dal token dell'authenticatore (fastify.authenticate() registrato da @pzeta/fastify-utils).

Casi d'uso

  • Pipeline di import dati: trigger schedulato → step di download da node-storage → validazione XML via node-xmlvalidation → import in DB via node-postgrest-sidecar → notifica completamento via node-notification
  • Generazione documenti batch: trigger webhook esterno → fan-out su N occorrenze → ciascuna invoca node-renderer + node-print → archiviazione su node-storage
  • Reazione a eventi di dominio: un workflow è sottoscritto a workflow.events.task.failed.> per innescare compensazioni o alert operativi
  • Export dati ricorrente: scheduler attiva un workflow che usa node-excel-export su un dataset PostgREST e deposita l'output su node-storage con notifica a fine job
  • Workflow interattivi: il frontend Vue chiama POST /executions per avviare un workflow ad-hoc e si sottoscrive via SSE alla timeline di esecuzione per mostrare il progresso

Identità & esposizione

CampoValore
Categoriaorchestration
Versione cluster1.0.0
Imagegitea.pzetatouch.it/pzeta_touch/node-orchestrator:1.0.10
URL pubblicohttps://ditta.pzeta.it/orchestrator
Path regex ingress`/orchestrator(/
Rewrite a backend/$2
DNS internonode-orchestrator-ditta.ditta.svc.cluster.local:3000
Auth nginxauth_requestnode-user-auth
Repositorynode-orchestrator
Endpoint REST44 (vedi sezione "API reference")

Endpoint operazionali

Endpoint convenzionali esposti da tutti i microservizi PZeta basati su @pzeta/fastify-utils:

Path pubblicoScopo
https://ditta.pzeta.it/orchestrator/healthliveness probe
https://ditta.pzeta.it/orchestrator/readyreadiness probe
https://ditta.pzeta.it/orchestrator/metricsmetriche Prometheus
https://ditta.pzeta.it/orchestrator/api-docs.jsonspec OpenAPI runtime (richiede OPENAPI_EXPOSE_IN_PRODUCTION=true)
https://ditta.pzeta.it/orchestrator/api-docsSwagger UI (solo in NODE_ENV !== production)

Configurazione

Variabili d'ambiente che un integratore deve conoscere (per la lista completa vedi .env.example del repo):

VariabileRuolo
DATABASE_HOST / _PORT / _USER / _PASSWORD / _NAMEConnessione PostgreSQL — workflow, esecuzioni, log
DATABASE_SCHEMADefault nodeorchestrator; un workflow può accedere ad altri schemi via PostgREST sidecar
NATS_URLURL del cluster NATS; obbligatorio
NATS_NAMESPACEPrefisso applicativo dei subject (default orchestrator)
NATS_JETSTREAM_ENABLEDSe true, le esecuzioni usano JetStream per delivery garantita
REDIS_ENABLEDAbilita la cache distribuita per i dataset; off in dev
API_KEYSCoppie key:user:scopes per autenticazione M2M (dev e moduli locali)

L'orchestrator espone Swagger UI solo se NODE_ENV !== production e /api-docs.json runtime solo se OPENAPI_EXPOSE_IN_PRODUCTION=true.

Note eventing NATS

Il servizio si comporta come consumer puro del proprio dominio: si sottoscrive a sei subject pattern (workflow.events.execution.*, workflow.events.task.*, workflow.events.level.completed.>) per popolare la timeline e gli aggregati di ExecutionLoggerService. Il pubblicatore di questi eventi è il modulo che esegue il task: l'orchestrator riceve la conferma asincrona via NATS invece di un polling.

Le request/reply verso i moduli registrati avvengono su subject derivati dal manifest del modulo (non statici, quindi non compaiono nello scanner statico). Quando JetStream è abilitato il dispatching è at-least-once con deduplica per executionId.

Dipendenze e dipendenti

Dipende da (servizi che questo servizio chiama):

Consumato da (chi chiama questo servizio):

Infrastruttura (PostgreSQL, NATS, Redis, MinIO) non è elencata qui — vedi sezione Architettura del singolo servizio.

Loading OpenAPI…
Loading NATS contracts…