Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
83 lines
9.3 KiB
Markdown
83 lines
9.3 KiB
Markdown
# 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).
|