Files
nis2-agile/docs/MIGRATION_UI_V2.md
DevEnv nis2-agileandClaude Opus 4.8 b80bf2361c [BACKUP] Sessione 2026-06-14: supervisore autonomo + contesto + mig.039 + UI V2 plan
- Supervisore autonomo ticket: prompt operativo + dry-run (scripts/), DRAFT rimosso; gate normativo gia' committato
- docs/CONTEXT_LAST_SESSION.md: sessione 2026-06-14 (supervisore LIVE, run#1/#2, rotazione Anthropic rinviata)
- docs/sql/039_integrity_keys.sql: migrazione integrita' DB (PK/UNIQUE/FK) gia' applicata in prod 12/6
- docs/MIGRATION_UI_V2.md: piano migrazione UI V2
- docs/nis2/incidente_r00/: 2 mockup incidente (gateway+dashboard)
- .gitignore: versiona public/vendor/ (asset Bootstrap Italia self-hosted)
- Fix accumulati: EmailService (kill-switch email), Incident/Onboarding/Organization/Services controllers, questionnaire, ReportService, CLAUDE.md standard

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 16:35:41 +02:00

200 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NIS2 Agile — Piano Realizzativo Migrazione UI V2 (Dark Mode · Inter · Standard SaaS AGI)
> **Data**: 2026-06-10 | **Autore**: Claude (sessione UI V2, analisi frontend completa)
> **Fonte standard**: `lg231-agile/docs/MIGRATION_UI_V2.md` (231 Agile, sessione 18, 10 agenti) — stesso design system già adottato da TRPG, ALLTAX, AgileHub.
> **Principio cardine**: **zero modifiche backend** — solo CSS, layout HTML, font, colori nei widget JS. Nessuna modifica a controller PHP, route, schema DB, logica `api.js`.
> **Obiettivo**: V2 **certificabile**, completa e **migliore** della V1 in ogni funzionalità (lettura, scrittura, stampe/report, accessibilità).
---
## 0. Perché V2 e perché ora
La V2 non è un restyling cosmetico: è un **cambio di design system** allineato allo standard AGI cross-suite (dark mode + glassmorphism + Inter + token semantici) già implementato da **231 Agile, TRPG, ALLTAX, AgileHub**. Allinearsi adesso significa:
- **Coerenza di suite**: un consulente che usa NIS2 + 231 + ALLTAX vede la stessa lingua visiva.
- **Certificabilità**: design system a token documentato, contrasto WCAG AA verificato, nessun colore hardcoded fuori controllo.
- **Leggibilità**: Inter sostituisce il system font; dark mode riduce l'affaticamento per operatori compliance/CISO che restano in app per ore.
- **Scalabilità**: nuovi moduli (Gap ACN, supplier portal, ecc.) nascono già V2.
---
## 1. Stato attuale (V1) — fotografia tecnica
| Aspetto | Valore V1 |
|---|---|
| Architettura frontend | **Multi-page** (36 file `.html` standalone, non SPA) |
| CSS condiviso | `public/css/style.css` (~2399 righe, **light mode**) |
| Sidebar/Topbar | **JS-injected** da `public/js/common.js` → `loadSidebar()` (centralizzato; le pagine hanno solo `<aside class="sidebar" id="sidebar"></aside>`) |
| Pagine app (con sidebar) | ~20 (dashboard, assessment, risks, incidents, policies, supply-chain, training, assets, reports, settings, acn-gap, normative, whistleblowing, kb, companies, cross-analysis, integrations, service-continuity, supplier-assessment, workflow…) |
| Pagine standalone (no sidebar) | `index.html` (landing), `login.html`, `register.html`, `onboarding.html`, `forgot-password.html`, `reset-password.html`, `index-en.html`, `presentation.html` |
| `<style>` per-pagina | quasi ogni pagina app ha 1 blocco `<style>` inline con CSS specifico |
| Inline `style=` attr | abbondanti: settings 101, supply-chain 74, whistleblowing 52, risks 51, assessment 50, reports 41, companies 40, normative 31, incidents 30 |
| JS con colori hardcoded | `bug-reporter.js` (80), `ai-assistant.js` (30), `common.js` (30), `help.js` (11), `kb.js` (6), `feedback.js` (5), `auth-gate.js` (4) |
| Chart.js | solo `supply-chain.html` |
| Font | system font (`-apple-system, Segoe UI, Roboto…`), **nessun Google Font** |
| Mobile | `mobile-conversion.css` (189 righe) + `mobile-conversion.js` |
| Versione | `1.13.0` (`public/version.json`) |
### Palette V1 (`:root`)
- `--primary: #1a73e8` (Google blue), `--primary-light: #4a9af5`, `--primary-dark: #1557b0`
- `--secondary: #34a853` (verde), `--warning: #fbbc04`, `--danger: #ea4335`, `--info: #4285f4`
- Neutrals `--gray-50…900`, `--content-bg: #f1f5f9`, `--card-bg: #ffffff`
- Sidebar **già dark**: `--sidebar-bg: #1e293b`
---
## 2. Delta Design System V1 → V2
### 2.1 Colori — mapping completo
| Token | V1 (light) | V2 (dark) | Note |
|---|---|---|---|
| `--bg` / `--content-bg` | `#f1f5f9` | `#0F172A` | Sfondo principale |
| `--surface` / `--card-bg` | `#FFFFFF` | `#1E293B` | Card, modal, sidebar |
| `--card` | `#FFFFFF` | `rgba(30,41,59,0.85)` | Glassmorphism |
| `--border` | `#e2e8f0` | `rgba(255,255,255,0.08)` | Bordi standard |
| `--border-subtle` | — | `rgba(255,255,255,0.04)` | Bordi sottili |
| `--text` | `#1e293b` | `#F8FAFC` | Testo primario |
| `--light` (text-secondary) | `#475569` | `#CBD5E1` | Testo secondario |
| `--muted` | `#64748b` | `#94A3B8` | Hint/disabled |
| `--primary` (brand) | `#1a73e8` | **vedi §2.2 decisione brand** | Identità NIS2 |
| `--blue` (interattivo) | `#1a73e8` | `#3B82F6` | Link, focus, btn |
| `--secondary`/`--success` | `#34a853` | `#10B981` | Verde |
| `--warning` | `#fbbc04` | `#F59E0B` | Amber |
| `--danger` | `#ea4335` | `#EF4444` | Rosso |
| `--info` | `#4285f4` | `#3B82F6` | Info/link |
| `--accent` | — | `#6366F1` | Indigo secondario |
| `--purple` | — | `#8B5CF6` | Accent terziario |
| `--sidebar-bg` | `#1e293b` | `#0B1929` | Più profondo (coerente suite) |
| `--code-bg` | — | `#0D1117` | Nuovo |
### 2.2 DECISIONE BRAND — ✅ CONFERMATA (2026-06-10)
**Accent/brand interattivo V2 = Suite blue `#3B82F6`** (hover `#2563EB`, focus ring `rgba(59,130,246,.2)`). Scelta per massima uniformità con 231/TRPG/ALLTAX/AgileHub. Il resto della palette (bg/surface/semantic) è identico alla suite.
### 2.3 Tipografia
| Aspetto | V1 | V2 |
|---|---|---|
| Font UI | system stack | `'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif` |
| Monospace | SF Mono/Fira | `'JetBrains Mono', monospace` |
| Base size | 16px html | 15px body |
| Weights | 400/600/700/800 | 400/500/600/700/800/900 |
| Google Fonts | nessuno | `Inter:wght@400..900 + JetBrains Mono:wght@400;500;600` |
### 2.4 Componenti — delta visivo
Identico al delta lg231 (card glassmorphism radius 12 + blur 8, btn solido no-gradient radius 8, badge semitrasparenti radius 20, table header uppercase 11px letter-spacing, input dark `rgba(255,255,255,.05)`, label uppercase 11px muted, modal overlay `rgba(0,0,0,.7)` + blur, alert border 1px + bg rgba). Vedi `lg231-agile/docs/MIGRATION_UI_V2.md` §5 per il CSS definitivo da riusare 1:1.
---
## 3. File coinvolti
### Da modificare (zero backend)
```
public/css/style.css ← RESET :root + design system V2 completo (CUORE)
public/mobile-conversion.css ← allineamento token dark
public/js/common.js ← sidebar/topbar injected + 30 colori hardcoded → token
public/js/bug-reporter.js ← 80 colori hardcoded → token/dark (widget FAB)
public/js/ai-assistant.js ← 30 colori → dark (widget chat ARIA)
public/js/help.js ← 11 colori → token (help contestuale)
public/js/feedback.js, kb.js, auth-gate.js ← colori residui
public/*.html (app, ~20) ← <style> per-pagina + inline style= → token V2
public/login.html register.html onboarding.html ← redesign dark standalone
public/index.html index-en.html ← landing (palette/font V2, non full dark — vedi §6)
public/forgot-password.html reset-password.html presentation.html
public/version.json ← bump MINOR → 1.14.0 (a fine, NON manuale durante apply)
```
### NON toccare
`application/**` (PHP), `public/index.php`, `public/js/api.js`, `public/js/i18n.js` (solo stringhe colore se presenti), `docs/sql/**`, `docker/**`, `.env`.
---
## 4. Partizione 10 Agenti + 10 QA (esecuzione background)
Ogni **agente realizzatore** è accoppiato a un **agente QA di controllo qualità** che, a valle, verifica: (a) nessun colore V1 hardcoded residuo nel suo ambito, (b) contrasto WCAG AA su dark, (c) nessuna regressione funzionale (markup/classi intatti, JS non rotto), (d) coerenza con i token V2. Il QA produce un verdetto `PASS/FAIL + findings`; un FAIL rimanda l'item all'agente realizzatore.
> **Concorrenza & isolamento**: gli agenti che scrivono `style.css` lavorano su **sezioni disgiunte** dello stesso file → per evitare conflitti di scrittura concorrente, la **FASE 1 (style.css) è sequenziale per file** ma parallela per QA; le fasi su file distinti (HTML pagine, JS widget) sono pienamente parallele. In alternativa worktree isolati + merge.
| # | Agente realizzatore | File/ambito | QA verifica |
|---|---|---|---|
| 1 | **CSS Base** | `style.css` :root tokens V2 + Inter import + body/reset + utility classes (`.mono`, `.text-success/-warning/-danger/-primary/-info/-muted`) | token completi, font caricato, no var orfane |
| 2 | **Sidebar + Topbar** | `style.css` sezione sidebar/topbar + `common.js loadSidebar()` colori | active state visibile, glassmorphism topbar, brand color |
| 3 | **Main + Layout** | `style.css` main-content, view, section-header, grid responsive | contrasto, responsive (fix grid hardcoded), densità |
| 4 | **Card + KPI** | `style.css` card glassmorphism, kpi-card/value/icon/trend | radius 12, blur, leggibilità valori |
| 5 | **Tabelle + Badge** | `style.css` table header/body/hover, status-badge tutte le varianti | badge semitrasparenti, contrasto righe |
| 6 | **Form + Button** | `style.css` form-control, label, focus ring, btn-primary/secondary, upload-area | focus ring accent, select option bg, input visibili |
| 7 | **Modal + Alert + Progress** | `style.css` modal overlay/box/header/footer, alert, progress-bar, score-ring | overlay scuro+blur, modal leggibile |
| 8 | **Componenti speciali** | `style.css` risk matrix 5×5, heatmap, workflow nodes, timeline, accordion guida, **Chart.js in supply-chain.html** (grid/tick color dark) | chart visibili su dark, matrice leggibile |
| 9 | **Pagine standalone** | `login.html`, `register.html`, `onboarding.html`, `forgot/reset-password.html` (CSS inline → dark V2) | login funzionante dark, step indicator V2 |
| 10 | **Pagine app + widget JS + landing** | `<style>`/inline di ~20 pagine app → token; `bug-reporter.js`/`ai-assistant.js`/`help.js`/`feedback.js`/`kb.js` colori → dark; `index.html`/`index-en.html` landing palette V2 | no inline V1 residuo, widget dark, landing coerente |
> L'Agente 10 è il più pesante (20 pagine + 5 widget): in esecuzione reale va **splittato in sub-task** (pagine app per gruppi + widget separati) mantenendo 1 QA per gruppo, restando entro il cap di 10 coppie attive.
---
## 5. Pattern di sostituzione inline (HTML + JS)
| Pattern V1 | Sostituzione V2 |
|---|---|
| `#1a73e8` / `#4285f4` | `var(--blue)` o brand accent |
| `color:#34a853` | `var(--success)` (`#10B981`) |
| `color:#ea4335` | `var(--danger)` (`#EF4444`) |
| `color:#fbbc04` | `var(--warning)` (`#F59E0B`) |
| `background:#fff` / `#ffffff` | `var(--surface)` |
| `background:#f1f5f9` / `#f8fafc` | `var(--bg)` o `rgba(255,255,255,.03)` |
| `border:1px solid #e2e8f0` | `border:1px solid var(--border)` |
| bg pastello chiaro (`#e6f4ea`, `#fce8e6`, `#fef7e0`, `#e8f0fe`) | `rgba(<sem>,.1)` semitrasparente |
| `color:#1e293b` / `#0f172a` (testo) | `var(--text)` |
| `color:#475569` / `#64748b` | `var(--light)` / `var(--muted)` |
---
## 6. Note critiche (da lg231, valide per NIS2)
1. **Chart.js dark** (supply-chain.html): impostare esplicitamente `scales.*.ticks.color:'#94A3B8'` e `grid.color:'rgba(255,255,255,.08)'`, altrimenti assi invisibili su dark.
2. **Landing pubblica** (`index.html`): può restare con accent brand distinto (cyan NIS2) e **non** full-dark se si preferisce marketing chiaro — decisione §2.2. Coerenza font/btn comunque V2.
3. **Backdrop-filter**: fallback `--surface` solido per Firefox<103/Safari<15.4 (già nella variabile).
4. **Stampe/Report** (`reports.html`, `ReportService` HTML esecutivo): le **print styles** restano **light** (carta bianca) — la V2 dark NON deve rompere `@media print`. QA Agente 8/10 verifica che il report stampato resti leggibile su carta.
5. **`--text-secondary` → `--muted`**: mantenere alias backward-compat in `:root` per il JS che genera HTML inline (evita regressioni).
6. **Hot-reload**: CSS/HTML live via bind-mount; per i `.php` (nessuno qui) servirebbe `kill -USR2 1`. Per CSS/HTML basta hard-refresh (cache-bust `?v=1.14.0` sui `<link>` consigliato).
---
## 7. Strategia di rilascio — IN-PLACE vs PARALLELA (da confermare)
- **In-place** (come lg231): si riscrive `style.css` live. Impatto immediato su produzione per tutti gli utenti. Rollback = `git revert`.
- **Parallela** (più certificabile): si costruisce `css/style-v2.css` + si verifica su un sottoinsieme/branch, poi si commuta il `<link>` di tutte le pagine. Permette QA completa prima del go-live.
> Trattandosi di **produzione live** (`nis2.agile.software`, bind-mount istantaneo, 36 pagine), si **consiglia la parallela** con commit su branch dedicato + verifica, poi switch.
**✅ DECISIONE CONFERMATA (2026-06-10): PARALLELA.** La V2 è costruita in un **git worktree isolato** fuori dal path servito: `/tmp/nis2-ui-v2` su branch `ui-v2`. La produzione (`/projects/nis2-agile` == bind-mount `/var/www/nis2-agile`, ramo `main`) resta **intatta** finché l'utente non approva il merge/go-live. Backup V1: `/tmp/nis2-ui-v2/.backups/ui_v2_20260610/style.css.v1`.
---
## 8. Checklist verifica post-migrazione (certificazione)
- [ ] Tutte le ~20 view app rese senza errori JS, leggibili dark
- [ ] Login/Register/Onboarding funzionanti dark
- [ ] Chart supply-chain visibile su dark
- [ ] Tabelle/badge contrasto ≥ 4.5:1 (WCAG AA)
- [ ] Form input visibili, focus ring accent
- [ ] Modal overlay/header/footer dark ok (tutti i modal)
- [ ] Sidebar JS-injected: active/hover/brand corretti
- [ ] Mobile drawer + `mobile-conversion.css` coerenti
- [ ] Google Font Inter caricato (no fallback)
- [ ] Widget FAB (bug-reporter), chat ARIA (ai-assistant), help contestuale: dark coerente
- [ ] **Stampe/report**: `@media print` resta leggibile su carta bianca
- [ ] Nessun colore V1 hardcoded residuo (`#1a73e8`, `#34a853`, `#ea4335`, `#fbbc04`, `#fff` in stili critici)
- [ ] `version.json` → `1.14.0`
- [ ] i18n IT/EN intatto, help.js intatto
---
## 9. Governance (CLAUDE.md)
- Modifica file = **conferma utente** (questo doc è la proposta). Live via bind-mount.
- Commit immediato post-smoke + push via host se cache token vuota.
- Backup pre-migrazione: `public/css/style.css` → `.backups/ui_v2_<ts>/`.
- A fine sessione aggiornare `docs/CONTEXT_LAST_SESSION.md` e `CLAUDE.md` se cambia architettura UI.
```