0044. La documentazione vive nell'app desktop, al posto della guida in-app
- Stato: Accettata
- Data: 2026-09-14
- Decisori: Team BI/ETL
- Contesto correlato: ADR-0043 (il sito), ADR-0025 (l'app desktop Tauri)
Contesto
ADR-0043 ha introdotto il sito di documentazione generato da docs/, lasciando aperto dove pubblicarlo. Nel frattempo noeva-etl-ui aveva la sua pagina /guida: una sintesi scritta a mano in JSX di due documenti del repository, da rivedere a mano ogni volta che quei documenti cambiavano (noeva-etl-ui/docs/navigation.md, § Contenuto della guida). Due testi sullo stesso argomento, uno dei quali destinato a restare indietro.
L'app è usata solo dal team di Gruppo4D, e chi la apre è esattamente il pubblico del sito: chi consulta i processi e chi li crea. GitHub Pages sui repo privati non è disponibile con il piano dell'org, e un hosting separato avrebbe voluto dire un accesso in più da gestire.
Decisione
Il sito di documentazione è la guida dell'app: la pagina /guida di noeva-etl-ui lo mostra al posto della sintesi in JSX.
Nel bundle, non da rete.
pnpm run docs:bundle(innoeva-etl-ui) builda il sito dal repository padre con base/docs/dentronoeva-etl-ui/public/docs/(git-ignored); Vite lo copia nel bundle e Tauri lo serve come il resto del frontend. La build di produzione (pnpm build, quindipnpm tauri build) lo esegue da sola, e fallisce con un messaggio chiaro se la UI non è dentro un checkout di noeva-etl con le dipendenze installate. Funziona offline, come i font self-hostati dell'app.In un iframe, dentro l'app.
/guidatiene l'header dell'app (marchio, «← Processi», tema) e sotto mostra il sito. Resta fuori dal gate di autenticazione, come prima.Un protocollo
postMessageminimo fra le due parti — lato sitodocs/.vitepress/lib/embed-protocol.tse il componenteEmbedBridge, lato appsrc/lib/docs-embed.ts— con tre messaggi:ready(sito → app): il sito si è montato. Un percorso che l'app non trova ricade sul suoindex.html: senza questo segnale l'iframe potrebbe mostrare l'app dentro sé stessa. L'iframe resta nascosto finché il sito non risponde, e se non risponde l'app dice che la documentazione non è inclusa nella build.theme(app → sito): il tema lo decide l'app; dentro l'iframe il selettore del sito sparisce.open-external(sito → app): nella webview Tauri un link esterno non apre nulla. Il sito intercetta il clic e l'app apre l'URL nel browser di sistema con@tauri-apps/plugin-opener, con lo scope limitato ahttpse all'httpversolocalhoste127.0.0.1.
Il sito resta un sito. Fuori da un iframe nessun messaggio parte e nulla cambia: la stessa build si può ancora consultare con
pnpm run docs:dev. Dentro l'app, logo e wordmark lasciano il posto alla scritta «Documentazione», perché il marchio sta già nell'header dell'app.Due varianti, scelte con
NOEVA_DOCS_TARGET. Ogni cliente ha le sue pipeline, quindi le parti che parlano di un cliente non vanno in una documentazione pubblicata fuori dall'app:app— la variante chedocs:bundlemette nell'app. Contiene tutto.public— il default, per un hosting esterno (Cloudflare Workers, ADR-0045). Esclude i percorsi elencati inAPP_ONLY(docs/.vitepress/lib/docs-target.ts: le schede pipeline e i runbook delle pipeline di un cliente) e i passaggi dei documenti pubblici racchiusi in un blocco::: solo-app. I link verso ciò che è escluso diventano testo semplice: un link a GitHub direbbe comunque di quale cliente è la pipeline. Sparisce anche il conteggio delle schede nella home.
Il default è
publicperché una build lanciata senza pensarci non deve esporre le pipeline dei clienti. Il gate (pnpm run checke la CI) builda entrambe le varianti.
Alternative considerate
- Servire il sito da
etl serve. L'app parla già con quel server, ma la documentazione dipenderebbe dalla rete e da un server acceso, e un container ETL servirebbe pagine web che non sono affar suo. - Aprire il sito a finestra piena, uscendo dall'app React. Nella finestra Tauri non c'è un pulsante Indietro: servirebbe un link di ritorno dentro il sito, e il tema non sarebbe più dell'app.
- Link esterni disattivati nell'app. Nessun permesso Tauri in più, ma i riferimenti a GitHub e Jira — decine, non i due che avevano fatto scartare il plugin opener per la vecchia guida — diventerebbero testo morto per chi ha accesso al repository.
- Un hosting esterno come unica sede. Un accesso in più da proteggere e un posto in più da tenere aggiornato, per un pubblico che ha già l'app. Resta possibile come sede aggiuntiva per la variante
public, che non contiene nulla di specifico dei clienti: con ADR-0045 la si pubblica su Cloudflare Workers. - Un'unica variante, con le pipeline in pagine non linkate. Una pagina fuori dal menu resta raggiungibile e finisce nell'indice di ricerca: nascondere non basta, bisogna non pubblicare.
Conseguenze
- Positive. Una sola documentazione, sempre coerente con i documenti del repository al momento della build dell'app; consultabile offline; la sintesi a mano sparisce, e con lei il lavoro di tenerla allineata.
- Costi. Il bundle dell'app cresce di circa 17 MB, soprattutto per mermaid, che però si carica solo sulle pagine con un diagramma. La build della UI richiede il checkout di noeva-etl con
pnpm installfatto: è già il modo in cui la UI si builda, come submodule. - La documentazione nell'app è quella del momento della build. Un documento cambiato dopo arriva nell'app con la release successiva. In sviluppo si rigenera con
pnpm run docs:bundle(./dev-desktop.shlo fa da solo la prima volta). - Contratto a due metà. Il protocollo è definito in due repository; ciascuna metà ha i suoi test, e i due file si citano a vicenda. Chi ne cambia uno cambia l'altro.
- Un vincolo in più per chi scrive. Un documento nuovo specifico di un cliente va sotto
docs/pipelines/, oppure si aggiunge adAPP_ONLY; un passaggio che nomina un cliente in un documento pubblico va in un blocco::: solo-app. Su GitHub i marcatori del blocco restano visibili come testo.

