[FEAT] Simulatore v2: auto-reset, UX migliorata, 6 scenari (lg231-inspired)
- simulate-nis2.php: autoResetDemo() via PDO pulisce dati demo prima di ogni run (SIM-01→05), skip per SIM-06 indipendente. Rimuove tutte le tabelle org_id>4 eccetto audit_logs (trigger immutabile). - simulate.html v2.0: rimosso pulsante "Reset Dati Demo" (chiamava endpoint inesistente /api/admin/reset-demo). Aggiunti: confirm dialog con lista aziende + durata, spinner sul bottone, nota auto-reset visibile, run history localStorage (ultimi 5), card SIM-06 B2B License Provisioning, console phase-banner stile lg231. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
ca8f077a7a
commit
e8b74a7cb7
@@ -606,6 +606,95 @@ function getAssessmentResponses(string $sector): array
|
||||
return array_merge($base, $overrides);
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
// Auto-Reset Demo Data — eseguito prima di ogni run SIM-01→05
|
||||
// Usa PDO con nis2_user (NO SUPER privilege → non tocca audit_logs/trigger)
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
function autoResetDemo(): void
|
||||
{
|
||||
$host = readEnvValue('DB_HOST', 'localhost');
|
||||
$port = readEnvValue('DB_PORT', '3306');
|
||||
$name = readEnvValue('DB_NAME', 'nis2_agile_db');
|
||||
$user = readEnvValue('DB_USER', 'nis2_user');
|
||||
$pass = readEnvValue('DB_PASS', '');
|
||||
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"mysql:host={$host};port={$port};dbname={$name};charset=utf8mb4",
|
||||
$user,
|
||||
$pass,
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_TIMEOUT => 10]
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
simLog('Auto-reset: connessione DB fallita — ' . $e->getMessage(), 'warn');
|
||||
return;
|
||||
}
|
||||
|
||||
$pdo->exec('SET FOREIGN_KEY_CHECKS=0');
|
||||
|
||||
// Tabelle con organization_id (ordine: dipendenti prima dei parent)
|
||||
$orgTables = [
|
||||
'incident_timeline' => 'incident_id IN (SELECT id FROM incidents WHERE organization_id > 4)',
|
||||
'incidents' => 'organization_id > 4',
|
||||
'risk_treatments' => 'risk_id IN (SELECT id FROM risks WHERE organization_id > 4)',
|
||||
'risks' => 'organization_id > 4',
|
||||
'assessment_responses' => 'assessment_id IN (SELECT id FROM assessments WHERE organization_id > 4)',
|
||||
'assessments' => 'organization_id > 4',
|
||||
'policies' => 'organization_id > 4',
|
||||
'suppliers' => 'organization_id > 4',
|
||||
'training_assignments' => 'course_id IN (SELECT id FROM training_courses WHERE organization_id > 4)',
|
||||
'training_courses' => 'organization_id > 4',
|
||||
'assets' => 'organization_id > 4',
|
||||
'compliance_controls' => 'organization_id > 4',
|
||||
'evidence_files' => 'organization_id > 4',
|
||||
'capa_actions' => 'ncr_id IN (SELECT id FROM non_conformities WHERE organization_id > 4)',
|
||||
'non_conformities' => 'organization_id > 4',
|
||||
'whistleblowing_timeline' => 'report_id IN (SELECT id FROM whistleblowing_reports WHERE organization_id > 4)',
|
||||
'whistleblowing_reports' => 'organization_id > 4',
|
||||
'normative_ack' => 'organization_id > 4',
|
||||
'webhook_deliveries' => 'subscription_id IN (SELECT id FROM webhook_subscriptions WHERE organization_id > 4)',
|
||||
'webhook_subscriptions' => 'organization_id > 4',
|
||||
'api_keys' => 'organization_id > 4',
|
||||
'feedback_reports' => 'organization_id > 4',
|
||||
'ai_interactions' => 'organization_id > 4',
|
||||
// audit_logs: trigger immutabile blocca DELETE — skip (dati storici accettabili)
|
||||
];
|
||||
|
||||
$deleted = 0;
|
||||
foreach ($orgTables as $table => $where) {
|
||||
try {
|
||||
$n = $pdo->exec("DELETE FROM `{$table}` WHERE {$where}");
|
||||
$deleted += ($n ?: 0);
|
||||
} catch (\Throwable $e) {
|
||||
simLog(" skip {$table}: " . $e->getMessage(), 'skip');
|
||||
}
|
||||
}
|
||||
|
||||
// Email log (no organization_id)
|
||||
try { $pdo->exec("DELETE FROM email_log WHERE recipient LIKE '%.demo%'"); } catch (\Throwable) {}
|
||||
|
||||
// User organizations + refresh tokens demo
|
||||
try { $pdo->exec('DELETE FROM user_organizations WHERE organization_id > 4'); } catch (\Throwable) {}
|
||||
try {
|
||||
$pdo->exec("DELETE rt FROM refresh_tokens rt
|
||||
JOIN users u ON rt.user_id = u.id
|
||||
WHERE u.email LIKE '%.demo%'");
|
||||
} catch (\Throwable) {}
|
||||
|
||||
// Utenti demo
|
||||
try { $n = $pdo->exec("DELETE FROM users WHERE email LIKE '%.demo%'"); $deleted += ($n ?: 0); } catch (\Throwable) {}
|
||||
|
||||
// Organizzazioni demo
|
||||
try { $n = $pdo->exec('DELETE FROM organizations WHERE id > 4'); $deleted += ($n ?: 0); } catch (\Throwable) {}
|
||||
|
||||
$pdo->exec('SET FOREIGN_KEY_CHECKS=1');
|
||||
|
||||
// Verifica org rimaste
|
||||
$orgCount = $pdo->query('SELECT COUNT(*) FROM organizations')->fetchColumn();
|
||||
simLog("Auto-reset completato — {$deleted} record rimossi, {$orgCount} org base mantenute", 'ok');
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
// FASE 0 — Health Check
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
@@ -623,6 +712,15 @@ if ($code === 200 && !empty($hRes['status'])) {
|
||||
warn("API health check degradato (HTTP $code) — continuo comunque");
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
// FASE 0b — Auto-Reset Dati Demo Precedenti
|
||||
// (skip se si lancia solo SIM-06 che è indipendente)
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
if ($SIM_FILTER !== 'SIM06') {
|
||||
simPhase(0, 'Auto-Reset Dati Demo Precedenti');
|
||||
autoResetDemo();
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
// SIM-01→05 — skip se si esegue solo SIM-06
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user