Files
nis2-agile/docs/mappa-logica/14_kb.md
T
DevEnv nis2-agileandClaude Opus 4.8 4dfab2a391 [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>
2026-06-12 18:50:19 +02:00

45 lines
4.9 KiB
Markdown
Raw 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.
# MAPPA-LOGICA · Knowledge Base
⟦ INIZIO · U-KB · Videata "Knowledge Base" ⟧
File: public/kb.html · URL: /kb.html · Scopo: caricamento e gestione dei documenti (procedure, policy, normative, training material) che l'AI usa per rispondere con citazioni precise (pipeline RAG su Qdrant), con visibilità a 3 livelli: SYSTEM (vendor), FIRM (studio + condivisioni esplicite), ORG (singola organizzazione cliente) · Profili: lettura/ricerca per tutti gli utenti autenticati (la visibilità applica il filtro authz a 3 livelli); l'upload (ingest) è riservato ai ruoli super_admin, org_admin, compliance_manager e consultant (employee/auditor read-only, 403 KB_FORBIDDEN). Per scope: SYSTEM solo super_admin; FIRM solo utenti con consulting_firm_id (consulenti di studio); ORG richiede ruolo org_admin/compliance_manager sull'organizzazione destinataria (super_admin bypassa) e `organization_id` valorizzato lato backend. La UI mostra/nasconde le radio di scope client-side (`setupScopeForUser`), ma l'enforcement è nel backend (KnowledgeBaseController::ingest).
• U-KB.1 — Header pagina + "Carica documento"
Mostra: titolo "Knowledge Base"; paragrafo introduttivo sul modello di visibilità a 3 livelli (SYSTEM/FIRM/ORG).
Azioni: bottone "Carica documento" → toggle del form di upload (U-KB.2); all'apertura chiama `setupScopeForUser()` che mostra/nasconde le opzioni di scope in base a ruolo e firm.
Dati da: GET /api/auth/me (per role e consulting_firm_id, determina gli scope disponibili).
Confine: `#btn-kb-upload` (riga 34).
• U-KB.2 — Form di upload/indicizzazione documento (nascosto di default)
Mostra: campo "Titolo"; select "Tipo" (Procedura interna / Linea guida / Normativa / Training); textarea "Contenuto (testo libero, 50–50.000 caratteri)"; radio "Visibilità": "Sistema (super_admin)" (visibile solo a super_admin), "Studio + condivisioni" (visibile solo a utenti firm), "Solo organizzazione corrente" (default, sempre visibile); status di indicizzazione ("Indicizzazione in corso..." / "Documento indicizzato (SCOPE, N chunk)" / messaggi di errore con validazione: titolo obbligatorio, testo minimo 50 caratteri).
Azioni: "Indicizza documento" → POST ingest (embed Voyage + upsert Qdrant + tracking MySQL), poi svuota i campi e ricarica la lista; "Annulla" → nasconde il form; selezione radio "FIRM" → mostra il blocco condivisione (U-KB.3).
Dati da: POST /api/knowledgebase/ingest (body: title, text, entity_type, scope, shared_with_orgs[]).
Confine: `#kb-form-card` (riga 50); `#kb-title` (55), `#kb-entity-type` (59), `#kb-text` (70), radio `input[name="kb-scope"]` con label `[data-scope-opt="SYSTEM|FIRM|ORG"]` (righe 77-84), `#btn-kb-submit` (102), `#btn-kb-cancel` (103), `#kb-status` (104).
• U-KB.3 — Blocco condivisione FIRM (visibile solo con scope=FIRM)
Mostra: multi-select "Organizzazioni clienti destinatarie (Ctrl/Cmd per selezione multipla, opzionale)" popolata con le organizzazioni dello studio (nome + P.IVA); nota: "Lascia vuoto per condividere solo con i collaboratori dello studio".
Azioni: selezione multipla delle org destinatarie → inviate come shared_with_orgs nell'ingest.
Dati da: GET /api/knowledgebase/firmOrgs (risposta: data.organizations[]).
Confine: `#kb-share-block` (riga 89), `#kb-shared-with` (riga 93).
• U-KB.4 — Lista "Documenti caricati visibili"
Mostra: per ogni documento visibile all'utente: titolo, badge scope colorato (SYSTEM blu / FIRM ambra / ORG verde), tipo entità, numero chunk, data di creazione; "Nessun documento visibile" se vuota. La visibilità applica il filtro authz a 3 livelli lato backend.
Azioni: bottone "Elimina" per documento → conferma → DELETE (rimuove documento + chunk da Qdrant) e ricarica la lista.
Dati da: GET /api/knowledgebase/list (risposta: data.documents[]); DELETE /api/knowledgebase/{id}.
Confine: card `.kb-doc-list` (riga 110); contenitore lista `#kb-doc-list` (riga 115); bottoni elimina dinamici con attributo `[data-del-id="<id>"]` (kb.js riga 110).
• U-KB.5 — "Test search semantica"
Mostra: campo query (placeholder "Es: come gestire un incidente NIS2?"); risultati: per ogni hit [N] titolo, badge scope, score di similarità, estratto del contenuto (primi 300 caratteri); "Nessun risultato" se vuoto.
Azioni: bottone "Cerca" → POST search semantica (top 5 risultati) nel perimetro di visibilità dell'utente.
Dati da: POST /api/knowledgebase/search (body: {query, top_k: 5}; risposta: data.results[]).
Confine: `#kb-search-query` (riga 127), `#btn-kb-search` (riga 128), `#kb-search-results` (riga 133).
⟦ FINE · U-KB ⟧
## ID STABILI MANCANTI (da aggiungere)
| Elemento | Riga | Id proposto |
|---|---|---|
| Card lista documenti (wrapper) | 110 | `nis2-kb-doc-list-card` |
| Card test search (wrapper) | 122 | `nis2-kb-search-card` |
| Paragrafo intro visibilità | 42 | `nis2-kb-intro` |
| Bottone "Elimina" documento (dinamico) | kb.js 110 | già presente `data-del-id` (selettore stabile, ok) |