# ADR 0021 — Shell separati e adapter sostituibile per il portale - Stato: accettato - Data: 2026-09-13 ## Decisione ThothII espone due modalità di installazione, selezionate da `shell.mode`: - `embedded` (default): ThothII è ospitato da Omics Portal. Non renderizza alcun header e riceve dal portale lingua, tema e fullscreen. L'accesso resta verificato dal server. - `full`: ThothII è autonomo. Renderizza il proprio header, con selettore lingua, tema, fullscreen e nome utente. Il click sul nome apre il logout. Non mostra mai la rotellina o altri comandi amministrativi del portale. Mantiene un rail vuoto a sinistra di almeno 20 px. Il fatto che la shell sia `full` è distinto dallo stato `fullscreen`: la prima decide quale contenitore viene renderizzato, il secondo indica se è attiva la Fullscreen API del browser. L'icona passa da “entra in fullscreen” a “torna alla modalità normale”; anche `Esc` aggiorna lo stato visualizzato. La configurazione installata resta semplice e retrocompatibile. Sul Mac di sviluppo il profilo locale userà: ```yaml shell: mode: full defaultLocale: en ``` Il deploy sul server userà invece: ```yaml shell: mode: embedded adapter: omics-portal ``` `defaultLocale` indica la lingua iniziale della shell full; in embedded la fonte autorevole resta il portale. L'adapter è l'unico confine tra ThothII e il portale. La sua interfaccia pubblica è volutamente profonda e minima: consegna solo snapshot dello stato, senza esporre comandi, token, identità o dettagli di trasporto. ```ts export type HostShellState = { locale: string; // BCP-47, inizialmente it/en theme: "light" | "dark"; fullscreen: boolean; }; export interface PortalAdapter { subscribe( onState: (state: HostShellState) => void, onError: (error: Error) => void, ): () => void; } ``` `OmicsPortalAdapter` è l'implementazione corrente. Un adapter per un altro portale potrà sostituirlo senza modificare shell, i18n o workflow. In `full` l'adapter non viene istanziato: lo stato è gestito internamente dalla shell. Per l'integrazione oggi operativa, che monta la SPA direttamente nel DOM di Omics Portal, l'adapter legge la lingua effettiva dal selettore Omics, osserva l'attributo del tema e ascolta il fullscreen del documento. Selettori e osservatori restano privati dell'implementazione Omics. La lingua segue il normale ricaricamento Django; tema e fullscreen cambiano nella pagina aperta. La revisione approvata del 2026-09-13 elimina il precedente handshake a eventi: non servono messaggi personalizzati, versioni di trasporto o timeout di avvio. Un futuro adapter potrà usare un diverso trasporto senza modificare l'interfaccia applicativa. Se `shell` o l'adapter embedded sono omessi, si usa `embedded` con `omics-portal`. Questo default supporta il documento Omics esistente; nomi adapter sconosciuti o dati host mancanti producono un errore esplicito, senza attivare la shell full. ## Confini che restano invariati L'identità e l'autorizzazione del backend non vengono ricostruite nel browser. In embedded, Omics Portal continua a gestire login e logout e la catena server-side `auth_request` continua a fornire i principal header già previsti. Lo stato UI non dichiara l'utente autenticato: il modulo di accesso usa la verifica backend esistente anche alla riconnessione e al ritorno alla pagina. Un rifiuto su una singola operazione non equivale automaticamente alla perdita dell'accesso. La lingua UI e la lingua di interazione con il modello restano separate dalla lingua del workspace; il relativo contratto è in [ADR 0022](0022-separate-ui-locale-from-session-interaction-language.md). ## Alternative scartate - Duplicare l'header di Omics in embedded: crea due fonti di stato e incompatibilità visive. - Spargere controlli `if embedded/full` nei componenti: lega ogni pagina al portale. - Trasmettere utente o token nel bridge: aumenta superficie e accoppia UI e autenticazione. - Introdurre un protocollo completo request/response: non aggiunge funzionalità richiesta. - Usare `profile` per distinguere le shell: `profile` descrive la topologia dell'installazione, non la sua presentazione. ## Conseguenze La soluzione richiede un adapter nel frontend che osserva il documento condiviso e mantiene la logica di shell locale a ThothII. Il backend non necessita di un nuovo protocollo di autenticazione o di una nuova sessione browser. Un nuovo portale deve soddisfare anche il contratto server di identità fidata: la sola sostituzione della classe UI non sostituisce quel contratto.