Skip to content

ADR-0025 — noeva-etl-ui come app desktop Tauri v2 (non più web-app nginx)

  • Stato: Accettata
  • Data: 2026-07-22
  • Supera: ADR-0023 (deploy UI nginx/ECR)
  • Contesto correlato: ADR-0019/0021 (worker via API, workspace), ADR-0024 (server HTTP grafi)

Contesto

noeva-etl-ui è una SPA React 19 + Vite + React Router (DAG via @xyflow/react/elkjs) che consuma due backend remoti: noeva-server-api (VITE_API_BASE_URL, auth + processi) e il server HTTP dei grafi ETL (VITE_ETL_API_BASE_URL, vedi ADR-0024). Finora era distribuita come immagine nginx su ECR insieme al worker (ADR-0023).

Si vuole distribuirla come applicazione desktop invece che come web-app. L'auth è già token-based (Bearer access/refresh in localStorage, nessun cookie) — favorevole a un webview desktop, che non condivide i cookie del browser.

Decisione

Wrappare l'app Vite/React esistente in Tauri v2, senza riscrivere il frontend.

  • Stack invariato. Nessuna migrazione a SvelteKit o altro: si aggiunge src-tauri/ e si configura Vite per Tauri (clearScreen:false, server.port fisso 5173 + strictPort, envPrefix con VITE_+TAURI_ENV_*, build.target moderno). BrowserRouter è mantenuto: la navigazione è in-app, senza reload reali.
  • Networking via plugin HTTP di Tauri. Dall'origine tauri://localhost la fetch del webview sarebbe soggetta a CORS verso i due backend. Si usa invece @tauri-apps/plugin-http: le richieste passano dal lato Rust (reqwest), aggirando la CORS senza toccare i server. Punto di indirezione unico in src/services/api/http.ts (ri-esporta fetch); i tre call-site (base-client.ts ×2, graphs.ts) importano da lì. Gli host autorizzati sono nello scope http:default di src-tauri/capabilities/default.json.
  • Font self-hostati. I font (Sora, Hanken Grotesk, JetBrains Mono, subset latin+latin-ext) sono in public/fonts/ con @font-face locale invece della CDN Google Fonts → l'app funziona offline.
  • Rimozione del deploy web. Coerente con "non più web-app": eliminati Dockerfile, nginx.conf, .dockerignore della UI; deploy-ecr.sh/run-ecr.sh tornano worker-only (rimossi flag --ui/--no-ui, repo ECR -ui, mode UI). ADR-0023 è superato.

Alternative scartate

  • Configurare la CORS lato server per l'origine tauri://localhost: richiede modifiche a noeva-server-api e al server grafi ETL (più superfici di rottura, più repo toccati) per un problema che il plugin HTTP risolve interamente lato client.
  • Riscrivere il frontend in SvelteKit: scope enorme, si butta un'app React funzionante, nessun beneficio per l'obiettivo desktop.
  • Mantenere sia web sia desktop: dual-target, più manutenzione, contro l'obiettivo esplicito.

Conseguenze

  • Nuova dipendenza dal toolchain Rust (cargo/rustc ≥ 1.77.2) per buildare l'app.
  • Le VITE_* restano congelate a build-time nel binario: l'URL dei backend è fissato per build. Ambienti diversi ⇒ binari diversi (come già per il bundle web). Nessuna config runtime.
  • Lo scope http:default va tenuto allineato agli host dei backend: oggi include solo http://localhost:3002/* e :3005/* (dev). Gli host di produzione vanno aggiunti prima di distribuire un build (vedi capabilities/default.json).
  • build.target non usa i valori safariNN del template Tauri (fanno fallire il toolchain Vite 8/rolldown sul lowering del destructuring): si usa es2021 (non-Windows) / chrome105 (Windows), adeguati alle WebView evergreen di Tauri.
  • Fuori scope per ora: auto-updater, code-signing/notarization, CI di release desktop.

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