Add full shell, replaceable Omics adapter and bilingual interaction
Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# Full shell, Omics e interfaccia bilingue — verifica
|
||||
|
||||
Data: 2026-09-13. Specifica: [Full shell, integrazione Omics e interfaccia bilingue](../plans/2026-09-13-full-shell-spec.md).
|
||||
I cinque ticket e le loro dipendenze sono elencati nel [piano](../plans/2026-09-13-full-shell-and-portal-integration.md).
|
||||
|
||||
## Risultato
|
||||
|
||||
- Configurazione pubblica generata dal descrittore installato; full ed embedded
|
||||
usano la stessa immagine frontend. Sul Mac: `full`, locale iniziale `en`.
|
||||
- Header full con lingua, tema, fullscreen reale e menu utente/logout; rail sinistro
|
||||
vuoto di almeno 20 px. Nessuna rotellina amministrativa.
|
||||
- Embedded senza header locale; `OmicsPortalAdapter` incapsula l'osservazione del
|
||||
portale. Identità e autorizzazioni rimangono verificate dal server.
|
||||
- Cataloghi EN/IT, traduzioni dei controlli delle griglie, grafici e SQL adattati
|
||||
al tema. I contenuti di dominio rimangono invariati.
|
||||
- `interaction_language` fissata nel manifest: cattura alla creazione, mantenimento
|
||||
alla ripresa e assegnazione atomica del valore workspace per sessioni precedenti.
|
||||
- Continuità della selezione al reload, nessuna ripresa automatica del modello e
|
||||
protezione delle bozze non inviate.
|
||||
|
||||
La [guida operativa](../operations/shell-and-localization.md) descrive configurazione,
|
||||
accesso, estensione ad altri portali/lingue e checklist di deploy.
|
||||
|
||||
## Verifiche automatiche
|
||||
|
||||
| Livello | Esito |
|
||||
| --- | --- |
|
||||
| CLI nativa Go | `go test ./...`: 21 package verificati |
|
||||
| Harness Python | 1290 passati, 1 saltato, 6 L2 esclusi |
|
||||
| Gate Pi JavaScript | 205 passati |
|
||||
| Frontend | suite completa: 755 passati in 90 file; regressione CSS prebuild superata |
|
||||
| Backend | suite completa Node 24: 1397 passati, 40 saltati |
|
||||
| Omics Docker isolato | 15 test Django/integrazione passati; controlli JavaScript del browser inclusi |
|
||||
| Cataloghi | 1666 messaggi italiani, 1701 riferimenti statici; conflitti e interpolazioni verificati |
|
||||
| Build | frontend, backend/typecheck e documentazione MkDocs strict verificati; regressione CSS eseguita automaticamente prima della build frontend |
|
||||
|
||||
La suite backend richiede Node 24. Sul Mac il percorso Homebrew `node@24`
|
||||
risolveva a Node 25; è stato usato esplicitamente Node 24.16.0 già presente in NVM,
|
||||
senza modificare il runtime globale. Un test preesistente sul timeout di arresto
|
||||
di un processo è fallito sotto carico parallelo ed è passato isolatamente;
|
||||
la verifica finale usa un solo worker.
|
||||
|
||||
I test coprono comportamenti pubblici e confini approvati: manifest filesystem e
|
||||
PostgreSQL, CLI, Fastify, processo Pi simulato, stream SSE, shell e widget React,
|
||||
template/autorizzazione Omics. Non è stata avviata una nuova generazione L2 contro
|
||||
il modello remoto o il DWH operativo. Il controllo statico dei cataloghi non è
|
||||
una prova di traduzione di ogni possibile messaggio diagnostico esterno.
|
||||
|
||||
## Standards
|
||||
|
||||
Revisione indipendente rispetto al punto iniziale ThothII
|
||||
`2d1b714ebe31419d712e9c3324a5e171d5f0317d` e Omics `aff7581`.
|
||||
Due violazioni concrete del contratto: bozze dei gate non protette dal reload e
|
||||
selezione di sessioni altrui persa per gli amministratori. Entrambe corrette e
|
||||
riesaminate dal revisore indipendente. La protezione resta attiva anche durante
|
||||
un invio e dopo un errore HTTP, fino all'accettazione e allo smontaggio del widget.
|
||||
Nessun ulteriore rilievo concreto sul codice Omics o sulle euristiche di manutenibilità.
|
||||
Esito finale del revisore: approvato, zero rilievi aperti.
|
||||
|
||||
## Spec
|
||||
|
||||
Quattro rilievi: i due precedenti, più verifica dell'identità mancante dopo una
|
||||
riconnessione SSE riuscita ed errori deterministici dello stream non tradotti.
|
||||
Le correzioni includono test di regressione e sono state riesaminate dal revisore
|
||||
indipendente. Sono tradotti anche gli errori sanitizzati di avvio e le notifiche
|
||||
deterministiche dei gate già localizzate nella lingua fissata della sessione.
|
||||
Esito finale del revisore: tutti e quattro i rilievi chiusi, nessun nuovo rilievo
|
||||
o ampliamento ingiustificato dell'ambito.
|
||||
|
||||
Riepilogo iniziale: Standards 2 rilievi P2; Spec 4 rilievi P2. Gli assi restano
|
||||
separati; i rilievi comuni non rappresentano ulteriori difetti distinti.
|
||||
Riepilogo finale: Standards 0 aperti; Spec 0 aperti.
|
||||
|
||||
## Collaudo visivo
|
||||
|
||||
Il collaudo con l'account locale autenticato ha trovato tre difetti non visibili
|
||||
nei test DOM dei componenti:
|
||||
|
||||
1. Il contenitore CSS `@scope` includeva l'intero livello base Tailwind e nel browser
|
||||
integrato non applicava i token. Il CSS era servito con HTTP 200, ma il font
|
||||
effettivo era Times e `--background` risultava vuoto. L'isolamento del reset
|
||||
è ora compilato in selettori ordinari, senza modificare gli stili del portale.
|
||||
Il browser applica Manrope e i token light/dark corretti. Revisione indipendente
|
||||
del CSS compilato: nessuna perdita di isolamento individuata.
|
||||
2. La classe full costruita per interpolazione faceva eliminare il token del
|
||||
margine dalla build Tailwind. Nomi di classe letterali e una regressione sulla
|
||||
presenza di `--thot-shell-gutter` rendono il requisito verificabile nella build.
|
||||
3. Le griglie amministrative caricavano il tema CSS preesistente insieme al nuovo
|
||||
tema automatico della libreria. Griglie amministrative e anteprime ora usano
|
||||
un solo sistema CSS con i token della shell, eliminando il conflitto. I token
|
||||
vengono applicati anche ai contenitori di tema interni creati da AG Grid,
|
||||
che altrimenti sovrascriverebbero i colori ereditati.
|
||||
|
||||
Questi controlli sono stati eseguiti prima del commit di consegna. Il nuovo test
|
||||
`scripts/scoped-base.test.mjs` viene eseguito dal comando `prebuild` anche in Docker.
|
||||
Le prove di lingua/tema non hanno modificato dati del catalogo o avviato sessioni.
|
||||
|
||||
## Installazione locale e recupero
|
||||
|
||||
Il binario nativo aggiornato è installato in `/usr/local/bin/tht`.
|
||||
Il descrittore locale, non versionato, è
|
||||
`deploy/psd/thothii-installation.yaml`; `installation generate` ha prodotto:
|
||||
|
||||
```javascript
|
||||
window.__THOTHII_CONFIG__ = {"backendBaseUrl":"/api","shell":{"mode":"full","defaultLocale":"en"}};
|
||||
```
|
||||
|
||||
Il progetto Docker locale è `thothii-18998cca7b0a`; l'aggiornamento riguarda soltanto
|
||||
core/frontend. Database, Qdrant, embedding e volumi persistenti restano invariati.
|
||||
Le immagini precedenti sono conservate come
|
||||
`thothii-core:before-full-shell-20260913` e
|
||||
`thothii-frontend:before-full-shell-20260913`.
|
||||
Binario e descrittore precedenti sono in `/private/tmp/thothii-shell-install.8idNoC`
|
||||
(copia temporanea locale, non backup permanente).
|
||||
|
||||
Il sorgente Omics aggiornato è registrato nel commit locale `95154e1`.
|
||||
Nessun push o deploy sul server di produzione è stato eseguito. Il collaudo
|
||||
operativo sul server resta una fase del normale rilascio, seguendo la guida.
|
||||
|
||||
Core/frontend locali aggiornati e healthy; `/api/health` restituisce 200,
|
||||
`/config.js` espone full/en e `/api/auth/config` conferma l'accesso locale.
|
||||
Con l'account locale autenticato sono stati controllati header, cambio EN/IT,
|
||||
light/dark, menu utente/logout, ingresso/uscita fullscreen tramite pulsante e
|
||||
margini effettivi di 24 px. I test automatici coprono logout e sincronizzazione
|
||||
con `fullscreenchange`, compreso il ritorno allo stato normale. L'uscita tramite
|
||||
tasto Esc nativo resta da provare in un browser desktop ordinario: il comando
|
||||
di tastiera automatizzato del browser integrato non l'ha riprodotta. Nessuna
|
||||
promessa di collaudo completo del browser del server è implicita in queste prove.
|
||||
Le preferenze locali sono state riportate a inglese e tema chiaro.
|
||||
@@ -0,0 +1,195 @@
|
||||
# Revisione della semplificazione della shell
|
||||
|
||||
Data: 2026-09-13. Oggetto: piano full/embedded, ADR 0021–0022 e contratto
|
||||
Portal Shell Adapter v1. Questa è una revisione con raccomandazioni: non modifica il
|
||||
codice applicativo né sostituisce automaticamente i contratti accettati.
|
||||
|
||||
## Valutazione
|
||||
|
||||
La separazione tra shell, autenticazione e lingua delle sessioni è corretta. La
|
||||
semplificazione precedente ha però mantenuto un protocollo di comunicazione non
|
||||
necessario per il montaggio corrente e ha lasciato ambigue alcune condizioni di
|
||||
compatibilità. Raccomando un adapter che osservi il documento già condiviso con
|
||||
Omics, riutilizzi l'autenticazione esistente e non imponga un nuovo bridge al portale.
|
||||
|
||||
La revisione considera il sorgente locale di ThothII e Omics Portal al commit
|
||||
`aff7581`, già ottenuto con il pull richiesto. Non certifica quali immagini,
|
||||
configurazioni o modifiche siano attualmente attive sul server.
|
||||
|
||||
## Problemi individuati e correzioni raccomandate
|
||||
|
||||
### 1. Il cambio lingua senza ricaricamento non corrisponde a Omics
|
||||
|
||||
In `templates/partials/topbar.html:74–87`, Omics usa il form Django `set_language`
|
||||
con `onchange="this.form.submit()"`. La lingua cambia attraverso una nuova pagina
|
||||
renderizzata dal server. Il criterio 2 del contratto v1 promette invece aggiornamenti
|
||||
senza ricaricamento per tutte le preferenze.
|
||||
|
||||
Raccomandazione: rispettare il comportamento del portale. In full, lingua e tema
|
||||
cambiano immediatamente. In embedded, il tema cambia immediatamente e la lingua
|
||||
segue il normale ricaricamento Omics. Evitare di intercettare il form per cambiare
|
||||
solo ThothII: lascerebbe header, sidebar e testi Django nella lingua precedente.
|
||||
|
||||
Il ricaricamento va verificato durante una sessione attiva e con modifiche non
|
||||
salvate: deve essere possibile ritrovare la sessione senza avviare una nuova
|
||||
generazione; eventuali bozze richiedono una protezione dalla navigazione. Lo stato
|
||||
persistito del workflow non equivale alla conservazione automatica della bozza UI
|
||||
o del flusso di messaggi in memoria. Questa verifica è necessaria anche mantenendo
|
||||
il protocollo a eventi del piano precedente.
|
||||
|
||||
### 2. Un protocollo ready/state non è necessario nello stesso documento
|
||||
|
||||
`templates/kokoro/datamart_builder.html` monta React in `#root`, nello stesso
|
||||
documento dell'header. L'adapter può ottenere direttamente:
|
||||
|
||||
- lingua effettivamente renderizzata: `data-lang` del selettore
|
||||
`.omics-language-select`;
|
||||
- tema: attributo `data-bs-theme` sull'elemento `html`;
|
||||
- fullscreen: stato del documento e relativo evento del browser.
|
||||
|
||||
Un'osservazione limitata all'attributo del tema e un listener del fullscreen
|
||||
coprono gli aggiornamenti attuali. La lingua viene riletta quando Django restituisce
|
||||
la pagina. Questi selettori e dettagli devono comparire soltanto dentro
|
||||
`OmicsPortalAdapter`, con test basati sul template reale.
|
||||
|
||||
Attenzione: `templates/base.html:3` contiene oggi `lang="en"` fisso; quell'attributo
|
||||
non è una fonte attendibile per la lingua Omics. Se in futuro il portale espone la
|
||||
lingua su un attributo dedicato del punto di montaggio, si modifica soltanto l'adapter.
|
||||
|
||||
La proposta elimina due eventi personalizzati, la versione del protocollo, il
|
||||
timeout di avvio e il rischio che il messaggio iniziale parta prima del listener.
|
||||
L'osservazione va installata prima di consegnare lo snapshot iniziale; la funzione
|
||||
di disiscrizione rimuove tutte le risorse. L'assenza dei dati Omics attesi produce
|
||||
un errore di integrazione comprensibile, senza attivare la shell full.
|
||||
|
||||
Il costo accettato è una dipendenza esplicita dal piccolo contratto DOM Omics,
|
||||
confinata nell'adapter. Un secondo portale potrà fornire gli stessi dati usando
|
||||
un'altra implementazione, anche con un diverso trasporto. Non occorre costruirla ora.
|
||||
|
||||
### 3. `authenticated` duplica uno stato che il server già verifica
|
||||
|
||||
`kokoro/datamart_catalog_views.py:49` e `nginx/nginx.conf:69` verificano l'accesso
|
||||
Omics e trasmettono al backend identità e autorizzazioni normalizzate. ThothII
|
||||
ottiene già l'utente tramite `/me`. Non serve un ulteriore login né un flag nel
|
||||
documento che dichiari l'utente autenticato.
|
||||
|
||||
Il logout Omics attuale è una navigazione (`topbar.html:118`), non un evento di
|
||||
revoca. Un click sul link non prova che il logout sia stato completato; inoltre,
|
||||
un flag inviato una volta non rileva la scadenza della sessione o un logout in
|
||||
un'altra scheda.
|
||||
|
||||
Raccomandazione: togliere `authenticated` dallo snapshot visivo. La verifica
|
||||
dell'accesso rimane nel percorso di autenticazione esistente. In embedded,
|
||||
perdita dell'accesso significa chiudere i dati protetti e demandare il rientro
|
||||
al portale, senza mostrare il form di login ThothII.
|
||||
|
||||
Serve verificare la gestione dei rifiuti Omics: l'endpoint di autorizzazione
|
||||
restituisce attualmente 403 anche quando l'accesso non è disponibile, mentre
|
||||
`frontend/src/api/client.ts` pulisce automaticamente lo stato su 401. Un 403
|
||||
ordinario può anche significare che manca il permesso per una sola operazione;
|
||||
non va trasformato indiscriminatamente in logout. La verifica `/me` deve
|
||||
distinguere la perdita di accesso all'applicazione dal rifiuto di una sua funzione.
|
||||
|
||||
`frontend/src/stream/useSessionStream.ts` esegue già un controllo di autenticazione
|
||||
quando il collegamento eventi fallisce: riutilizzare quel percorso. Non promettere
|
||||
revoca istantanea di una connessione già aperta in un'altra scheda sulla sola base
|
||||
di `auth_request` o di un evento nella pagina corrente. Il contratto deve dichiarare
|
||||
quando l'accesso viene ricontrollato e verificare anche il ritorno a una scheda
|
||||
rimasta aperta.
|
||||
|
||||
In full sul Mac resta il login locale esistente. Il logout backend esiste già
|
||||
(`backend/src/auth/routes.ts:355`): il lavoro riguarda il collegamento all'header
|
||||
e la pulizia della UI. Per installazioni full con OIDC va consentito anche quel
|
||||
logout; oggi `AuthGate` lo espone soltanto per `mode === "local"`. La revoca della
|
||||
sessione ThothII non va descritta come logout globale dal fornitore d'identità.
|
||||
|
||||
### 4. Il default embedded contraddice l'adapter obbligatorio
|
||||
|
||||
Il piano dichiara compatibilità con descrittori senza `shell`, ma il contratto
|
||||
richiede `adapter` in embedded. Inoltre, pretendere un nuovo bridge renderebbe
|
||||
inutilizzabile la vecchia pagina Omics finché non fosse aggiornata.
|
||||
|
||||
Raccomandazione: risolvere i valori in un unico punto di configurazione:
|
||||
|
||||
- assenza di `shell`: embedded con adapter Omics predefinito;
|
||||
- embedded senza `adapter`: `omics-portal`;
|
||||
- full: nessun adapter istanziato;
|
||||
- nome adapter sconosciuto: errore esplicito di configurazione.
|
||||
|
||||
L'adapter che legge lo stato già esistente rende questa compatibilità concreta.
|
||||
Sul Mac rimangono espliciti `mode: full` e `defaultLocale: en`. La proiezione
|
||||
pubblica può usare il `config.js` già presente; non serve un nuovo servizio di
|
||||
configurazione. Va verificato anche il prefisso API `/datamart-builder/api` nel
|
||||
montaggio Omics: il default frontend `/api` non basta a dimostrare che il deploy
|
||||
funzioni. Prima si aggiorna il lettore del descrittore, poi il file installato,
|
||||
poiché il lettore corrente rifiuta chiavi sconosciute.
|
||||
|
||||
### 5. Fullscreen e dark mode hanno già elementi riutilizzabili
|
||||
|
||||
ThothII possiede già token scuri in `frontend/src/index.css:67`, attivati anche da
|
||||
`data-bs-theme="dark"`. Il lavoro è completarne la copertura e verificare contrasto,
|
||||
form, menu e finestre, riutilizzando questi token.
|
||||
|
||||
Omics cambia la classe `fullscreen-enable` al click (`static/js/app.js:702`)
|
||||
prima di conoscere il risultato. Il ramo di uscita usa metodi storici e non
|
||||
contiene `document.exitFullscreen()`. Non va copiato nella shell full: l'icona
|
||||
deve seguire lo stato effettivo, compresi Esc e richieste rifiutate. La correzione
|
||||
equivalente dell'header Omics appartiene al suo modulo UI, non a un secondo
|
||||
controllo fullscreen dentro ThothII embedded.
|
||||
|
||||
La fascia vuota sinistra si realizza con una misura CSS condivisa, almeno 20 px,
|
||||
bilanciata con lo spazio destro. Non richiede un modulo di navigazione vuoto.
|
||||
Poiché il documento è condiviso, verificare anche che stili globali ThothII e
|
||||
contenuti sovrapposti non alterino header e sidebar del portale: il template Omics
|
||||
contiene già correzioni per reset CSS e altezza `100vh`.
|
||||
|
||||
## Elementi da conservare
|
||||
|
||||
La lingua dell'interfaccia, quella delle domande al revisore e quella dei contenuti
|
||||
del workspace hanno proprietari e durate diverse. Conservare la separazione di
|
||||
ADR 0022: semplificarla in un'unica preferenza globale introdurrebbe errori in
|
||||
ripresa e nei workspace italiani.
|
||||
|
||||
Precisare tre regole d'implementazione:
|
||||
|
||||
- una nuova sessione salva il locale UI effettivamente risolto, dopo il fallback
|
||||
delle traduzioni;
|
||||
- una sessione esistente conserva la propria lingua anche se un altro revisore
|
||||
usa un'interfaccia diversa;
|
||||
- per manifest precedenti senza campo lingua, usare la lingua del workspace come
|
||||
criterio di compatibilità e fissarla alla prima ripresa con un aggiornamento
|
||||
idempotente. Non dedurla dalla lingua del browser del nuovo revisore. La lingua
|
||||
storica esatta non è ricostruibile se il workspace è stato cambiato nel frattempo.
|
||||
|
||||
L'i18n resta il lavoro trasversale principale: include pagine amministrative,
|
||||
errori, accessibilità e testi deterministici dei widget, anche quelli costruiti
|
||||
fuori da React. Aggiungere soltanto i cataloghi dell'header non soddisfa la richiesta.
|
||||
Il modello deve ricevere la lingua dal manifest autorevole, senza tradurre a
|
||||
posteriori payload delle decisioni, SQL o contenuti del workspace.
|
||||
|
||||
## Struttura raccomandata
|
||||
|
||||
Un solo controller di shell alimenta l'interfaccia. In full gestisce preferenze
|
||||
locali e header; in embedded riceve `{ locale, theme, fullscreen }` da un
|
||||
`PortalAdapter.subscribe(...)`. I componenti applicativi usano quello stato e
|
||||
non conoscono Omics. Nessun registro dinamico di plugin, protocollo di comandi o
|
||||
controller separato per ciascun pulsante.
|
||||
|
||||
L'autenticazione continua a usare il modulo esistente, con presentazione dell'accesso
|
||||
coerente con la shell. L'integrazione con un futuro portale richiede anche che il
|
||||
suo lato server soddisfi il contratto di identità verificata: sostituire una classe
|
||||
JavaScript non può da solo sostituire l'autenticazione server. Documentare insieme
|
||||
l'adapter UI e la configurazione server Omics, senza introdurre nuove dipendenze
|
||||
Omics nel workflow o nelle pagine ThothII.
|
||||
|
||||
## Verifiche necessarie prima della consegna
|
||||
|
||||
Verificare full sul Mac con default inglese, accesso/logout, tema e fullscreen;
|
||||
embedded sul template Omics, con preferenze già impostate prima del montaggio,
|
||||
cambio tema e lingua, Esc, assenza di header ThothII e descrittore precedente.
|
||||
Verificare nuova sessione, ripresa, manifest precedente, ricaricamento durante
|
||||
la revisione e perdita dell'accesso con collegamento eventi attivo.
|
||||
|
||||
Sono verifiche del comportamento, non motivi per costruire un'infrastruttura
|
||||
generica. Questa revisione si basa sull'ispezione del sorgente; non sono stati
|
||||
eseguiti test runtime né modificati i due applicativi.
|
||||
Reference in New Issue
Block a user