Files
nis2-agile/docs/DESIGN_A2_ONBOARDING.md

83 lines
9.3 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.
# DESIGN — A2: Onboarding aziendale con classificazione NIS2 (autovalutazione preliminare)
> Stato: **DESIGN (pre-implementazione)**. Contesto: segnalazione Simon Fattori, punto accolto A2.
> Data: 2026-06-15. Fonti verificate: `docs/nis2/AmbitiNIS2_ITA.pdf` (matrice ACN settore×dimensione), `Determina333017_sett2025` (commi art.3, soglie, DPR 445, finestra registrazione), `Dir2022_2555_UE_NIS2_ITA` (Racc. 2003/361/CE, soggetti size-independent, esclusione PA). Vedi memoria `reference-dlgs-articles`.
## 0. Principio cardine (vincolante)
L'esito dell'onboarding è una **AUTOVALUTAZIONE PRELIMINARE NON VINCOLANTE**. La **qualifica formale** di soggetto essenziale/importante e la **registrazione** spettano esclusivamente ad **ACN** via piattaforma (Det. 333017/2025: dichiarazione ex **DPR 445/2000** confermata dal punto di contatto; finestra registrazione **1 gennaio – 28 febbraio**; verifiche di coerenza ACN ex art. 14). → Mai etichettare l'esito come "classificazione" o "qualifica"; sempre "**autovalutazione preliminare**" + disclaimer + rinvio alla piattaforma ACN. La classificazione formale e i pareri legali competono a Direzione/Legale del cliente.
## 1. Stato attuale (da ESTENDERE, non riscrivere)
- **Wizard 4 step** (`onboarding.html` = `onboarding-bi.html`): 1) P.IVA → 2) Dati aziendali → 3) Profilo → 4) Classificazione + voluntary.
- **Backend**: `OnboardingController.complete()` → `classifyNis2Entity(sector, employees, turnover)`; `OrganizationController.classifyEntity()` (POST `/api/organizations/classify`).
- **Tabella `organizations`**: `sector` ENUM(17), `entity_type` ENUM('essential','important','not_applicable'), `employee_count`, `annual_turnover_eur`, `voluntary_compliance` TINYINT.
- **Logica attuale**: grande (≥250 dip OR ≥50M€) / media (≥50 dip OR ≥10M€) × settore (lista essenziali/importanti). `VisuraService` mappa ATECO→sector.
- **GAP da colmare**: manca il criterio **bilancio €43M**, le **categorie size-independent**, il **calcolo gruppo/collegate**, i **criteri qualitativi sotto-soglia**, i campi **mission/codice etico**, e il framing **"preliminare/non vincolante"**.
## 2. Matrice di classificazione (VERIFICATA)
**Soglie dimensionali (Racc. 2003/361/CE):** Micro <10 dip & ≤2M€ · Piccola <50 & ≤10M€ · Media <250 & ≤50M€ fatt / ≤43M€ bilancio · **Grande** ≥250 dip **OR** >50M€ fatt **OR** >43M€ bilancio. (NB: il **bilancio** è un terzo criterio oggi assente nel prodotto.)
| Dimensione | Allegato I (alta criticità) | Allegato II (altri settori critici) |
|---|---|---|
| **Grande** | **ESSENZIALE** | IMPORTANTE |
| **Media** | IMPORTANTE | IMPORTANTE |
| **Piccola / micro** | fuori soglia¹ | fuori soglia¹ |
¹ salvo categorie size-independent (§3) e individuazione sotto-soglia (§4).
**Gruppo/collegate**: per imprese non autonome il calcolo è **consolidato** (Racc. 2003/361/CE art. 6 §2; Det. 333017 art. 11 c. 4). L'onboarding deve chiedere l'autonomia e, se gruppo, segnalare che il calcolo va consolidato (no auto-classificazione cieca sulla singola entità).
## 3. Soggetti in ambito A PRESCINDERE DALLA DIMENSIONE (§ size-independent)
Da AmbitiNIS2 + Direttiva Art. 2: **essenziali** indipendentemente dalla taglia → fornitori **DNS** (no root server), registri **TLD**, **IXP**, **servizi fiduciari qualificati**, **reti pubbliche di comunicazione elettronica** e **servizi di comunicazione elettronica accessibili al pubblico**. **Importanti** → servizi fiduciari **non** qualificati, **registrar** di nomi di dominio. **PA** (Allegato III): centrali = essenziali, regionali/locali = importanti — **con esclusione** sicurezza nazionale/difesa/intelligence/ordine pubblico. → L'onboarding deve poter marcare queste categorie e classificarle a prescindere dalle soglie.
## 4. Criteri qualitativi sotto-soglia — ✅ COMMA CONFERMATO
Riferimento **verificato sul testo verbatim** (`docs/nis2/Dlgs138_art3_ambito.md`): **art. 3, comma 9, lett. b/c/d** del D.Lgs. 138/2024:
1. **lett. b** — il soggetto è l'**unico fornitore nazionale** di un servizio essenziale per attività sociali/economiche fondamentali;
2. **lett. c** — una perturbazione del servizio avrebbe **impatto significativo su sicurezza pubblica, incolumità pubblica o salute pubblica**;
3. **lett. d** — una perturbazione comporterebbe un **rischio sistemico significativo** (anche transfrontaliero).
(lett. a = ex operatore servizi essenziali D.Lgs. 65/2018.) La **procedura di individuazione** è il **comma 13** (ACN su proposta delle Autorità di settore), richiamato dal comma 9. → In UI/AI citare "**art. 3, c. 9, lett. b/c/d**" per i criteri e "**individuazione ex art. 3, c. 13**" per la procedura.
**Esito quando scattano**: **NON auto-assegnare** essenziale/importante (Allegato IV ACN: i sotto-soglia sono individuati caso per caso dall'Autorità). Il prodotto segnala "**potenziale soggetto individuabile ex art. 3 c. 9/c. 13 — rinvio ad ACN**".
**Esito quando scattano**: **NON auto-assegnare** essenziale/importante (Allegato IV ACN: i sotto-soglia possono essere individuati importanti *o* essenziali, caso per caso, dall'Autorità). Il prodotto segnala solo "**potenziale soggetto individuabile — rinvio ad ACN**".
## 5. Data model (nuova migration `040_onboarding_classification.sql`, additiva)
`ALTER TABLE organizations ADD`:
- `total_balance_eur` DECIMAL(15,2) NULL — bilancio (3° criterio dimensionale)
- `is_autonomous` TINYINT(1) DEFAULT 1 — impresa autonoma? (no → calcolo consolidato/gruppo da rivedere)
- `size_independent_category` ENUM('none','dns','tld','ixp','trust_qualified','trust_unqualified','ecomm_public_network','ecomm_public_service','domain_registrar','pa_central','pa_regional_local') DEFAULT 'none'
- `crit_sole_supplier` TINYINT(1) NULL · `crit_public_impact` TINYINT(1) NULL · `crit_systemic_risk` TINYINT(1) NULL — risposte ai 3 criteri qualitativi
- `mission` TEXT NULL — contesto organizzativo (input GV.OC / registro sistemi rilevanti)
- `has_code_of_ethics` TINYINT(1) DEFAULT 0 + `code_of_ethics_note` VARCHAR(255) NULL — **facoltativo, best practice** (NON obbligo NIS2)
- `designation_basis` ENUM('dimensional','size_independent','sub_threshold_candidate','voluntary','out_of_scope') NULL
- `self_assessment_status` ENUM('preliminary','acn_confirmed') DEFAULT 'preliminary'
`entity_type` ENUM resta **invariato** ('essential','important','not_applicable') per compatibilità; il dettaglio "candidato sotto-soglia" è in `designation_basis`.
## 6. Logica di classificazione v2 (decision tree — `classifyNis2Entity()`)
```
1. SE size_independent_category != none:
-> essential/important secondo categoria (trust_qualified=essential, trust_unqualified=important,
dns/tld/ixp/ecomm_public_*=essential, domain_registrar=important, pa_central=essential,
pa_regional_local=important); designation_basis = size_independent
2. ALTRIMENTI calcola classe dimensionale da dip / fatturato / BILANCIO (+ se !is_autonomous: WARNING gruppo)
3. settore Allegato I: grande->essential ; media->important
settore Allegato II: media|grande->important
4. ALTRIMENTI (piccola/micro o settore fuori): out_of_scope -> mostra i 3 criteri qualitativi (§4).
SE almeno 1 = sì -> designation_basis = sub_threshold_candidate, entity_type = not_applicable
(NON essential/important), messaggio "possibile individuazione ACN".
5. voluntary_compliance resta disponibile per out_of_scope che aderiscono volontariamente.
TUTTI gli esiti: self_assessment_status = preliminary + disclaimer (§0).
```
## 7. UI flow (estensione del wizard esistente)
- **Step 2 (Dati aziendali)** +: `total_balance_eur`; domanda **autonomia/gruppo**; sezione **"Categorie speciali NIS2"** (checkbox: fornitore DNS/TLD/IXP, servizi fiduciari [qualif/non], rete o servizio TLC pubblico, registrar domini, PA centrale/locale); **mission** (textarea, label "contesto organizzativo — alimenta il registro dei sistemi rilevanti, misura GV.OC"); **codice etico** (toggle opzionale, badge "facoltativo — buona prassi, non richiesto dalla NIS2").
- **Step 4 (Esito)**: **griglia settore×dimensione** con la cella risultante evidenziata; badge **"Autovalutazione preliminare — non vincolante"**; SE sotto-soglia → blocco con le **3 domande qualitative** (principi, "individuazione dell'Autorità") → esito "potenziale individuazione, rinvio ACN"; **disclaimer ACN** (Det. 333017, DPR 445/2000, finestra 1/1–28/2, verifiche art. 14) + link/CTA "registrazione sulla piattaforma ACN".
## 8. PREREQUISITI prima dell'implementazione (gating)
1. ✅ **Comma confermato** sul testo verbatim (criteri = art. 3 **c. 9 lett. b/c/d**; procedura individuazione = **c. 13**; size-independent = **c. 5**; dimensionale = **c. 2**) → estratto in `docs/nis2/Dlgs138_art3_ambito.md`. **Prereq risolto: A2 non è più bloccato.**
2. (Facoltativo — grounding KB completo) ingestare il **PDF integrale** del D.Lgs. 138/2024: NON auto-fetchabile da GU/Normattiva (solo metadati/indice), serve il PDF fornito manualmente → `docs/nis2/` + KB. Non blocca A2.
3. Decidere il trattamento **gruppo/collegate** (almeno warning + flag `is_autonomous`).
## 9. Cosa NON cambia (compatibilità)
`entity_type` ENUM (3 valori) invariato · `voluntary_compliance` invariato · init dei 13 compliance controls invariato · flusso visura/CertiSource/lookup-piva invariato · `classify` endpoint retro-compatibile (campi nuovi opzionali).