[FORMAZIONE] Avatar di prodotto — mappa-logica COMPLETA (22 viste) + SELETTORI_DEMO + tassonomia corso + fix kb.js

Deliverable formazione-first (DESIGN_AVATAR_FORMAZIONE / product-demo-complete):
- docs/mappa-logica/01..22_*.md: tutte le viste app V2 mappate (formato canonico standard §2),
  selettori VERIFICATI sul DOM reale, endpoint verificati su api.js/script, gate ruolo dai controller
- docs/mappa-logica/SELETTORI_DEMO.md: registry canonico (22 viste, 131 visualizzazione + 89 azioni)
  + worklist consolidata 132 id stabili da aggiungere (modifiche chirurgiche future)
- docs/formazione/TASSONOMIA_CORSO_NIS2.{md,json}: 10 moduli / 28 lezioni / ~7h45, prerequisiti+durate,
  esame con soglia 80%, sandbox 'prova tu' org 996002
- fix kb.js: ingest scope=ORG ora invia organization_id (prima 422 KB_ORG_REQUIRED) — bug trovato da A2

Prodotto con 4 trittici di agenti (A1 esecutore -> A2 revisore -> A3 controllore avversariale):
A2: ~14 correzioni (cross-ref, gate ruolo, comportamenti); A3 PASS: 38 selettori campionati 0 rotti,
18 endpoint reali, 0 violazioni normative (Allegati 3/4, IS-4, '1 mese', PII.* interna), 9 claim verificati.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-06-12 18:50:19 +02:00
co-authored by Claude Opus 4.8
parent e1ab0b3ea0
commit 4dfab2a391
27 changed files with 2041 additions and 5 deletions
+58
View File
@@ -0,0 +1,58 @@
# MAPPA-LOGICA · AI Cross-Analysis
⟦ INIZIO · U-XA · Videata "AI Cross-Analysis" ⟧
File: public/cross-analysis.html · URL: /cross-analysis.html · Scopo: analisi AI conversazionale sui dati aggregati e anonimizzati del portfolio clienti di un consulente (gap comuni, rischio medio, categorie NIS2 deboli, benchmark), con storico delle analisi e vista dati portfolio · Profili: SOLO consultant e super_admin — il backend risponde error_code INSUFFICIENT_ROLE agli altri ruoli e la pagina mostra "Funzione riservata a Consulenti e Super Admin".
• U-XA.1 — Header pagina + badge privacy/ruolo
Mostra: titolo "AI Cross-Analysis" con badge verde "Dati aggregati — privacy garantita" e badge viola "Solo Consulenti & Admin".
Azioni: nessuna (informativo).
Dati da: statico (HTML).
Confine: `header.content-header` (riga 280) — nessun id sugli elementi badge.
• U-XA.2 — Header portfolio (banner viola)
Mostra: "Il tuo portfolio — N organizzazioni monitorate" + 4 statistiche: Compliance medio (%), Rischi aperti, Formazione media (%), Organizzazioni. Se ruolo insufficiente: lucchetto + "Funzione riservata a Consulenti e Super Admin". Se errore: "Errore caricamento portfolio".
Azioni: nessuna (lettura, caricata al boot da `loadPortfolio()`).
Dati da: GET /api/cross-analysis/portfolio (risposta: data.org_count, data.aggregated.{avg_compliance_score, risks.total_open, training.avg_completion_rate, by_sector, score_distribution, assessments.avg_by_category}).
Confine: `#portfolio-header` (riga 298).
• U-XA.3 — Barra tab (Chat AI / Storico / Portfolio dati)
Mostra: 3 tab con icone: "Chat AI", "Storico", "Portfolio dati"; tab attiva sottolineata viola.
Azioni: click tab → `switchTab()` mostra il pannello corrispondente; la tab Storico carica lazy lo storico (U-XA.6).
Dati da: nessuno (navigazione client-side).
Confine: `.tab-bar[role="tablist"]` (riga 307); bottoni `.tab-btn` senza id ma con `aria-controls="tab-chat|tab-history|tab-portfolio"` (righe 308-315).
• U-XA.4 — Tab Chat AI: domande rapide + input
Mostra: empty state iniziale "Analisi AI del tuo portfolio clienti — Fai una domanda sui dati aggregati delle tue organizzazioni"; 6 chip di domande rapide: "Gap più frequenti", "Livello di rischio medio", "Categorie NIS2 deboli", "Intervento urgente", "Stato formazione", "Benchmark NIS2" (ognuna pre-compila una domanda in italiano); textarea domanda con invio via Enter (Shift+Enter per newline); bottone invio; nota privacy: "Dati anonimizzati e aggregati — nessun nome organizzazione inviato all'AI".
Azioni: chip → `setQuestion()` pre-compila l'input; invio → `sendMessage()` aggiunge la bolla utente, mostra l'indicatore "thinking" animato, poi POST all'AI.
Dati da: POST /api/cross-analysis/analyze (body: {question}; risposta: data.result + data.org_count).
Confine: `#tab-chat` (riga 320); `#chat-messages` (322), `#chat-empty` (323), `#quick-qs` (330), `#chat-input` (340), `#btn-send` (342).
• U-XA.5 — Risposta AI strutturata (bolla chat)
Mostra: risposta testuale (answer); sezioni opzionali: "Risultati chiave" (key_findings, elenco), "Raccomandazioni" (recommendations, elenco), "Aree di attenzione" (risk_areas, elenco), box viola benchmark (benchmark_note), box ambra nota privacy (privacy_note); footer "Basato su N organizzazioni anonimizzate" + orario. In caso di errore: bolla rossa con il messaggio.
Azioni: nessuna (output).
Dati da: risposta di POST /api/cross-analysis/analyze (result.{answer, key_findings[], recommendations[], risk_areas[], benchmark_note, privacy_note}).
Confine: bolle generate via JS dentro `#chat-messages`; indicatore thinking con id dinamico `#think-<timestamp>`.
• U-XA.6 — Tab Storico
Mostra: lista delle ultime 20 analisi: data/ora (it-IT), domanda (prompt_summary, ripulita dal prefisso "CROSS_ORG [...]"), sintesi risposta (response_summary); "Nessuna analisi precedente." se vuoto.
Azioni: caricata al click sulla tab (lazy via `loadHistory()`).
Dati da: GET /api/cross-analysis/history?limit=20 (risposta: data.history[]).
Confine: `#tab-history` (riga 355), `#history-content` (riga 356).
• U-XA.7 — Tab Portfolio dati
Mostra: card "Distribuzione Settoriale" (settore, conteggio, % con barra viola); card "Distribuzione Score Compliance" (fasce 0-20% … 81-100% colorate dal rosso al verde, conteggio org per fascia); card "Score Medio per Categoria NIS2 (dal più basso)" — fino a 5 categorie con % colorata (rosso <30, ambra <60, verde altrimenti) e mini progress bar.
Azioni: nessuna (lettura, renderizzata da `renderPortfolioTab()` con i dati già caricati al boot).
Dati da: GET /api/cross-analysis/portfolio (stessa chiamata di U-XA.2: aggregated.by_sector, aggregated.score_distribution, aggregated.assessments.avg_by_category).
Confine: `#tab-portfolio` (riga 362), `#portfolio-content` (riga 363).
⟦ FINE · U-XA ⟧
## ID STABILI MANCANTI (da aggiungere)
| Elemento | Riga | Id proposto |
|---|---|---|
| Tab "Chat AI" | 308 | `nis2-xa-tab-btn-chat` |
| Tab "Storico" | 311 | `nis2-xa-tab-btn-history` |
| Tab "Portfolio dati" | 314 | `nis2-xa-tab-btn-portfolio` |
| Badge privacy header | 284 | `nis2-xa-privacy-badge` |
| Badge "Solo Consulenti & Admin" | 289 | `nis2-xa-role-badge` |
| Chip domande rapide (6) | 331-336 | `nis2-xa-quickq-1` … `nis2-xa-quickq-6` (o `data-quickq`) |