node-excel-export

Esportazione di dati in formato Excel/CSV.
data-io
/excel-exportauth: nginx

node-excel-export

In sintesi

Servizio di esportazione tabellare che trasforma payload JSON o query su PostgreSQL in file Excel (XLSX) e CSV pronti al download. Espone due workflow distinti: uno legacy a payload diretto (il chiamante passa righe e intestazioni) e uno dinamico basato su modelli persistiti su DB, dove il client indica risorsa, campi, filtri e ordinamento, e il servizio costruisce la query, esegue l'estrazione paginata e formatta il file. È il punto di uscita standard per le funzioni "Esporta" del frontend Vue del tenant ditta.

Funzionalità principali

  • Export sincrono da payload JSON (POST /export) per fogli singoli o multi-worksheet con intestazioni, righe e merge cells dichiarate dal client
  • Export dinamico da template DB (POST /api/export/dynamic) che esegue query sicure su risorse registrate (anagrafica, articoli, ecc.) applicando campi, filtri, ordinamento e limite
  • CRUD modelli di export persistiti su PostgreSQL (modelliexport): creazione, aggiornamento, soft delete e contatore volteusato per le statistiche
  • Discovery metadati campi per risorsa (GET /api/export/metadata/:risorsa/fields) consumata dalla libreria @pzeta/vue-importexport per costruire l'UI di selezione
  • Strategy multi-formato (XLSX via exceljs, CSV streaming) selezionata dinamicamente dal formato richiesto
  • Rate limiting per IP configurabile (default 10 richieste / 60 s) sulla rotta di export, applicato dal securityPlugin di @pzeta/fastify-utils
  • Validazione strutturale Zod su request, schema OpenAPI auto-generato e formattazione uniforme degli errori HTTP 400/422
  • Logging applicativo delle esportazioni su tabella logexportazioni per audit e diagnostica, con request ID di tracing propagato
  • Migrazioni automatiche dello schema importexport all'avvio (idempotenti) se RUN_MIGRATIONS=true

Architettura

Stack: Fastify v5 · TypeScript strict · @pzeta/fastify-utils (security/error-handler/healthcheck/openapi/metrics/tracing/logging) · @pzeta/log per logging strutturato · PostgreSQL via driver pg diretto · exceljs per la generazione XLSX · Zod per la validazione · DI container interno (infrastructure/container/DIContainer.ts) con risoluzione per token string.

Layout DDD (src/):

LayerContenuto
domain/Entità (ExportJob, ExportTemplate, ExportLog, Workbook, Worksheet), repository interface (IExportTemplateRepository, IExportLogRepository, IFileManager, IDatabaseQueryProvider), servizi di dominio per formattazione ed export
application/DTO request/response, ExportApplicationService, DynamicExportService, DynamicQueryService, RequestValidationService, adapter verso strategie infrastrutturali
infrastructure/PostgresConnection (pool pg), MigrationRunner, repository concreti, ExportStrategyFactory con XlsxExportStrategy e CsvExportStrategy, EnvironmentConfig singleton
presentation/Plugin di route (export.routes, dynamicExport.routes, exportLimits.routes, exportExamples.routes, buildInfo.routes), controller dedicati per ciascuna famiglia di endpoint, schemi Fastify+JSON-Schema generati da Zod

