[FEAT] Add onboarding wizard with visura camerale and CertiSource integration

- New 5-step onboarding wizard (onboarding.html) replacing setup-org.html
- Step 1: Choose data source (Upload Visura / CertiSource / Manual)
- Step 2: PDF upload with AI extraction or CertiSource P.IVA lookup
- Step 3: Verify/complete company data with NIS2 sector mapping
- Step 4: User profile completion
- Step 5: NIS2 classification (Essential/Important) with summary
- OnboardingController with upload-visura, fetch-company, complete endpoints
- VisuraService with Claude AI PDF extraction and ATECO-to-NIS2 mapping
- CertiSource API integration for automatic company data retrieval
- Updated login/register redirects to point to new onboarding wizard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 19:01:34 +01:00
co-authored by Claude Opus 4.6
parent 73e78ea6b4
commit 9aa2788c68
7 changed files with 2337 additions and 2 deletions
+8
View File
@@ -97,6 +97,7 @@ $controllerMap = [
'assets' => 'AssetController',
'audit' => 'AuditController',
'admin' => 'AdminController',
'onboarding' => 'OnboardingController',
];
if (!isset($controllerMap[$controllerName])) {
@@ -265,6 +266,13 @@ $actionMap = [
'GET:users' => 'listUsers',
'GET:stats' => 'platformStats',
],
// ── OnboardingController ──────────────────────
'onboarding' => [
'POST:uploadVisura' => 'uploadVisura',
'POST:fetchCompany' => 'fetchCompany',
'POST:complete' => 'complete',
],
];
// ═══════════════════════════════════════════════════════════════════════════
+24
View File
@@ -238,6 +238,30 @@ class NIS2API {
generateComplianceReport() { return this.get('/audit/report'); }
getAuditLogs(params = {}) { return this.get('/audit/logs?' + new URLSearchParams(params)); }
getIsoMapping() { return this.get('/audit/iso27001-mapping'); }
// ═══════════════════════════════════════════════════════════════════
// Onboarding
// ═══════════════════════════════════════════════════════════════════
async uploadVisura(file) {
const formData = new FormData();
formData.append('visura', file);
const headers = { 'Authorization': 'Bearer ' + this.token };
if (this.orgId) headers['X-Organization-Id'] = this.orgId;
try {
const response = await fetch(this.baseUrl + '/onboarding/upload-visura', {
method: 'POST',
headers,
body: formData,
});
return response.json();
} catch (error) {
return { success: false, message: 'Errore di connessione al server' };
}
}
fetchCompany(vatNumber) { return this.post('/onboarding/fetch-company', { vat_number: vatNumber }); }
completeOnboarding(data) { return this.post('/onboarding/complete', data); }
}
// Singleton globale
+1 -1
View File
@@ -86,7 +86,7 @@
if (result.data.organizations && result.data.organizations.length > 0) {
window.location.href = 'dashboard.html';
} else {
window.location.href = 'setup-org.html';
window.location.href = 'onboarding.html';
}
} else {
errorEl.textContent = result.message || 'Credenziali non valide.';
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -160,7 +160,7 @@
showNotification('Account creato con successo!', 'success');
// Dopo la registrazione, porta al setup organizzazione
setTimeout(() => {
window.location.href = 'setup-org.html';
window.location.href = 'onboarding.html';
}, 500);
} else {
errorEl.textContent = result.message || 'Errore durante la registrazione.';