diff --git a/docs/MANUALE_UTENTE_NIS2_AGILE.docx b/docs/MANUALE_UTENTE_NIS2_AGILE.docx index bb9bffa..e85df07 100644 Binary files a/docs/MANUALE_UTENTE_NIS2_AGILE.docx and b/docs/MANUALE_UTENTE_NIS2_AGILE.docx differ diff --git a/scripts/genera-manuale-utente.py b/scripts/genera-manuale-utente.py index 6a3cc05..1de7d03 100644 --- a/scripts/genera-manuale-utente.py +++ b/scripts/genera-manuale-utente.py @@ -1,287 +1,228 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""Genera il Manuale d'uso di NIS2 Agile in .docx usando solo stdlib (zipfile+XML).""" -import zipfile, re, datetime +"""Manuale d'uso COMPLETO di NIS2 Agile (.docx, solo stdlib). Contenuti moduli da help.js reale.""" +import zipfile, re, json, html as _html, subprocess, os from xml.sax.saxutils import escape -OUT = "/projects/nis2-agile/docs/MANUALE_UTENTE_NIS2_AGILE.docx" - -# ───────────────────────────────────────────────────────────────────────── -# CONTENUTO DEL MANUALE (DSL: lista di blocchi) -# ('title', titolo, sottotitolo, riga_meta) -# ('h1'|'h2'|'h3', testo) | ('p', testo) | ('note', testo) -# ('ul', [voci]) | ('ol', [voci]) -# ('table', [intestazioni], [[riga],...]) -# ('pb',) page break -# Nel testo: **grassetto** supportato. -# ───────────────────────────────────────────────────────────────────────── +BASE = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # repo root +OUT = os.path.join(BASE, "docs", "MANUALE_UTENTE_NIS2_AGILE.docx") +HELP_JSON = "/tmp/help.json" +# Auto-estrae i contenuti dall'help reale del prodotto (public/js/help.js) via node. +_node = ('const fs=require("fs");let s=fs.readFileSync(process.argv[1],"utf8");' + 'const a=s.indexOf("var _helpContent");const start=s.indexOf("{",a);' + 'const end=s.indexOf("var _pageMap");let obj=s.slice(start,s.lastIndexOf("}",end)+1);' + 'fs.writeFileSync(process.argv[2],JSON.stringify(eval("("+obj+")")));') +subprocess.run(["node","-e",_node, os.path.join(BASE,"public","js","help.js"), HELP_JSON], check=True) +HELP = json.load(open(HELP_JSON, encoding="utf-8")) DATE = "11 giugno 2026" + C = [] def add(*b): C.append(b) -add('title', "NIS2 Agile", "Manuale d'uso del prodotto", - "Versione piattaforma 1.14.0 · Aggiornato all'%s" % DATE) +def html2mk(s): + """Converte l'HTML dell'help nel markup interno (**bold**) + testo pulito.""" + s = re.sub(r'|', '**', s) + s = re.sub(r'<[^>]+>', '', s) # rimuovi altri tag (span/em/...) + s = _html.unescape(s) # < ≥   ... + s = s.replace(' ', ' ') + s = re.sub(r'\s+', ' ', s).strip() + # bilancia eventuali ** dispari + if s.count('**') % 2: s += '**' + return s -# ===== INDICE (statico, i numeri di pagina non sono calcolati) ===== -add('h1', "Indice dei contenuti") -for n in ["1. Introduzione","2. Primi passi (accesso, registrazione, onboarding)", - "3. Dashboard","4. Gap Analysis NIS2 (Art. 21)","5. Gap Analysis ACN (Determinazione 164179/2025)", - "6. Modello Organizzativo SGSI (ISO 27001/27017/27018)","7. Gestione dei Rischi", - "8. Gestione degli Incidenti (Art. 23)","9. Policy e procedure","10. Supply Chain (fornitori)", - "11. Formazione","12. Asset","13. Audit & Report","14. Whistleblowing (Art. 32)", - "15. Aggiornamenti normativi","16. Knowledge Base e Assistente AI","17. Segnalazioni (feedback)", - "18. Impostazioni","19. Amministrazione","20. Integrazioni e API","21. Glossario","22. Riferimenti normativi"]: - add('p', n) +def module_chapter(num, title, topic_key, lead=None): + t = HELP.get(topic_key, {}) + add('h1', f"{num}. {title}") + if lead: add('p', lead) + if t.get('intro'): add('p', html2mk(t['intro'])) + for sec in t.get('sections', []): + add('h3', html2mk(sec.get('heading',''))) + items = [html2mk(x) for x in sec.get('items', [])] + if items: add('ul', items) + refs = [html2mk(x) for x in t.get('references', [])] + if refs: + add('h3', "Riferimenti normativi") + add('ul', refs) + +# ══════════════════ COPERTINA ══════════════════ +add('title', "NIS2 Agile", "Manuale d'uso del prodotto", + f"Guida operativa completa · Versione piattaforma 1.14.0 · {DATE}") +add('p', "Questo manuale spiega passo dopo passo come accedere alla piattaforma, registrarsi, completare l'onboarding aziendale e utilizzare ogni modulo. Per ogni schermata trovi cosa contiene, a cosa serve e come operare.") add('pb') -# ===== 1. INTRODUZIONE ===== +# ══════════════════ INDICE ══════════════════ +add('h1', "Indice") +toc = ["1. Introduzione","2. Requisiti e accesso alla piattaforma","3. Registrazione di un nuovo utente", + "4. Onboarding: configurazione dell'azienda","5. Come muoversi nell'interfaccia","6. Dashboard", + "7. Gap Analysis NIS2 (Art. 21)","8. Gap Analysis ACN (Determinazione 164179/2025)", + "9. Modello Organizzativo SGSI (ISO 27001/27017/27018)","10. Gestione dei Rischi", + "11. Gestione degli Incidenti (Art. 23)","12. Policy e procedure","13. Supply Chain (fornitori)", + "14. Formazione","15. Asset","16. Audit & Report","17. Whistleblowing (Art. 32)", + "18. Aggiornamenti normativi","19. Knowledge Base","20. Compliance Journey","21. Segnalazioni (feedback)", + "22. Impostazioni","23. Gestione delle aziende (consulenti)","24. Domande frequenti (FAQ)", + "25. Glossario","26. Riferimenti normativi"] +for x in toc: add('p', x) +add('note', "I nomi delle voci e l'aspetto delle schermate possono variare leggermente con gli aggiornamenti. In ogni pagina è disponibile il pulsante di aiuto contestuale (icona ?) con la guida e i riferimenti normativi.") + +# ══════════════════ 1. INTRODUZIONE ══════════════════ add('h1', "1. Introduzione") -add('h2', "1.1 Che cos'è NIS2 Agile") -add('p', "NIS2 Agile è una piattaforma SaaS multi-tenant che supporta le aziende nel percorso di conformità alla **Direttiva (UE) 2022/2555 (NIS2)** e al suo recepimento italiano (**D.Lgs. 138/2024**), comprese le **Determinazioni dell'Agenzia per la Cybersicurezza Nazionale (ACN)**. Integra l'intelligenza artificiale (Claude) per gap analysis, generazione di policy, classificazione degli incidenti e suggerimento dei rischi.") -add('p', "Dalla versione 1.14.0 la piattaforma include anche un modulo guidato per la costruzione del **Modello Organizzativo SGSI secondo ISO/IEC 27001:2022**, con estensioni cloud ISO/IEC 27017:2015 e 27018:2019.") -add('h2', "1.2 A chi è rivolto") -add('ul', ["**PMI** che devono adeguarsi agli obblighi NIS2 con risorse limitate;", - "**Grandi imprese / Enterprise** con processi di compliance strutturati;", - "**Consulenti e CISO** che gestiscono più organizzazioni clienti tramite uno studio (consulting firm)."]) -add('h2', "1.3 Quadro normativo di riferimento") -add('table', ["Fonte","Ruolo"], - [["Direttiva (UE) 2022/2555 (NIS2)","Principi e obblighi europei di cibersicurezza"], - ["D.Lgs. 138/2024","Recepimento italiano della NIS2 (obblighi operativi)"], - ["Determinazione ACN 164179/2025","Misure di sicurezza di base, classificazione e notifica incidenti (Allegati)"], - ["ISO/IEC 27001:2022","Requisiti del Sistema di Gestione della Sicurezza delle Informazioni (best practice)"], - ["ISO/IEC 27017:2015 / 27018:2019","Controlli per servizi cloud / protezione PII in cloud (best practice)"]]) -add('note', "Disclaimer: NIS2 Agile è uno strumento di supporto operativo e pre-audit. Non costituisce consulenza legale né parere professionale vincolante, e non rilascia certificazioni ISO. Le valutazioni proposte (perimetro, applicabilità, significatività) vanno confermate con il referente compliance/legale dell'organizzazione.") +add('p', "**NIS2 Agile** è una piattaforma web (SaaS) che accompagna le aziende nella conformità alla **Direttiva (UE) 2022/2555 (NIS2)**, al suo recepimento italiano (**D.Lgs. 138/2024**) e alle **Determinazioni dell'Agenzia per la Cybersicurezza Nazionale (ACN)**. Integra l'intelligenza artificiale per gap analysis, generazione di policy, classificazione degli incidenti e suggerimento dei rischi.") +add('p', "Dalla versione 1.14.0 include anche il **Modello Organizzativo SGSI** secondo **ISO/IEC 27001:2022**, con estensioni cloud ISO 27017/27018.") +add('h3', "A chi è rivolto") +add('ul', ["**PMI** che devono adeguarsi agli obblighi NIS2;", + "**Grandi imprese** con processi di compliance strutturati;", + "**Consulenti e CISO** che seguono più aziende clienti tramite uno studio."]) +add('h3', "Come è organizzato il lavoro nella piattaforma") +add('p', "Il percorso tipico è: **(1)** accedi o registrati → **(2)** completa l'onboarding dell'azienda (che ne determina la classificazione NIS2) → **(3)** esegui la Gap Analysis NIS2 → **(4)** approfondisci con la Gap Analysis ACN e costruisci il Modello SGSI → **(5)** gestisci rischi, incidenti, policy, fornitori, formazione e audit nel tempo.") +add('note', "Disclaimer: NIS2 Agile è uno strumento di supporto operativo e pre-audit. Non costituisce consulenza legale né parere professionale vincolante e non rilascia certificazioni ISO. Le valutazioni proposte vanno confermate con il referente compliance/legale dell'organizzazione.") -# ===== 2. PRIMI PASSI ===== -add('pb'); add('h1', "2. Primi passi") -add('h2', "2.1 Accesso e indirizzo") -add('p', "La piattaforma è raggiungibile all'indirizzo **https://nis2.agile.software/**. L'accesso avviene con email e password (autenticazione JWT). Se la tua organizzazione usa il Single Sign-On centralizzato (AgileHub), le credenziali sono condivise tra i prodotti della suite.") -add('h2', "2.2 Registrazione") -add('ol', ["Apri la pagina di **Registrazione** e inserisci i dati richiesti (email, password conforme alla policy di sicurezza).", - "Al termine vieni indirizzato automaticamente alla procedura di **onboarding** aziendale.", - "Se possiedi un **invito/licenza** (token `inv_...`) fornito da un partner, inseriscilo per attivare l'organizzazione pre-configurata."]) -add('h2', "2.3 Recupero password") -add('p', "Dalla pagina di login usa **Password dimenticata** per ricevere un link di reset via email. Il cambio password effettuato da AgileHub si propaga automaticamente entro pochi minuti grazie al sync SSO.") -add('h2', "2.4 Onboarding dell'organizzazione") -add('p', "Il wizard di onboarding crea l'organizzazione e ne determina la classificazione NIS2. Si articola in quattro passi:") -add('ol', ["**Dati azienda** — inserimento manuale oppure precompilazione tramite **Partita IVA** (lookup automatico) o caricamento della **visura camerale** (estrazione AI dei dati).", - "**Verifica e completamento** — settore (ATECO → settore NIS2), numero dipendenti, fatturato, sede, contatti.", - "**Profilo utente** — nome, ruolo, telefono.", - "**Classificazione NIS2** — la piattaforma propone se il soggetto è **essenziale**, **importante** o **non applicabile** in base a settore e dimensione; è possibile aderire volontariamente."]) -add('note', "La classificazione (essenziale/importante) determina il perimetro applicabile in più moduli, in particolare la Gap Analysis ACN e gli obblighi sugli incidenti. Puoi rivederla in Impostazioni › Classificazione NIS2.") -add('h2', "2.5 Ruoli e permessi") -add('table', ["Ruolo","Descrizione"], - [["super_admin","Amministratore di piattaforma (accesso a tutte le organizzazioni)"], - ["org_admin","Amministratore dell'organizzazione"], - ["compliance_manager","Responsabile compliance: gestisce assessment, rischi, policy, SGSI"], - ["board_member","Organo direttivo: visione e approvazioni"], - ["auditor","Revisore: lettura e compilazione evidenze/controlli"], - ["employee","Dipendente: formazione, segnalazioni"], - ["consultant","Consulente di studio che opera su più organizzazioni clienti"]]) -add('h2', "2.6 Multi-organizzazione, lingua e aiuto") -add('ul', ["Chi appartiene a più organizzazioni (es. consulenti) può **cambiare contesto** dall'intestazione/menu.", - "L'interfaccia è disponibile in **Italiano** ed **Inglese** (selettore lingua).", - "Ogni pagina dispone di **Aiuto contestuale** (icona ?) con guida e riferimenti normativi certi."]) +# ══════════════════ 2. ACCESSO ══════════════════ +add('h1', "2. Requisiti e accesso alla piattaforma") +add('h3', "Requisiti") +add('ul', ["Un browser web aggiornato (Chrome, Edge, Firefox o Safari);", + "una connessione a Internet;", + "le credenziali di accesso (email e password) oppure un invito ricevuto dal proprio studio/partner."]) +add('h3', "Indirizzo della piattaforma") +add('p', "Apri il browser e vai su **https://nis2.agile.software/**. Si apre la pagina di accesso.") +add('h3', "Come accedere (login)") +add('ol', ["Nel campo **Indirizzo Email** inserisci l'email con cui sei registrato (es. nome@azienda.it).", + "Nel campo **Password** inserisci la tua password. Puoi usare l'icona a forma di occhio per mostrarla/nasconderla.", + "Premi **Accedi**.", + "Se le credenziali sono corrette: se hai già un'azienda configurata vieni portato alla **Dashboard**, altrimenti alla procedura di **Onboarding**."]) +add('p', "In caso di errore compare un messaggio in rosso sotto il titolo. Verifica email e password e riprova.") +add('h3', "Password dimenticata") +add('ol', ["Dalla pagina di accesso scegli **Password dimenticata**.", + "Inserisci l'email dell'account: riceverai un messaggio con un link per impostare una nuova password.", + "Apri il link, scegli la nuova password (rispettando i requisiti di sicurezza) e conferma."]) +add('note', "Se la tua azienda usa il Single Sign-On della suite (AgileHub), la password è condivisa tra i prodotti: un cambio password si propaga automaticamente entro pochi minuti.") +add('h3', "Disconnessione e sessioni") +add('p', "Per uscire usa la voce **Esci/Logout** nel menu utente. Dalle Impostazioni puoi vedere i **dispositivi collegati** (sessioni attive) e revocarli singolarmente o tutti.") -# ===== 3. DASHBOARD ===== -add('pb'); add('h1', "3. Dashboard") -add('p', "La Dashboard è la pagina iniziale dopo l'accesso e offre una visione d'insieme dello stato di conformità.") -add('ul', ["**Avanzamento implementazione misure Art. 21 NIS2** — indicatore complessivo (gauge);", - "**Scadenze imminenti** — adempimenti e revisioni in arrivo da più moduli;", - "**Attività recenti** — ultime azioni tracciate;", - "**Heatmap dei rischi** — distribuzione dei rischi su probabilità × impatto;", - "**Benchmark settoriale** (anonimizzato) — confronto con il proprio settore;", - "**Compliance Journey** — percorso guidato che indica i prossimi passi consigliati."]) +# ══════════════════ 3. REGISTRAZIONE ══════════════════ +add('h1', "3. Registrazione di un nuovo utente") +add('p', "Se non hai un account, dalla pagina di accesso scegli **Registrati**. La registrazione è una procedura guidata in tre passi, con un indicatore di avanzamento in alto.") +add('h3', "Passo 1 — Ruolo e (eventuale) codice invito") +add('p', "Scegli il **ruolo** con cui ti registri, selezionando una delle schede disponibili:") +add('table', ["Scheda ruolo","Quando sceglierlo"], + [["Responsabile compliance","Gestisci direttamente assessment, rischi, policy e SGSI dell'azienda"], + ["Amministratore organizzazione","Amministri l'azienda, gli utenti e le impostazioni"], + ["Consulente","Segui più aziende clienti per conto di uno studio"], + ["Auditor","Esegui verifiche e compili evidenze/controlli (lettura prevalente)"], + ["Membro del board","Organo direttivo: visione e approvazioni"]]) +add('p', "Se hai ricevuto un **Codice Invito** da un partner o dal tuo studio (formato `inv_...`), inseriscilo nell'apposito campo: il sistema lo verifica e mostra l'azienda/piano associati. Premi **Avanti** per proseguire.") +add('h3', "Passo 2 — Dati personali e password") +add('ul', ["**Nome** e **Cognome** (es. Mario Rossi);", + "**Email** (sarà il tuo identificativo di accesso);", + "eventuale **Partita IVA** dell'azienda (verificata in tempo reale, dove richiesto);", + "**Password** (minimo 8 caratteri): un indicatore mostra la robustezza della password mentre la digiti;", + "**Conferma password**: ripeti la stessa password."]) +add('h3', "Passo 3 — Conferma e avvio") +add('p', "Rivedi i dati, accetta le condizioni e completa la registrazione. Al termine vieni indirizzato automaticamente all'**Onboarding** per configurare l'azienda (se non sei entrato tramite un invito che la pre-configura).") -# ===== 4. GAP ANALYSIS NIS2 ===== -add('pb'); add('h1', "4. Gap Analysis NIS2 (Art. 21)") -add('p', "Analisi di **primo livello** sulle 10 categorie di misure dell'Art. 21.2 NIS2, basata su un questionario di 80 domande (10 categorie), ciascuna collegata anche al controllo ISO 27001 corrispondente.") -add('h2', "4.1 Come si svolge") -add('ol', ["Crea un nuovo assessment: la piattaforma pre-popola tutte le domande.", - "Per ogni domanda indica lo stato: **Attuato**, **Parziale**, **Non attuato**, **Non applicabile**. Le risposte si salvano automaticamente.", - "Completa l'assessment per ottenere un **punteggio** per categoria e complessivo.", - "Avvia l'**analisi AI** per ricevere sintesi esecutiva, priorità, quick win e una roadmap di conformità."]) -add('note', "Le risposte della Gap Analysis NIS2 alimentano automaticamente il Modello SGSI (capitolo 6): il loro stato pre-popola lo Statement of Applicability ISO 27001.") +# ══════════════════ 4. ONBOARDING ══════════════════ +add('h1', "4. Onboarding: configurazione dell'azienda") +add('p', "L'onboarding crea l'organizzazione e ne stabilisce la **classificazione NIS2** (essenziale, importante o non applicabile), che determina gli obblighi e il perimetro applicabile negli altri moduli. È una procedura guidata con uno **stepper** in alto che mostra i passi.") +add('h3', "Passo 1 — Inserisci la Partita IVA") +add('p', "Nella prima schermata (\"Inserisci la Partita IVA dell'azienda\") digiti la **Partita IVA** (es. 12345678901) e premi il pulsante di ricerca: la piattaforma tenta di **recuperare automaticamente** i dati aziendali. In alternativa puoi caricare la **visura camerale** (i dati vengono estratti dall'AI) oppure proseguire e inserire tutto manualmente. Premi **Continua**.") +add('h3', "Passo 2 — Verifica e completa i dati aziendali") +add('p', "Nella schermata \"Verifica e Completa i Dati Aziendali\" un banner indica la fonte dei dati (visura, lookup P.IVA o inserimento manuale). Controlla e completa i campi:") +add('ul', ["**Ragione sociale** (es. Acme S.r.l.);", + "**Partita IVA** e **Codice Fiscale**;", + "**Indirizzo**, **Città**, **Sito web**;", + "**Email aziendale** e **Telefono aziendale**;", + "**Settore** — scegli dall'elenco il settore NIS2 (es. Energia, Trasporti, Sanità, Infrastrutture digitali, ecc.): è determinante per la classificazione;", + "**Numero di dipendenti** e **fatturato** annuo, usati per stabilire la dimensione dell'impresa."]) +add('h3', "Passo 3 — Il tuo profilo") +add('p', "Inserisci i dati del tuo profilo utente: **nome completo**, **ruolo** in azienda e **telefono** di contatto.") +add('h3', "Passo 4 — Classificazione NIS2") +add('p', "In base a settore e dimensione, la piattaforma **propone la classificazione**: soggetto **essenziale**, **importante** oppure **non applicabile**. Se non rientri obbligatoriamente ma vuoi adeguarti, puoi indicare l'**adesione volontaria**. Conferma per completare l'onboarding e accedere alla Dashboard.") +add('note', "Puoi rivedere o aggiornare la classificazione in qualsiasi momento da Impostazioni › Classificazione NIS2. La classificazione filtra automaticamente, ad esempio, i requisiti applicabili nella Gap Analysis ACN e gli obblighi sugli incidenti.") -# ===== 5. GAP ANALYSIS ACN ===== -add('pb'); add('h1', "5. Gap Analysis ACN (Determinazione 164179/2025)") -add('p', "Analisi di **secondo livello** sulle misure e i requisiti puntuali stabiliti dall'ACN, articolati secondo il **Framework Nazionale** (funzioni Governo GV, Identificazione ID, Protezione PR, Rilevamento DE, Risposta RS, Ripristino RC).") -add('table', ["Classificazione","Perimetro applicabile"], - [["Soggetto IMPORTANTE (Allegato 1)","37 misure / 87 requisiti"], - ["Soggetto ESSENZIALE (Allegato 2)","43 misure / 116 requisiti"]]) -add('ul', ["Il perimetro è filtrato automaticamente in base alla classificazione NIS2 dell'organizzazione;", - "scoring per funzione del Framework Nazionale e punteggio complessivo;", - "**piano d'azione** dei requisiti non conformi e **analisi AI** ancorata ai 203 requisiti ACN reali (nessun riferimento inventato);", - "**Catalogo requisiti** consultabile in sola lettura."]) +# ══════════════════ 5. NAVIGAZIONE ══════════════════ +add('h1', "5. Come muoversi nell'interfaccia") +add('p', "Dopo l'accesso l'interfaccia è composta da una **barra laterale** (sidebar) a sinistra con il menu, e dall'**area principale** a destra che mostra la pagina selezionata. In alto a destra di ogni pagina trovi il pulsante di **aiuto contestuale (?)** e le azioni della pagina.") +add('h3', "Le sezioni del menu") +add('table', ["Sezione","Voci"], + [["Principale","Dashboard, Compliance Journey, Gap Analysis (NIS2), Gap Analysis ACN, Modello SGSI (ISO 27001)"], + ["Gestione","Rischi, Incidenti, Policy, Supply Chain, Segnalazioni (whistleblowing), Normative, AI Cross-Analysis, Knowledge Base"], + ["Operativo","Formazione, Asset, Audit & Report"], + ["Sistema","Guida all'uso, Impostazioni, Architettura, Simulazione Demo, Integrazioni Esterne"]]) +add('h3', "Lingua e aiuto") +add('ul', ["L'interfaccia è disponibile in **Italiano** ed **Inglese** (selettore lingua).", + "Il pulsante **?** in ogni pagina apre la guida contestuale con spiegazioni e riferimenti normativi.", + "Chi appartiene a più aziende (consulenti) può **cambiare organizzazione** dal menu."]) -# ===== 6. MODELLO SGSI ISO 27001 (NUOVO) ===== -add('pb'); add('h1', "6. Modello Organizzativo SGSI (ISO 27001/27017/27018)") -add('p', "Procedura guidata per costruire il **Sistema di Gestione della Sicurezza delle Informazioni (SGSI / ISMS)** secondo **ISO/IEC 27001:2022** (clausole 4–10) e il relativo **Statement of Applicability (SoA)** sui 93 controlli dell'Annex A. È uno strumento di supporto e pre-audit, non una certificazione.") -add('h2', "6.1 Il wizard in 6 passi") -add('table', ["Passo","Clausola ISO 27001","Contenuto"], - [["1. Contesto e Ambito","cl. 4","Scope del SGSI, contesto interno/esterno, parti interessate, confini, esclusioni motivate, attivazione estensioni cloud"], - ["2. Leadership","cl. 5","Ruoli e responsabilità con matrice RACI (Responsible, Accountable, Consulted, Informed)"], - ["3. Risk","cl. 6","Metodologia di risk assessment e obiettivi del SGSI (il registro rischi resta nel modulo Rischi)"], - ["4. Statement of Applicability","cl. 6.1.3","Applicabilità, stato e motivazione dei 93 controlli Annex A + estensioni cloud"], - ["5. Documented Information","cl. 7–8","Policy e procedure, con bozze generabili dall'AI"], - ["6. Monitoraggio e Miglioramento","cl. 9–10","Audit interni e non conformità (moduli Audit & Report e NCR/CAPA); checklist di completamento"]]) -add('h2', "6.2 SoA pre-popolato dalla Gap Analysis NIS2") -add('p', "Ogni domanda della Gap Analysis NIS2 è collegata a un controllo ISO 27001 (es. A.5.1). Per questo lo Statement of Applicability viene **pre-compilato** a partire dalle risposte NIS2 già date: i controlli con corrispondenza riportano il badge **\"da NIS2\"** e uno stato proposto (Attuato = 100%, Parziale = 50%, Non attuato = 0%). I controlli non coperti dal NIS2 (es. parte dei controlli fisici A.7) restano da compilare manualmente.") -add('note', "Il pulsante \"Ri-deriva dal NIS2\" aggiunge soltanto i controlli mancanti e non sovrascrive le modifiche manuali già inserite.") -add('h2', "6.3 Estensioni cloud (condizionali)") -add('ul', ["**ISO/IEC 27017:2015** — attivala se usi servizi cloud pubblici o sei un fornitore cloud: aggiunge 7 controlli cloud (CLD.*) al SoA;", - "**ISO/IEC 27018:2019** — attivala se tratti dati personali (PII) in cloud pubblico come responsabile: aggiunge i controlli privacy (PII.*), sinergici con il GDPR.", - "Le sezioni cloud/PII compaiono nel SoA **solo** se attivi i relativi flag nel passo 1."]) -add('h2', "6.4 Documenti e generazione AI") -add('p', "Nel passo 5 puoi generare bozze di policy e procedure (Policy SGSI, Dichiarazione di Applicabilità, controllo accessi, gestione incidenti, continuità, sicurezza fornitori). Le bozze sono prodotte dall'AI con ancoraggio alle fonti certe e richiedono **revisione umana** prima dell'approvazione.") -add('h2', "6.5 Esportazione") -add('p', "Il pulsante **Esporta SGSI** apre una versione stampabile del modello (ambito, metodologia, SoA con stato dei controlli), utile come evidenza in vista di un audit.") +# ══════════════════ 6..23 MODULI (da help.js) ══════════════════ +module_chapter(6, "Dashboard", "dashboard") +module_chapter(7, "Gap Analysis NIS2 (Art. 21)", "assessment", + "Apri la voce **Gap Analysis** dal menu. È l'analisi di primo livello sulle 10 categorie di misure dell'Art. 21 NIS2.") +module_chapter(8, "Gap Analysis ACN (Determinazione 164179/2025)", "acn", + "Apri la voce **Gap Analysis ACN**. È l'analisi di secondo livello sui requisiti puntuali ACN.") +module_chapter(9, "Modello Organizzativo SGSI (ISO 27001/27017/27018)", "isms", + "Apri la voce **Modello SGSI (ISO 27001)**. Una procedura guidata in 6 passi costruisce il Sistema di Gestione della Sicurezza delle Informazioni; lo Statement of Applicability è pre-popolato dalle risposte della Gap Analysis NIS2.") +module_chapter(10, "Gestione dei Rischi", "risks", "Apri la voce **Rischi**.") +module_chapter(11, "Gestione degli Incidenti (Art. 23)", "incidents", "Apri la voce **Incidenti**.") +module_chapter(12, "Policy e procedure", "policies", "Apri la voce **Policy**.") +module_chapter(13, "Supply Chain (fornitori)", "supply-chain", "Apri la voce **Supply Chain**.") +module_chapter(14, "Formazione", "training", "Apri la voce **Formazione**.") +module_chapter(15, "Asset", "assets", "Apri la voce **Asset**.") +module_chapter(16, "Audit & Report", "reports", "Apri la voce **Audit & Report**.") +module_chapter(17, "Whistleblowing (Art. 32)", "whistleblowing", "Apri la voce **Segnalazioni**.") +module_chapter(18, "Aggiornamenti normativi", "normative", "Apri la voce **Normative**.") +module_chapter(19, "Knowledge Base", "kb", "Apri la voce **Knowledge Base**.") +module_chapter(20, "Compliance Journey", "workflow", "Apri la voce **Compliance Journey**: un percorso guidato che indica i prossimi passi consigliati.") +module_chapter(21, "Segnalazioni (feedback)", "feedback", + "Usa lo strumento di feedback per segnalare problemi o suggerimenti: ogni segnalazione cattura automaticamente versione e superficie del prodotto.") +module_chapter(22, "Impostazioni", "settings", "Apri la voce **Impostazioni**.") +module_chapter(23, "Gestione delle aziende (consulenti)", "companies", + "Disponibile per i consulenti: consente di gestire più aziende clienti da un unico accesso.") -# ===== 7. RISCHI ===== -add('pb'); add('h1', "7. Gestione dei Rischi") -add('p', "Registro dei rischi con matrice **Probabilità × Impatto 5×5** e supporto AI, conforme all'Art. 21 NIS2 e alla metodologia ISO 27005.") -add('ul', ["Creazione del rischio con scala probabilità/impatto (dettagli ISO 27005);", - "**Piani di trattamento** (mitigare, accettare, trasferire, evitare) e stato di avanzamento;", - "**Suggerimento AI** dei rischi per settore e asset (dati anonimizzati);", - "Funzioni avanzate: registro quantitativo **FAIR** (calcolo ALE Monte Carlo) e dashboard **KRI**."]) +# ══════════════════ 24. FAQ ══════════════════ +add('h1', "24. Domande frequenti (FAQ)") +add('h3', "Non riesco ad accedere") +add('p', "Verifica email e password; usa **Password dimenticata** per reimpostarla. Se usi il SSO della suite, accedi con le credenziali centralizzate.") +add('h3', "Ho sbagliato la classificazione NIS2") +add('p', "Puoi correggerla in **Impostazioni › Classificazione NIS2**: il perimetro dei moduli (es. Gap Analysis ACN) si aggiorna di conseguenza.") +add('h3', "Lo Statement of Applicability del Modello SGSI è quasi vuoto") +add('p', "Viene pre-popolato dalle risposte della **Gap Analysis NIS2**: completa prima quell'assessment, poi usa **Ri-deriva dal NIS2** nel SoA. I controlli senza corrispondenza NIS2 (es. alcuni controlli fisici) vanno compilati manualmente.") +add('h3', "Le email non vengono inviate") +add('p', "Negli ambienti dimostrativi l'invio email può essere disattivato per sicurezza. In produzione le notifiche (CSIRT, formazione, inviti) vengono inviate regolarmente.") +add('h3', "Le bozze generate dall'AI sono definitive?") +add('p', "No: sono **bozze** da rivedere e approvare. Riportano sempre un avviso e citano le fonti normative.") -# ===== 8. INCIDENTI ===== -add('pb'); add('h1', "8. Gestione degli Incidenti (Art. 23)") -add('p', "Gestione del ciclo di vita degli incidenti significativi e degli obblighi di notifica al CSIRT secondo l'Art. 23 e la Determinazione ACN 164179/2025.") -add('h2', "8.1 Tempistiche di notifica") -add('table', ["Adempimento","Termine"], - [["Pre-allarme (early warning)","entro 24 ore dalla conoscenza"], - ["Notifica completa","entro 72 ore dalla conoscenza"], - ["Relazione finale","entro 1 mese dalla notifica delle 72 ore"]]) -add('h2', "8.2 Funzioni") -add('ul', ["**Albero decisionale** per valutare la significatività (utenti ≥ 500, durata > 4h, cross-border, attacco cyber, danni > €100k);", - "**timeline** dell'incidente e metriche (triage, contenimento, eradicazione, ripristino);", - "invio di **early warning, notifica e relazione finale** al CSIRT;", - "**classificazione AI** (tipo IS-1..IS-4, severità) con citazione della fonte (Allegato 3 = importanti, Allegato 4 = essenziali);", - "**PIR** (Post-Incident Review) per l'apprendimento."]) - -# ===== 9. POLICY ===== -add('pb'); add('h1', "9. Policy e procedure") -add('ul', ["Creazione di policy da **template** o **generazione AI** (bozze marcate da revisionare);", - "flusso di **approvazione** e **versioning** con confronto delle versioni (diff);", - "**attestazione** di presa visione da parte del personale e relativo tracciamento."]) -add('note', "Le bozze generate dall'AI riportano un banner di avviso: vanno riviste e approvate da un responsabile prima della pubblicazione.") - -# ===== 10. SUPPLY CHAIN ===== -add('pb'); add('h1', "10. Supply Chain (fornitori)") -add('p', "Gestione della sicurezza della catena di approvvigionamento (Art. 21.2.d).") -add('ul', ["Anagrafica fornitori, categorie e **import** massivo;", - "**questionari** configurabili (categorie, template, domande) inviati ai fornitori;", - "**portale fornitore** dedicato con accesso separato via OTP/magic-link (autosalvataggio risposte);", - "**campagne** di valutazione e cruscotto del rischio fornitori (risk overview)."]) - -# ===== 11. FORMAZIONE ===== -add('pb'); add('h1', "11. Formazione") -add('p', "Gestione della formazione e dell'igiene informatica (Art. 21.2.g) e degli obblighi formativi per gli organi direttivi (Art. 20).") -add('ul', ["Catalogo **corsi** e **assegnazioni** al personale;", - "monitoraggio della **compliance formativa** e dei corsi obbligatori non completati."]) - -# ===== 12. ASSET ===== -add('pb'); add('h1', "12. Asset") -add('p', "Inventario degli asset informativi e delle dipendenze.") -add('ul', ["Anagrafica asset e **import** (CMDB/cloud);", - "**scoring di rilevanza NIS2** (0–100, criterio GV.OC-04) e classificazione dei sistemi rilevanti;", - "**mappa delle dipendenze** tra asset."]) - -# ===== 13. AUDIT & REPORT ===== -add('pb'); add('h1', "13. Audit & Report") -add('ul', ["Gestione dei **controlli di conformità** (framework NIS2 / ISO 27001) con stato ed evidenze;", - "caricamento **evidenze** e registro dei **log di audit**;", - "**mappature**: NIS2 ↔ ISO 27001 e NIST CSF 2.0; **registro dei sistemi rilevanti** (GV.OC-04);", - "**report esecutivo** stampabile ed **export CSV**;", - "**catena di integrità (hash chain SHA-256)**: ogni voce del log è concatenata alla precedente; verifica integrità ed **export certificato**."]) - -# ===== 14. WHISTLEBLOWING ===== -add('pb'); add('h1', "14. Whistleblowing (Art. 32)") -add('p', "Canale per le segnalazioni, anche anonime.") -add('ul', ["Invio segnalazione (anche **anonima**, con codice di tracciamento);", - "assegnazione, gestione e chiusura della segnalazione;", - "consultazione anonima dello stato tramite codice di tracciamento."]) - -# ===== 15. NORMATIVE ===== -add('pb'); add('h1', "15. Aggiornamenti normativi") -add('ul', ["Feed degli aggiornamenti **NIS2 / ACN / DORA**;", - "presa visione (**ACK**) tracciata per ciascun aggiornamento;", - "elenco aggiornamenti **in attesa** di presa visione e statistiche."]) - -# ===== 16. KB & AI ===== -add('pb'); add('h1', "16. Knowledge Base e Assistente AI") -add('h2', "16.1 Knowledge Base (RAG)") -add('p', "La Knowledge Base alimenta le risposte dell'AI tramite ricerca semantica (RAG). Prevede tre livelli di visibilità:") -add('table', ["Livello","Chi possiede","Chi vede"], - [["SYSTEM","Fornitore della piattaforma","Tutti gli utenti"], - ["FIRM","Studio di consulenza","Collaboratori dello studio + organizzazioni condivise"], - ["ORG","Singola organizzazione","Solo gli utenti di quella organizzazione"]]) -add('ul', ["Caricamento documenti (testo) con scelta dello scope;", - "ricerca semantica e cancellazione documenti;", - "le fonti normative certe (NIS2, D.Lgs. 138/2024, Determinazioni ACN) e i cataloghi **ISO 27001/27002/27017/27018** sono già indicizzati a livello SYSTEM."]) -add('h2', "16.2 Assistente AI") -add('p', "L'assistente risponde alle domande pescando dalla Knowledge Base e **cita sempre la fonte normativa pertinente**, senza inventare riferimenti. Le risposte sono di orientamento operativo e non sostituiscono il parere legale.") - -# ===== 17. FEEDBACK ===== -add('pb'); add('h1', "17. Segnalazioni (feedback)") -add('p', "Strumento integrato per segnalare bug o suggerimenti di UX. Le segnalazioni vengono classificate dall'AI e, una volta risolte, l'esito può essere comunicato ai membri dell'organizzazione. Ogni segnalazione cattura automaticamente la **versione del prodotto** e la **superficie** (web/mobile) per facilitare la diagnosi.") - -# ===== 18. IMPOSTAZIONI ===== -add('pb'); add('h1', "18. Impostazioni") -add('ul', ["**Organizzazione** — dati, classificazione NIS2;", - "**Profilo** — dati personali, cambio password, preferenze;", - "**Membri** — invito e gestione degli utenti e dei ruoli;", - "**Sessioni** — gestione dei dispositivi collegati (multi-device) e revoca;", - "**Branding** (white-label per studi) — personalizzazione per lo studio di consulenza."]) - -# ===== 19. AMMINISTRAZIONE ===== -add('pb'); add('h1', "19. Amministrazione") -add('p', "Area riservata al ruolo **super_admin**: gestione delle organizzazioni, degli utenti e statistiche di piattaforma.") - -# ===== 20. INTEGRAZIONI E API ===== -add('pb'); add('h1', "20. Integrazioni e API") -add('ul', ["**Services API** (autenticazione tramite API Key con scope) per integrazioni esterne, es. GRC/231: gap-analysis, misure, incidenti, formazione, scadenze e snapshot completo;", - "**Webhook** con firma HMAC-SHA256 e retry, per notifiche verso sistemi terzi;", - "**Licenze/inviti B2B** per provisioning di organizzazioni da parte di partner;", - "**SSO** centralizzato della suite AgileHub (sincronizzazione password)."]) - -# ===== 21. GLOSSARIO ===== -add('pb'); add('h1', "21. Glossario") +# ══════════════════ 25. GLOSSARIO ══════════════════ +add('h1', "25. Glossario") add('table', ["Termine","Significato"], [["NIS2","Direttiva (UE) 2022/2555 sulla cibersicurezza"], ["ACN","Agenzia per la Cybersicurezza Nazionale"], + ["Soggetto essenziale / importante","Categorie NIS2 che determinano gli obblighi applicabili"], + ["Gap Analysis","Analisi degli scostamenti tra stato attuale e requisiti"], ["SGSI / ISMS","Sistema di Gestione della Sicurezza delle Informazioni (ISO 27001)"], ["SoA","Statement of Applicability: dichiarazione di applicabilità dei controlli"], - ["Annex A","Elenco dei 93 controlli di sicurezza di ISO/IEC 27001:2022"], + ["Annex A","I 93 controlli di sicurezza di ISO/IEC 27001:2022"], ["RACI","Matrice di responsabilità: Responsible, Accountable, Consulted, Informed"], - ["CSIRT","Computer Security Incident Response Team (autorità di notifica)"], + ["CSIRT","Squadra nazionale di risposta agli incidenti (autorità di notifica)"], + ["NCR / CAPA","Non conformità / azioni correttive e preventive"], ["PIR","Post-Incident Review (revisione post-incidente)"], - ["RAG","Retrieval-Augmented Generation: AI con recupero da knowledge base"], - ["PII","Personally Identifiable Information (dati personali)"], - ["Soggetto essenziale / importante","Categorie NIS2 che determinano gli obblighi applicabili"]]) + ["RAG","Recupero da knowledge base a supporto delle risposte AI"], + ["PII","Dati personali (Personally Identifiable Information)"]]) -# ===== 22. RIFERIMENTI NORMATIVI ===== -add('pb'); add('h1', "22. Riferimenti normativi") +# ══════════════════ 26. RIFERIMENTI ══════════════════ +add('h1', "26. Riferimenti normativi") add('ul', ["Direttiva (UE) 2022/2555 (NIS2);", "Direttiva (UE) 2022/2557 (CER);", "D.Lgs. 4 settembre 2024, n. 138;", - "Determinazione ACN n. 164179 del 14/04/2025 (misure di base, classificazione e notifica incidenti, Allegati);", - "Determinazione ACN n. 333017/2025 (piattaforma ACN, designazione rappresentanti);", + "Determinazione ACN n. 164179 del 14/04/2025 (misure di base, classificazione e notifica incidenti);", + "Determinazione ACN n. 333017/2025;", "ISO/IEC 27001:2022, 27002:2022, 27017:2015, 27018:2019 (best practice, non vincolanti)."]) -add('note', "Questo manuale descrive le funzionalità della piattaforma NIS2 Agile alla versione 1.14.0. Le schermate e le voci di menu possono variare con gli aggiornamenti. Per l'aiuto contestuale usa l'icona ? presente in ogni pagina.") +add('note', f"Manuale d'uso di NIS2 Agile — versione piattaforma 1.14.0, aggiornato all'{DATE}. Per assistenza usa il pulsante di aiuto (?) presente in ogni pagina o la voce \"Guida all'uso\" nel menu.") -# ───────────────────────────────────────────────────────────────────────── -# EMITTER OOXML -# ───────────────────────────────────────────────────────────────────────── +# ════════════════════════════════ EMITTER OOXML ════════════════════════════════ def runs(text): - """Converte **bold** in run WordprocessingML.""" out = [] for i, part in enumerate(re.split(r'\*\*', text)): - if part == '': - continue - bold = (i % 2 == 1) - rpr = '' if bold else '' + if part == '': continue + rpr = '' if (i % 2 == 1) else '' out.append('%s%s' % (rpr, escape(part))) return ''.join(out) or '' @@ -294,62 +235,48 @@ def listitem(text, numid): '%s' % (numid, runs(text))) def cell(text, header=False): - shd = '' if header else '' - t = ('**%s**' % text) if header else text - # nelle intestazioni il testo bianco if header: + shd = '' r = '%s' % escape(text) else: - r = runs(text) - return ('%s%s' % (shd, r)) + shd = ''; r = runs(text) + return '%s%s' % (shd, r) def table(headers, rows): - borders = ('' + ''.join( - '' % s - for s in ['top','left','bottom','right','insideH','insideV']) + '') - tblpr = '%s' % borders - out = ['', tblpr] + borders = '' + ''.join(''%s + for s in ['top','left','bottom','right','insideH','insideV']) + '' + out = ['%s' % borders] out.append('' + ''.join(cell(h, True) for h in headers) + '') - for row in rows: - out.append('' + ''.join(cell(c) for c in row) + '') - out.append('') - out.append('') # spacing after table + for row in rows: out.append('' + ''.join(cell(c) for c in row) + '') + out.append('') return ''.join(out) -def title_block(t, sub, meta): - return (para(t, 'Title') + para(sub, 'Subtitle') + para(meta, 'Meta')) - body = [] for b in C: k = b[0] - if k == 'title': body.append(title_block(b[1], b[2], b[3])) - elif k == 'h1': body.append(para(b[1], 'Heading1')) - elif k == 'h2': body.append(para(b[1], 'Heading2')) - elif k == 'h3': body.append(para(b[1], 'Heading3')) + if k == 'title': body.append(para(b[1],'Title')+para(b[2],'Subtitle')+para(b[3],'Meta')) + elif k in ('h1','h2','h3'): body.append(para(b[1], {'h1':'Heading1','h2':'Heading2','h3':'Heading3'}[k])) elif k == 'p': body.append(para(b[1])) - elif k == 'note': body.append(para(b[1], 'Note')) - elif k == 'ul': body.append(''.join(listitem(x, 1) for x in b[1])) - elif k == 'ol': body.append(''.join(listitem(x, 2) for x in b[1])) + elif k == 'note': body.append(para(b[1],'Note')) + elif k == 'ul': body.append(''.join(listitem(x,1) for x in b[1])) + elif k == 'ol': body.append(''.join(listitem(x,2) for x in b[1])) elif k == 'table': body.append(table(b[1], b[2])) elif k == 'pb': body.append('') -SECT = ('' - '' - '') - +SECT = ('') document = ('' - '' - '' + ''.join(body) + SECT + '') + '' + + ''.join(body) + SECT + '') STYLES = ('' '' '' '' - '' - '' + '' + '' '' - '' - '' + '' + '' '' '' '' @@ -359,49 +286,35 @@ NUMBERING = ('' '' '' '' - '' - '' - '') + '') -CONTENT_TYPES = ('' +CT = ('' '' '' '' '' '' '' - '' - '') - + '') RELS = ('' '' '' - '' - '') - -DOC_RELS = ('' + '') +DRELS = ('' '' '' - '' - '') - + '') CORE = ('' - '' - 'Manuale d\'uso NIS2 AgileNIS2 Agile' - 'NIS2 Agile' - '2026-06-11T00:00:00Z' - '2026-06-11T00:00:00Z' - '') + '' + 'Manuale d\'uso NIS2 AgileNIS2 AgileNIS2 Agile' + '2026-06-11T00:00:00Z2026-06-11T00:00:00Z') with zipfile.ZipFile(OUT, 'w', zipfile.ZIP_DEFLATED) as z: - z.writestr('[Content_Types].xml', CONTENT_TYPES) + z.writestr('[Content_Types].xml', CT) z.writestr('_rels/.rels', RELS) z.writestr('word/document.xml', document) z.writestr('word/styles.xml', STYLES) z.writestr('word/numbering.xml', NUMBERING) - z.writestr('word/_rels/document.xml.rels', DOC_RELS) + z.writestr('word/_rels/document.xml.rels', DRELS) z.writestr('docProps/core.xml', CORE) - -print("OK ->", OUT) -print("blocchi:", len(C)) +print("OK ->", OUT, "| blocchi:", len(C))