[DOCS+KB] Gestione documentale: help (Permessi documentali) + i18n matrice IT/EN + ingest KB AI (v1.24.3)
- help.js: sezione 'Permessi documentali (ciclo di vita SGSI)' nel help Impostazioni - settings.html: matrice permessi bilingue IT/EN (azioni/ruoli/hint) + cache-buster help.js - KB AI: docs/kb/GESTIONE_DOCUMENTALE_SGSI.md + application/cli/ingest_doc_management_kb.php (ingerito in nis2_kb scope SYSTEM, ricercabilita verificata) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
e245e76671
commit
7b8a604739
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ingest_doc_management_kb.php — Ingest KB (RAG, scope SYSTEM) della guida "Gestione documentale SGSI".
|
||||||
|
* Testo INLINE (il container monta solo application/, non docs/). Idempotente (delete per source + re-upsert).
|
||||||
|
* Eseguire dal container: docker exec nis2-app php /var/www/nis2-agile/application/cli/ingest_doc_management_kb.php
|
||||||
|
* Opzioni: --dry-run
|
||||||
|
*/
|
||||||
|
if (PHP_SAPI !== 'cli') { http_response_code(403); exit("CLI only\n"); }
|
||||||
|
if (!defined('BASE_PATH')) define('BASE_PATH', dirname(dirname(__DIR__)));
|
||||||
|
if (!defined('APP_PATH')) define('APP_PATH', dirname(__DIR__));
|
||||||
|
require_once APP_PATH . '/config/env.php';
|
||||||
|
require_once APP_PATH . '/config/config.php';
|
||||||
|
require_once APP_PATH . '/config/database.php';
|
||||||
|
require_once APP_PATH . '/services/EmbedService.php';
|
||||||
|
require_once APP_PATH . '/services/VectorService.php';
|
||||||
|
|
||||||
|
$opts = getopt('', ['dry-run']); $dryRun = isset($opts['dry-run']);
|
||||||
|
function logln(string $m): void { echo '[' . date('Y-m-d H:i:s') . "] $m\n"; }
|
||||||
|
function uuid(): string { $b = random_bytes(16); $b[6]=chr((ord($b[6])&0x0f)|0x40); $b[8]=chr((ord($b[8])&0x3f)|0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($b),4)); }
|
||||||
|
function chunkText(string $t, int $size=2000, int $ov=200): array { $c=[]; $len=mb_strlen($t,'UTF-8'); $s=0; while($s<$len){ $take=min($size,$len-$s); $p=mb_substr($t,$s,$take,'UTF-8'); if(trim($p)!=='') $c[]=$p; if($s+$take>=$len) break; $s+=($size-$ov);} return $c; }
|
||||||
|
|
||||||
|
$SOURCE = 'Documentazione prodotto NIS2 Agile — Gestione documentale SGSI';
|
||||||
|
$TITLE = 'Gestione documentale SGSI (ciclo di vita, Word, editor, permessi)';
|
||||||
|
|
||||||
|
$TEXT = <<<'TXT'
|
||||||
|
DOCUMENTO: Gestione documentale del Modello SGSI in NIS2 Agile (ciclo di vita, export Word, editor, permessi).
|
||||||
|
USO: aiutare l'utente a gestire i documenti del Sistema di Gestione (Manuale, politiche, procedure, istruzioni operative).
|
||||||
|
NOTA: descrive funzioni dell'interfaccia; non e' contenuto normativo. ISO 27001/27017/27018 sono buone prassi; gli obblighi in Italia derivano da NIS2 / D.Lgs. 138/2024 / Determinazioni ACN.
|
||||||
|
|
||||||
|
# Gestione documentale del Modello SGSI (Modello SGSI > Documenti)
|
||||||
|
I documenti del Modello SGSI (ISO 27001) — Manuale SGSI, politiche, procedure e istruzioni operative — si trovano nel modulo "Modello SGSI (ISO 27001)", passo 5 "Documenti".
|
||||||
|
|
||||||
|
## Ciclo di vita del documento (ISO/IEC 27001 cl. 7.5)
|
||||||
|
Ogni documento attraversa gli stati: Bozza -> In revisione -> Approvato -> Pubblicato -> Archiviato. Lo stato e' mostrato con un badge colorato.
|
||||||
|
- "Invia in revisione": da Bozza a In revisione.
|
||||||
|
- "Approva": da In revisione ad Approvato (registra chi approva e quando).
|
||||||
|
- "Pubblica": da Approvato a Pubblicato — il documento entra in vigore; vengono impostate la data di entrata in vigore e la prossima data di riesame (a 1 anno).
|
||||||
|
- "Rimanda in bozza": riporta un documento in revisione alla Bozza, con una nota.
|
||||||
|
- "Archivia": ritira un documento pubblicato.
|
||||||
|
- "Nuova versione": riapre un documento pubblicato come nuova Bozza con numero di versione incrementato; la versione precedente resta nello storico.
|
||||||
|
Ad ogni pubblicazione viene salvato uno snapshot di versione, consultabile con il pulsante "Storico".
|
||||||
|
|
||||||
|
## Scaricare in Word
|
||||||
|
- Pulsante "Word" su un documento: scarica quel singolo documento in formato .doc, modificabile in Word o LibreOffice (mantiene titoli, elenchi e tabelle).
|
||||||
|
- Pulsante "Scarica tutto (Word)": scarica l'intero set documentale in un unico file Word, con copertina e indice.
|
||||||
|
- Pulsante "Apri": mostra il documento in una nuova scheda del browser.
|
||||||
|
|
||||||
|
## Modificare il contenuto
|
||||||
|
Il pulsante "Modifica" apre un editor con barra strumenti (grassetto, corsivo, titoli, elenchi) e una modalita' HTML. La modifica e' consentita solo sui documenti in stato Bozza o In revisione. Per modificare un documento gia' Pubblicato occorre prima creare una "Nuova versione".
|
||||||
|
|
||||||
|
## Permessi documentali (chi puo' fare cosa)
|
||||||
|
I diritti sulle azioni del ciclo di vita sono configurabili per RUOLO in "Impostazioni > Permessi documentali", tramite una matrice Ruolo x Azione (modifica contenuto, invia in revisione, approva, pubblica, rimanda in bozza, archivia, nuova versione). Vale per la singola organizzazione. Di default sono abilitati Amministratore, Responsabile SGSI/Compliance e Direzione; il super amministratore ha sempre tutti i permessi. La matrice e' visibile a tutti i membri, ma solo Amministratore e Direzione possono modificarla.
|
||||||
|
TXT;
|
||||||
|
|
||||||
|
$text = preg_replace('/\n{3,}/', "\n\n", trim($TEXT));
|
||||||
|
$chunks = chunkText($text, 2000, 200);
|
||||||
|
logln('=== Ingest "Gestione documentale SGSI" (scope SYSTEM) ===');
|
||||||
|
logln(' testo: ' . strlen($text) . ' char -> ' . count($chunks) . ' chunk');
|
||||||
|
if ($dryRun) { logln('DRY-RUN: nessun upsert.'); exit(0); }
|
||||||
|
|
||||||
|
$embed = new EmbedService();
|
||||||
|
$vector = new VectorService();
|
||||||
|
$vector->ensureCollection($embed->dims);
|
||||||
|
try {
|
||||||
|
$vector->deleteByFilter(['must' => [
|
||||||
|
['key' => 'scope', 'match' => ['value' => 'SYSTEM']],
|
||||||
|
['key' => 'source', 'match' => ['value' => $SOURCE]],
|
||||||
|
]]);
|
||||||
|
logln(' rimossi eventuali chunk precedenti per questa fonte');
|
||||||
|
} catch (Throwable $e) { logln(' (warning) delete: ' . $e->getMessage()); }
|
||||||
|
|
||||||
|
$docUuid = uuid(); $points = [];
|
||||||
|
foreach ($chunks as $i => $chunk) {
|
||||||
|
$vec = null;
|
||||||
|
for ($try = 1; $try <= 5; $try++) {
|
||||||
|
try { $vec = $embed->embed($chunk); break; }
|
||||||
|
catch (Throwable $e) { if ($try === 5) { logln(" ERRORE embed chunk {$i}: " . $e->getMessage()); throw $e; } logln(" retry embed chunk {$i} (tentativo {$try})"); sleep($try); }
|
||||||
|
}
|
||||||
|
$points[] = ['id' => uuid(), 'vector' => $vec, 'payload' => [
|
||||||
|
'doc_uuid' => $docUuid,
|
||||||
|
'title' => $TITLE . ($i > 0 ? ' (parte ' . ($i + 1) . ')' : ''),
|
||||||
|
'chunk' => $chunk,
|
||||||
|
'entity_type' => 'guida_prodotto',
|
||||||
|
'source' => $SOURCE,
|
||||||
|
'lang' => 'it',
|
||||||
|
'scope' => 'SYSTEM',
|
||||||
|
'consulting_firm_id' => null,
|
||||||
|
'organization_id' => null,
|
||||||
|
'shared_with_orgs' => [],
|
||||||
|
'uploaded_by' => 0,
|
||||||
|
]];
|
||||||
|
}
|
||||||
|
foreach (array_chunk($points, 64) as $batch) { $vector->upsertBatch($batch); }
|
||||||
|
logln(' upsert OK: ' . count($points) . ' chunk SYSTEM (source="' . $SOURCE . '")');
|
||||||
|
logln('=== FATTO ===');
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
DOCUMENTO: Gestione documentale del Modello SGSI in NIS2 Agile (ciclo di vita, export Word, editor, permessi).
|
||||||
|
USO: aiutare l'utente a gestire i documenti del Sistema di Gestione (Manuale, politiche, procedure, istruzioni operative).
|
||||||
|
NOTA: descrive funzioni dell'interfaccia; non e' contenuto normativo. ISO 27001/27017/27018 sono buone prassi; gli obblighi in Italia derivano da NIS2 / D.Lgs. 138/2024 / Determinazioni ACN.
|
||||||
|
|
||||||
|
# Gestione documentale del Modello SGSI (Modello SGSI > Documenti)
|
||||||
|
|
||||||
|
I documenti del Modello SGSI (ISO 27001) — Manuale SGSI, politiche, procedure e istruzioni operative — si trovano nel modulo "Modello SGSI (ISO 27001)", passo 5 "Documenti".
|
||||||
|
|
||||||
|
## Ciclo di vita del documento (ISO/IEC 27001 cl. 7.5)
|
||||||
|
Ogni documento attraversa gli stati: Bozza -> In revisione -> Approvato -> Pubblicato -> Archiviato. Lo stato e' mostrato con un badge colorato.
|
||||||
|
- "Invia in revisione": da Bozza a In revisione.
|
||||||
|
- "Approva": da In revisione ad Approvato (registra chi approva e quando).
|
||||||
|
- "Pubblica": da Approvato a Pubblicato — il documento entra IN VIGORE; vengono impostate la data di entrata in vigore e la prossima data di riesame (a 1 anno).
|
||||||
|
- "Rimanda in bozza": riporta un documento in revisione alla Bozza, con una nota.
|
||||||
|
- "Archivia": ritira un documento pubblicato.
|
||||||
|
- "Nuova versione": riapre un documento pubblicato come nuova Bozza con numero di versione incrementato; la versione precedente resta nello storico.
|
||||||
|
Ad ogni pubblicazione viene salvato uno snapshot di versione, consultabile con il pulsante "Storico".
|
||||||
|
|
||||||
|
## Scaricare in Word
|
||||||
|
- Pulsante "Word" su un documento: scarica quel singolo documento in formato .doc, modificabile in Word o LibreOffice (mantiene titoli, elenchi e tabelle).
|
||||||
|
- Pulsante "Scarica tutto (Word)": scarica l'INTERO set documentale in un unico file Word, con copertina e indice.
|
||||||
|
- Pulsante "Apri": mostra il documento in una nuova scheda del browser.
|
||||||
|
|
||||||
|
## Modificare il contenuto
|
||||||
|
Il pulsante "Modifica" apre un editor con barra strumenti (grassetto, corsivo, titoli, elenchi) e una modalita' HTML. La modifica e' consentita solo sui documenti in stato Bozza o In revisione. Per modificare un documento gia' Pubblicato occorre prima creare una "Nuova versione" (cosi' la versione in vigore resta tracciata e immutata).
|
||||||
|
|
||||||
|
## Permessi documentali (chi puo' fare cosa)
|
||||||
|
I diritti sulle azioni del ciclo di vita sono configurabili per RUOLO in "Impostazioni > Permessi documentali", tramite una matrice Ruolo x Azione (modifica contenuto, invia in revisione, approva, pubblica, rimanda in bozza, archivia, nuova versione). La configurazione vale per la singola organizzazione. Di default sono abilitati Amministratore, Responsabile SGSI/Compliance e Direzione; il super amministratore ha sempre tutti i permessi. La matrice e' visibile a tutti i membri (trasparenza), ma solo Amministratore e Direzione possono modificarla e salvarla.
|
||||||
@@ -1032,6 +1032,15 @@ const HelpSystem = (function () {
|
|||||||
'Il settore e la dimensione influenzano la classificazione NIS2.'
|
'Il settore e la dimensione influenzano la classificazione NIS2.'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
heading: 'Permessi documentali (ciclo di vita SGSI)',
|
||||||
|
items: [
|
||||||
|
'Nel tab <strong>Permessi documentali</strong> definisci, con una matrice <strong>Ruolo x Azione</strong>, quali ruoli possono compiere ogni passo del ciclo di vita dei documenti del Modello SGSI: modifica del contenuto, invio in revisione, approvazione, pubblicazione, rinvio in bozza, archiviazione, nuova versione.',
|
||||||
|
'La configurazione vale per la singola organizzazione; di default sono abilitati Amministratore, Responsabile SGSI/Compliance e Direzione. Il super amministratore ha sempre tutti i permessi.',
|
||||||
|
'La matrice è <strong>visibile a tutti i membri</strong> (trasparenza), ma solo <strong>Amministratore e Direzione</strong> possono modificarla e salvarla.',
|
||||||
|
'Lascia sempre almeno un ruolo abilitato per le azioni critiche (Approva, Pubblica), altrimenti nessuno potrebbe far avanzare i documenti.'
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
heading: 'Classificazione NIS2',
|
heading: 'Classificazione NIS2',
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
+16
-7
@@ -701,7 +701,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="/js/common-bi.js?v=20260631"></script>
|
<script src="/js/common-bi.js?v=20260631"></script>
|
||||||
<script src="/js/i18n.js?v=20260631"></script>
|
<script src="/js/i18n.js?v=20260631"></script>
|
||||||
<script src="/js/help.js?v=20260618p2"></script>
|
<script src="/js/help.js?v=20260620c"></script>
|
||||||
<script>
|
<script>
|
||||||
// ── Auth check ───────────────────────────────────────────
|
// ── Auth check ───────────────────────────────────────────
|
||||||
if (!checkAuth()) throw new Error('Not authenticated');
|
if (!checkAuth()) throw new Error('Not authenticated');
|
||||||
@@ -750,8 +750,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── Permessi documentali (matrice Ruolo x Azione) ──
|
// ── Permessi documentali (matrice Ruolo x Azione) ──
|
||||||
const DOCPERM_CAP_LABELS = { edit:'Modifica contenuto', submit:'Invia in revisione', approve:'Approva', publish:'Pubblica', reject:'Rimanda in bozza', archive:'Archivia', new_version:'Nuova versione' };
|
const _dpLang = function(){ try { return (window.I18n && I18n.getLang && I18n.getLang()) || 'it'; } catch(e){ return 'it'; } };
|
||||||
const DOCPERM_ROLE_LABELS = { org_admin:'Amministratore', compliance_manager:'Resp. SGSI/Compliance', board_member:'Direzione/CdA', auditor:'Auditor', employee:'Dipendente', consultant:'Consulente' };
|
const DOCPERM_CAP_LABELS = {
|
||||||
|
it: { edit:'Modifica contenuto', submit:'Invia in revisione', approve:'Approva', publish:'Pubblica', reject:'Rimanda in bozza', archive:'Archivia', new_version:'Nuova versione' },
|
||||||
|
en: { edit:'Edit content', submit:'Submit for review', approve:'Approve', publish:'Publish', reject:'Send back to draft', archive:'Archive', new_version:'New version' }
|
||||||
|
};
|
||||||
|
const DOCPERM_ROLE_LABELS = {
|
||||||
|
it: { org_admin:'Amministratore', compliance_manager:'Resp. SGSI/Compliance', board_member:'Direzione/CdA', auditor:'Auditor', employee:'Dipendente', consultant:'Consulente' },
|
||||||
|
en: { org_admin:'Administrator', compliance_manager:'ISMS/Compliance Mgr', board_member:'Board/Management', auditor:'Auditor', employee:'Employee', consultant:'Consultant' }
|
||||||
|
};
|
||||||
|
function _dpCap(c){ const l=_dpLang(); return (DOCPERM_CAP_LABELS[l]&&DOCPERM_CAP_LABELS[l][c]) || DOCPERM_CAP_LABELS.it[c] || c; }
|
||||||
|
function _dpRole(r){ const l=_dpLang(); return (DOCPERM_ROLE_LABELS[l]&&DOCPERM_ROLE_LABELS[l][r]) || DOCPERM_ROLE_LABELS.it[r] || r; }
|
||||||
let _docpermCanEdit = false;
|
let _docpermCanEdit = false;
|
||||||
async function loadDocPerms(){
|
async function loadDocPerms(){
|
||||||
const box = document.getElementById('docperms-matrix');
|
const box = document.getElementById('docperms-matrix');
|
||||||
@@ -762,11 +771,11 @@
|
|||||||
const roles = r.data.roleList || [];
|
const roles = r.data.roleList || [];
|
||||||
_docpermCanEdit = !!r.data.canEdit;
|
_docpermCanEdit = !!r.data.canEdit;
|
||||||
let h = '<div style="overflow-x:auto;"><table style="width:100%;border-collapse:collapse;font-size:.88rem;">';
|
let h = '<div style="overflow-x:auto;"><table style="width:100%;border-collapse:collapse;font-size:.88rem;">';
|
||||||
h += '<tr><th style="text-align:left;padding:8px;border-bottom:2px solid #e5e7eb;">Azione</th>';
|
h += '<tr><th style="text-align:left;padding:8px;border-bottom:2px solid #e5e7eb;">'+(_dpLang()==='en'?'Action':'Azione')+'</th>';
|
||||||
roles.forEach(function(role){ h += '<th style="padding:8px;border-bottom:2px solid #e5e7eb;text-align:center;">'+(DOCPERM_ROLE_LABELS[role]||role)+'</th>'; });
|
roles.forEach(function(role){ h += '<th style="padding:8px;border-bottom:2px solid #e5e7eb;text-align:center;">'+_dpRole(role)+'</th>'; });
|
||||||
h += '</tr>';
|
h += '</tr>';
|
||||||
caps.forEach(function(c){
|
caps.forEach(function(c){
|
||||||
h += '<tr><td style="padding:8px;border-bottom:1px solid #f1f5f9;font-weight:600;">'+(DOCPERM_CAP_LABELS[c.capability]||c.capability)+'</td>';
|
h += '<tr><td style="padding:8px;border-bottom:1px solid #f1f5f9;font-weight:600;">'+_dpCap(c.capability)+'</td>';
|
||||||
roles.forEach(function(role){
|
roles.forEach(function(role){
|
||||||
const checked = c.roles[role] ? 'checked' : '';
|
const checked = c.roles[role] ? 'checked' : '';
|
||||||
const dis = _docpermCanEdit ? '' : 'disabled';
|
const dis = _docpermCanEdit ? '' : 'disabled';
|
||||||
@@ -778,7 +787,7 @@
|
|||||||
const saveBtn = document.getElementById('docperms-save');
|
const saveBtn = document.getElementById('docperms-save');
|
||||||
const hint = document.getElementById('docperms-hint');
|
const hint = document.getElementById('docperms-hint');
|
||||||
if (saveBtn) saveBtn.style.display = _docpermCanEdit ? '' : 'none';
|
if (saveBtn) saveBtn.style.display = _docpermCanEdit ? '' : 'none';
|
||||||
if (hint) hint.textContent = _docpermCanEdit ? 'Suggerimento: lascia almeno un ruolo per ogni azione critica (approva, pubblica).' : 'Solo Amministratore o Direzione possono modificare i permessi.';
|
if (hint) hint.textContent = _docpermCanEdit ? (_dpLang()==='en'?'Tip: keep at least one role enabled for critical actions (approve, publish).':'Suggerimento: lascia almeno un ruolo per ogni azione critica (approva, pubblica).') : (_dpLang()==='en'?'Only Administrator or Management can change permissions.':'Solo Amministratore o Direzione possono modificare i permessi.');
|
||||||
}
|
}
|
||||||
async function saveDocPerms(){
|
async function saveDocPerms(){
|
||||||
if (!_docpermCanEdit) return;
|
if (!_docpermCanEdit) return;
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version": "1.24.2", "build": "2026-06-20-v1.24.2", "date": "2026-06-20", "changelog": "Permessi documentali profilabili per ruolo. I diritti sul ciclo di vita dei documenti SGSI (modifica, invia in revisione, approva, pubblica, rimanda in bozza, archivia, nuova versione) non sono piu cablati: si configurano in Impostazioni > Permessi documentali con una matrice Ruolo x Azione (org_admin, compliance_manager, board_member, auditor, employee, consultant), per organizzazione. Migrazione 061 (tabella isms_doc_permissions). I controlli di ruolo nelle 7 transizioni usano ora requireDocCapability (con default = comportamento precedente); super_admin sempre consentito. Endpoint GET/PUT /api/isms/docPermissions (lettura aperta ai membri, scrittura ad Amministratore/Direzione)."}
|
{"version": "1.24.3", "build": "2026-06-20-v1.24.3", "date": "2026-06-20", "changelog": "Allineamento help/traduzioni/AI per la gestione documentale SGSI: (1) Help contestuale — aggiunta in Impostazioni la sezione 'Permessi documentali (ciclo di vita SGSI)' e completata la guida del Modello SGSI su editor, download Word singolo/unico e ciclo di vita; (2) Traduzioni — matrice Permessi documentali resa bilingue IT/EN (azioni, ruoli, suggerimenti); (3) AI/KB — ingerito nella knowledge base RAG (nis2_kb, scope SYSTEM) il documento 'Gestione documentale SGSI' (ciclo di vita, export Word, editor, permessi), cosi' l'assistente puo' guidare l'utente su queste funzioni."}
|
||||||
|
|||||||
Reference in New Issue
Block a user