Pattern adottati: Strategy (un'implementazione per ogni formato di output), Factory per la selezione della strategia, Repository per la persistenza dei template e dei log, DI container leggero con resolve per token. La generazione del file avviene in memoria (stream) e ritorna Content-Disposition: attachment direttamente nella response, senza scrittura su disco né caricamento su storage esterno.

Sicurezza: dietro nginx con auth_request verso node-user-auth (strategia nginx); nessun token applicativo verificato dal servizio. Il rate limiting è applicato per IP a livello di plugin.

Casi d'uso

  • Export "Esporta tabella" dal frontend: una griglia Vue del Laundry ERP (anagrafiche, articoli, ordini) invoca POST /api/export/execute (alias compatibile con @pzeta/vue-importexport) con risorsa, campi selezionati, filtri della ricerca e ordinamento corrente; riceve il file XLSX da scaricare
  • Riuso di un modello salvato: l'operatore seleziona un template precedente (GET /api/export/templates/:risorsa), il servizio lo applica con i filtri runtime e incrementa volteusato per le statistiche d'uso
  • Export ad-hoc da modulo legacy: un microservizio chiama POST /export passando direttamente intestazioni e righe già pronte (ad esempio un report aggregato calcolato altrove), senza coinvolgere la pipeline dinamica
  • Step di un workflow orchestrato: node-orchestrator esegue un export programmato come task di un workflow notturno e inoltra l'output a node-storage o a un destinatario via node-notification
  • Discovery UI: la libreria @pzeta/vue-importexport chiama GET /api/export/metadata/:risorsa/fields per popolare il selettore campi con i metadati ufficiali della risorsa (label, tipo, gruppo)

Identità & esposizione

CampoValore
Categoriadata-io
Versione cluster1.0.3
Imagegitea.pzetatouch.it/pzeta_touch/node-excel-export:1.0.3
URL pubblicohttps://ditta.pzeta.it/excel-export
Path regex ingress`/excel-export(/
Rewrite a backend/$2
DNS internonode-excel-export-ditta.ditta.svc.cluster.local:3000
Auth nginxauth_requestnode-user-auth
Repositorynode-excel-export
Endpoint REST13 (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/excel-export/healthliveness probe
https://ditta.pzeta.it/excel-export/readyreadiness probe
https://ditta.pzeta.it/excel-export/metricsmetriche Prometheus
https://ditta.pzeta.it/excel-export/api-docs.jsonspec OpenAPI runtime (richiede OPENAPI_EXPOSE_IN_PRODUCTION=true)
https://ditta.pzeta.it/excel-export/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; lo schema applicativo è importexport (template, log) ma il servizio interroga anche le tabelle business per l'export dinamico
DATABASE_POOL_MAX / _IDLE_TIMEOUT_MS / _CONNECTION_TIMEOUT_MSTuning del pool pg; default 20 / 30000 / 2000 ms
RUN_MIGRATIONSEsegue le migrazioni dello schema importexport all'avvio; true di default
TEMP_DIRECTORYCartella per file temporanei di lavoro (./temp); il servizio non persiste l'output, ma può usarla per buffering
MAX_FILE_SIZE_MBLimite hard sulla dimensione del file generato (default 50 MB); oltre il limite la richiesta fallisce con 413
EXPORT_RATE_LIMIT_REQUESTS / EXPORT_RATE_LIMIT_WINDOW_MSRate limit per IP sulle rotte di export (default 10 richieste / 60 s)
CORS_ALLOWED_ORIGINSOrigini consentite in produzione, separate da virgola; in NODE_ENV !== production la policy è aperta
REVERSE_PROXYAbilita trustProxy di Fastify quando il servizio è dietro nginx

Swagger UI è esposto solo se NODE_ENV !== production; le metriche Prometheus sono pubblicate con prefisso excel_export_.

Note eventing NATS

Il servizio non partecipa al bus NATS: lo scanner statico ha rilevato zero subject pubblicati e zero subscription attive (vedi nats.json). L'integrazione è puramente sincrona via HTTP REST: il client (frontend Vue, altro microservizio, node-orchestrator come step di workflow) effettua una POST e riceve in risposta lo stream del file. Eventuali audit cross-servizio sulle esportazioni vanno costruiti sopra la tabella logexportazioni di questo servizio, non su eventi di dominio.

Dipendenze e dipendenti

Dipende da (servizi che questo servizio chiama):

Consumato da (chi chiama questo servizio):

  • frontend Vue

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

Loading OpenAPI…
Loading NATS contracts…