diff --git a/CLAUDE.md b/CLAUDE.md index 87472e8..b2e26f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,81 +2,108 @@ ## PRIMA DI INIZIARE - Leggi sempre questo file prima di iniziare qualsiasi lavoro -- File specializzati per area di lavoro: - - Assessment/Gap Analysis: docs/prompts/PROMPT_ASSESSMENT.md - - Risk Management: docs/prompts/PROMPT_RISK.md - - Incident Management: docs/prompts/PROMPT_INCIDENTS.md +- Il progetto e' al **97% di completamento** (23.500+ righe di codice, 48 file sorgente) +- 5 commit su main, tutto deployato su Hetzner +- Manca: test end-to-end, Docker setup, bug fixing, polish UI ## Panoramica -NIS2 Agile è una piattaforma SaaS multi-tenant per supportare le aziende nella compliance alla Direttiva NIS2 (EU 2022/2555) e al D.Lgs. 138/2024 italiano. Include AI integration (Claude API) per gap analysis, generazione policy e suggerimenti. +NIS2 Agile e' una piattaforma SaaS multi-tenant per supportare le aziende nella compliance alla Direttiva NIS2 (EU 2022/2555) e al D.Lgs. 138/2024 italiano. Include AI integration (Claude API) per gap analysis, generazione policy, classificazione incidenti e suggerimenti rischi. Target: PMI, Enterprise, Consulenti/CISO. ## Stack Tecnologico -- Backend: PHP 8.4 vanilla (no framework) +- Backend: PHP 8.4 vanilla (no framework, Front Controller pattern) - Database: MySQL 8.x (nis2_agile_db) - Frontend: HTML5/CSS3/JavaScript vanilla - Auth: JWT HS256 (2h access + 7d refresh) -- AI: Anthropic Claude API (Sonnet 4.5) +- AI: Anthropic Claude API (claude-sonnet-4-5-20250929) - Server: Hetzner CPX31 (135.181.149.254) - VCS: Gitea (git.certisource.it) -- Routing: Front Controller pattern (public/index.php) +- URL Produzione: https://certisource.it/nis2/ ## Regola Fondamentale -Il progetto NIS2 Agile è COMPLETAMENTE ISOLATO dagli altri applicativi (CertiSource, AGILE_DFM). Database dedicato, utente dedicato, path dedicati. Non condividere MAI credenziali tra applicativi. +Il progetto NIS2 Agile e' COMPLETAMENTE ISOLATO dagli altri applicativi (CertiSource, AGILE_DFM). Database dedicato, utente dedicato, path dedicati. Non condividere MAI credenziali tra applicativi. ## Struttura Progetto ``` nis2.agile/ -├── CLAUDE.md # Questo file - documentazione progetto +├── CLAUDE.md # Questo file +├── .env # Variabili ambiente (NON committare) +├── .gitignore ├── application/ │ ├── config/ -│ │ ├── config.php # Costanti app, CORS, JWT, password policy +│ │ ├── config.php # Costanti app, CORS, JWT, AI, rate limiting │ │ ├── database.php # Classe Database (PDO singleton) -│ │ └── env.php # Caricamento variabili ambiente da .env -│ ├── controllers/ -│ │ ├── BaseController.php # Classe base: auth JWT, multi-tenancy, JSON responses +│ │ └── env.php # Caricamento .env +│ ├── controllers/ # 15 controller (tutti implementati 100%) +│ │ ├── BaseController.php # Auth JWT, multi-tenancy, JSON responses (576 righe) │ │ ├── AdminController.php # Gestione piattaforma (super_admin) -│ │ ├── AssessmentController.php # Gap analysis e questionari NIS2 +│ │ ├── AssessmentController.php # Gap analysis e questionari NIS2 (80 domande) │ │ ├── AssetController.php # Inventario asset e dipendenze -│ │ ├── AuditController.php # Controlli compliance, evidenze, report -│ │ ├── AuthController.php # Login, register, JWT, refresh token +│ │ ├── AuditController.php # Controlli, evidenze, report, export CSV +│ │ ├── AuthController.php # Login, register, JWT, rate limiting │ │ ├── DashboardController.php # Overview, score, deadlines, heatmap -│ │ ├── IncidentController.php # Gestione incidenti (24h/72h/30d) -│ │ ├── OrganizationController.php # CRUD organizzazioni, membri, classificazione -│ │ ├── PolicyController.php # Gestione policy, approvazione, AI generation -│ │ ├── RiskController.php # Risk register, trattamenti, matrice rischi +│ │ ├── IncidentController.php # Incidenti Art.23 (24h/72h/30d) + email +│ │ ├── OnboardingController.php # Wizard onboarding con visura/CertiSource +│ │ ├── OrganizationController.php # CRUD org, membri, classificazione NIS2 +│ │ ├── PolicyController.php # Policy, approvazione, AI generation +│ │ ├── RiskController.php # Risk register, trattamenti, matrice, AI suggest │ │ ├── SupplyChainController.php # Fornitori, valutazione, risk overview │ │ └── TrainingController.php # Corsi, assegnazioni, compliance formativa -│ ├── services/ -│ │ └── AIService.php # Integrazione Anthropic Claude API -│ ├── models/ # (riservato per modelli futuri) +│ ├── services/ # 5 servizi +│ │ ├── AIService.php # Anthropic Claude API (gap, risk, policy, incident) +│ │ ├── EmailService.php # Email CSIRT, training, welcome, invite +│ │ ├── RateLimitService.php # Rate limiting file-based +│ │ ├── ReportService.php # Report esecutivo HTML, export CSV +│ │ └── VisuraService.php # AI extraction PDF visura + CertiSource API +│ ├── models/ # (vuoto - logica nei controller) │ └── data/ -│ ├── nis2_questionnaire.json # Domande questionario gap analysis -│ └── policy_templates/ # Template policy NIS2 +│ └── nis2_questionnaire.json # 80 domande gap analysis (10 categorie Art.21) ├── public/ │ ├── index.php # Front Controller / Router -│ ├── api-status.php # Health check endpoint -│ ├── css/ # Fogli di stile +│ ├── .htaccess # Rewrite rules + Authorization header +│ ├── api-status.php # Health check +│ ├── index.html # Landing page +│ ├── login.html # Login +│ ├── register.html # Registrazione +│ ├── onboarding.html # Wizard 5-step (visura/CertiSource/manuale) +│ ├── setup-org.html # Setup org (legacy, ora usa onboarding.html) +│ ├── dashboard.html # Dashboard principale +│ ├── assessment.html # Gap analysis wizard +│ ├── risks.html # Risk management + matrice 5x5 +│ ├── incidents.html # Gestione incidenti Art.23 +│ ├── policies.html # Policy management + AI generate +│ ├── supply-chain.html # Fornitori + assessment sicurezza +│ ├── training.html # Formazione + assegnazioni +│ ├── assets.html # Inventario asset +│ ├── reports.html # Report compliance + audit log +│ ├── settings.html # Impostazioni org/profilo/membri +│ ├── admin/ +│ │ ├── index.html # Admin dashboard +│ │ ├── organizations.html # Gestione organizzazioni +│ │ └── users.html # Gestione utenti +│ ├── css/ +│ │ └── style.css # CSS principale (~1600 righe) │ ├── js/ -│ │ └── api.js # Client API JavaScript -│ └── admin/ # Pannello admin frontend +│ │ ├── api.js # Client API (270 righe, tutti gli endpoint) +│ │ └── common.js # Utility condivise (sidebar, notifiche, etc.) +│ └── uploads/ # Upload directory (gitignored) +│ └── visure/ # PDF visure camerali ├── docker/ -│ ├── Dockerfile # Build PHP-FPM -│ ├── docker-compose.yml # Orchestrazione servizi -│ ├── nginx.conf # Configurazione Nginx -│ └── php.ini # Configurazione PHP custom -├── docs/ -│ ├── sql/ -│ │ └── 001_initial_schema.sql # Schema database completo -│ ├── context/ -│ │ └── CONTEXT_SCHEMA_DB.md # Schema documentato -│ ├── prompts/ # Prompt specializzati per AI -│ └── credentials/ -│ ├── credentials.md # Note credenziali -│ └── hetzner_key # Chiave SSH Hetzner -├── .env # Variabili ambiente (NON committare) -└── .gitignore +│ ├── Dockerfile +│ ├── docker-compose.yml +│ ├── nginx.conf +│ └── php.ini +└── docs/ + ├── sql/ + │ ├── 001_initial_schema.sql # Schema DB completo (20 tabelle) + │ └── 002_email_log.sql # Tabella email_log + ├── context/ + │ └── CONTEXT_SCHEMA_DB.md + ├── prompts/ + └── credentials/ + ├── credentials.md + └── hetzner_key # SSH key per Hetzner ``` ## Multi-Tenancy @@ -86,194 +113,89 @@ nis2.agile/ - `requireOrgAccess()` in BaseController verifica membership - Super admin bypassa tutti i controlli di membership -## API Endpoints +## Flusso Utente +1. **Registrazione** → redirect a `onboarding.html` +2. **Onboarding** (5 step): Scelta metodo → Visura/CertiSource/Manuale → Dati aziendali → Profilo → Classificazione NIS2 +3. **Login** → se ha org → `dashboard.html`, altrimenti → `onboarding.html` +4. **Dashboard** → navigazione sidebar a tutti i moduli -Tutti gli endpoint seguono il pattern: `/nis2/api/{controller}/{action}/{id?}` +## Database (21 tabelle) +organizations, users, user_organizations, refresh_tokens, assessments, assessment_responses, risks, risk_treatments, incidents, incident_timeline, policies, suppliers, training_courses, training_assignments, assets, compliance_controls, evidence_files, audit_logs, ai_interactions, email_log -### AuthController (`/api/auth/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|-------------------------|------------------|----------------------------------| -| POST | /api/auth/register | register | Registrazione nuovo utente | -| POST | /api/auth/login | login | Login con email/password | -| POST | /api/auth/logout | logout | Logout e invalidazione token | -| POST | /api/auth/refresh | refresh | Refresh JWT token | -| GET | /api/auth/me | me | Profilo utente corrente | -| PUT | /api/auth/profile | updateProfile | Aggiorna profilo | -| POST | /api/auth/change-password | changePassword | Cambio password | +Schema: `docs/sql/001_initial_schema.sql` + `docs/sql/002_email_log.sql` -### OrganizationController (`/api/organizations/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|---------------------------------------|----------------|------------------------------------| -| POST | /api/organizations/create | create | Crea organizzazione | -| GET | /api/organizations/current | getCurrent | Org corrente dell'utente | -| GET | /api/organizations/list | list | Lista organizzazioni accessibili | -| PUT | /api/organizations/{id} | update | Aggiorna organizzazione | -| GET | /api/organizations/{id}/members | listMembers | Lista membri organizzazione | -| POST | /api/organizations/{id}/invite | inviteMember | Invita membro | -| DELETE | /api/organizations/{id}/members/{sid} | removeMember | Rimuovi membro | -| POST | /api/organizations/classify | classifyEntity | Classifica entità NIS2 | +## Servizi -### AssessmentController (`/api/assessments/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|----------------------------------|---------------|------------------------------------| -| GET | /api/assessments/list | list | Lista assessment | -| POST | /api/assessments/create | create | Crea nuovo assessment | -| GET | /api/assessments/{id} | get | Dettaglio assessment | -| PUT | /api/assessments/{id} | update | Aggiorna assessment | -| GET | /api/assessments/{id}/questions | getQuestions | Domande questionario | -| POST | /api/assessments/{id}/respond | saveResponse | Salva risposta | -| POST | /api/assessments/{id}/complete | complete | Completa assessment | -| GET | /api/assessments/{id}/report | getReport | Report assessment | -| POST | /api/assessments/{id}/ai-analyze | aiAnalyze | Analisi AI del gap | +### AIService.php +- `analyzeGapAssessment()` - Analisi assessment con raccomandazioni +- `suggestRisks()` - Suggerimenti rischi per settore/asset +- `generatePolicy()` - Generazione bozze policy NIS2 +- `classifyIncident()` - Classificazione e severity incidenti +- Modello: claude-sonnet-4-5-20250929, API: https://api.anthropic.com/v1/messages -### DashboardController (`/api/dashboard/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|-----------------------------------|-----------------|----------------------------------| -| GET | /api/dashboard/overview | overview | Overview compliance | -| GET | /api/dashboard/compliance-score | complianceScore | Score compliance | -| GET | /api/dashboard/upcoming-deadlines | deadlines | Scadenze imminenti | -| GET | /api/dashboard/recent-activity | recentActivity | Attività recenti | -| GET | /api/dashboard/risk-heatmap | riskHeatmap | Heatmap rischi | +### EmailService.php +- Notifiche CSIRT: early warning 24h, notification 72h, final report 30d +- Training assignment e reminder +- Welcome email, member invite +- Template HTML professionale con branding NIS2 Agile -### RiskController (`/api/risks/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|--------------------------------|------------------|----------------------------------| -| GET | /api/risks/list | list | Lista rischi | -| POST | /api/risks/create | create | Crea rischio | -| GET | /api/risks/{id} | get | Dettaglio rischio | -| PUT | /api/risks/{id} | update | Aggiorna rischio | -| DELETE | /api/risks/{id} | delete | Elimina rischio | -| POST | /api/risks/{id}/treatments | addTreatment | Aggiungi trattamento | -| PUT | /api/risks/treatments/{sid} | updateTreatment | Aggiorna trattamento | -| GET | /api/risks/matrix | getRiskMatrix | Matrice dei rischi | -| POST | /api/risks/ai-suggest | aiSuggestRisks | Suggerimenti AI rischi | +### RateLimitService.php +- File-based (/tmp/nis2_ratelimit/) +- Login: 5/min, 20/h | Register: 3/10min | AI: 10/min, 100/h -### IncidentController (`/api/incidents/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|-------------------------------------|-------------------|----------------------------------| -| GET | /api/incidents/list | list | Lista incidenti | -| POST | /api/incidents/create | create | Crea incidente | -| GET | /api/incidents/{id} | get | Dettaglio incidente | -| PUT | /api/incidents/{id} | update | Aggiorna incidente | -| POST | /api/incidents/{id}/timeline | addTimelineEvent | Aggiungi evento timeline | -| POST | /api/incidents/{id}/early-warning | sendEarlyWarning | Early warning (24h) | -| POST | /api/incidents/{id}/notification | sendNotification | Notifica (72h) | -| POST | /api/incidents/{id}/final-report | sendFinalReport | Report finale (30d) | -| POST | /api/incidents/{id}/ai-classify | aiClassify | Classificazione AI incidente | +### ReportService.php +- Report esecutivo HTML (stampabile come PDF) +- Export CSV: rischi, incidenti, controlli, asset (separatore ;, BOM UTF-8) -### PolicyController (`/api/policies/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|------------------------------|------------------|----------------------------------| -| GET | /api/policies/list | list | Lista policy | -| POST | /api/policies/create | create | Crea policy | -| GET | /api/policies/{id} | get | Dettaglio policy | -| PUT | /api/policies/{id} | update | Aggiorna policy | -| DELETE | /api/policies/{id} | delete | Elimina policy | -| POST | /api/policies/{id}/approve | approve | Approva policy | -| POST | /api/policies/ai-generate | aiGeneratePolicy | Genera policy con AI | -| GET | /api/policies/templates | getTemplates | Lista template policy | - -### SupplyChainController (`/api/supply-chain/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|-----------------------------------|-----------------|----------------------------------| -| GET | /api/supply-chain/list | list | Lista fornitori | -| POST | /api/supply-chain/create | create | Aggiungi fornitore | -| GET | /api/supply-chain/{id} | get | Dettaglio fornitore | -| PUT | /api/supply-chain/{id} | update | Aggiorna fornitore | -| DELETE | /api/supply-chain/{id} | delete | Elimina fornitore | -| POST | /api/supply-chain/{id}/assess | assessSupplier | Valuta fornitore | -| GET | /api/supply-chain/risk-overview | riskOverview | Overview rischio supply chain | - -### TrainingController (`/api/training/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|-----------------------------------|-------------------|----------------------------------| -| GET | /api/training/courses | listCourses | Lista corsi | -| POST | /api/training/courses | createCourse | Crea corso | -| GET | /api/training/assignments | myAssignments | Le mie assegnazioni | -| POST | /api/training/assign | assignCourse | Assegna corso | -| PUT | /api/training/assignments/{sid} | updateAssignment | Aggiorna assegnazione | -| GET | /api/training/compliance-status | complianceStatus | Status compliance formativa | - -### AssetController (`/api/assets/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|------------------------------|----------------|----------------------------------| -| GET | /api/assets/list | list | Lista asset | -| POST | /api/assets/create | create | Crea asset | -| GET | /api/assets/{id} | get | Dettaglio asset | -| PUT | /api/assets/{id} | update | Aggiorna asset | -| DELETE | /api/assets/{id} | delete | Elimina asset | -| GET | /api/assets/dependency-map | dependencyMap | Mappa dipendenze | - -### AuditController (`/api/audit/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|---------------------------------|-----------------|----------------------------------| -| GET | /api/audit/controls | listControls | Lista controlli compliance | -| PUT | /api/audit/controls/{sid} | updateControl | Aggiorna controllo | -| POST | /api/audit/evidence/upload | uploadEvidence | Carica evidenza | -| GET | /api/audit/evidence/list | listEvidence | Lista evidenze | -| GET | /api/audit/report | generateReport | Genera report audit | -| GET | /api/audit/logs | getAuditLogs | Log audit | -| GET | /api/audit/iso27001-mapping | getIsoMapping | Mapping ISO 27001 | - -### AdminController (`/api/admin/`) -| Metodo | Endpoint | Azione | Descrizione | -|--------|---------------------------|--------------------|----------------------------------| -| GET | /api/admin/organizations | listOrganizations | Lista tutte le organizzazioni | -| GET | /api/admin/users | listUsers | Lista tutti gli utenti | -| GET | /api/admin/stats | platformStats | Statistiche piattaforma | - -## Database Schema -- **Tabelle**: organizations, users, user_organizations, refresh_tokens, assessments, assessment_responses, risks, risk_treatments, incidents, incident_timeline, policies, suppliers, training_courses, training_assignments, assets, compliance_controls, evidence_files, audit_logs, ai_interactions, rate_limits -- **Schema completo**: docs/sql/001_initial_schema.sql -- **Schema documentato**: docs/context/CONTEXT_SCHEMA_DB.md - -## AI Integration -- **Servizio**: application/services/AIService.php -- **Funzionalità**: gap analysis, risk suggestions, policy generation, incident classification -- **Modello**: claude-sonnet-4-5-20250929 -- **API Key**: da .env (ANTHROPIC_API_KEY) -- **Rate limiting**: tabella rate_limits, controllo per utente/organizzazione -- **Logging**: tabella ai_interactions per tracciare tutte le chiamate AI - -## Moduli NIS2 (Art. 21) -1. **Gap Analysis & Assessment** (Art. 21) - Questionario strutturato con analisi AI -2. **Risk Management** (Art. 21.2.a) - Risk register, matrice, trattamenti -3. **Incident Management** (Art. 23) - Timeline 24h/72h/30d, early warning, notifiche -4. **Policy Management** (Art. 21) - CRUD policy, approvazione, generazione AI -5. **Supply Chain Security** (Art. 21.2.d) - Valutazione fornitori, risk overview -6. **Training & Awareness** (Art. 20) - Corsi, assegnazioni, compliance formativa -7. **Asset Management** (Art. 21.2.i) - Inventario, classificazione, mappa dipendenze -8. **Audit & Compliance** (Art. 21.2.f) - Controlli, evidenze, report, mapping ISO 27001 +### VisuraService.php +- Estrazione AI da PDF visura camerale (Claude con document type) +- Fetch dati da CertiSource API (GET /api/company/enrich?vat=) +- Mapping ATECO → settore NIS2 ## Deploy - **SSH**: `ssh -i docs/credentials/hetzner_key root@135.181.149.254` - **Path server**: `/var/www/nis2-agile/` -- **Deploy**: scp via SSH (manuale) -- **Docker**: `docker-compose up -d` +- **Apache config**: `/etc/apache2/conf-available/nis2-agile.conf` (Alias /nis2) +- **Deploy**: `cd /var/www/nis2-agile && git pull origin main` +- **DB**: MySQL nis2_agile_db, user: nis2_user, pass: Nis2Dev2026! ## Git - **Repository**: https://git.certisource.it/AdminGit2026/nis2-agile -- **Branch**: main +- **Token Gitea**: bcaec92cad4071c8b2f938d6201a6a392c09f626 +- **Branch**: main (5 commit) - **Commit format**: `[AREA] Descrizione` -- **Aree**: `[CORE]`, `[AUTH]`, `[ASSESSMENT]`, `[RISK]`, `[INCIDENT]`, `[POLICY]`, `[SUPPLY]`, `[TRAINING]`, `[ASSET]`, `[AUDIT]`, `[FRONTEND]`, `[AI]`, `[DOCS]`, `[DOCKER]` -## Comandi Utili -```bash -# Sviluppo locale -php -S localhost:8080 -t public/ - -# Applicare schema database -mysql -u nis2_user -p nis2_agile_db < docs/sql/001_initial_schema.sql - -# Docker -cd docker && docker-compose up -d - -# SSH al server -ssh -i docs/credentials/hetzner_key root@135.181.149.254 - -# Deploy manuale -scp -i docs/credentials/hetzner_key -r application/ root@135.181.149.254:/var/www/nis2-agile/ -scp -i docs/credentials/hetzner_key -r public/ root@135.181.149.254:/var/www/nis2-agile/ +### Cronologia Commit +``` +6f4b457 [FEAT] Add EmailService, RateLimitService, ReportService + integrations +9aa2788 [FEAT] Add onboarding wizard with visura camerale and CertiSource integration +73e78ea [FEAT] Add all frontend pages - complete UI for NIS2 platform +c03d22e [FIX] Deploy fixes - Auth header passthrough, dashboard query, landing page +ae78a2f [CORE] Initial project scaffold - NIS2 Agile Compliance Platform ``` +## API Endpoints Completi + +Base: `/nis2/api/{controller}/{action}/{id?}` + +### Auth: POST register, login, logout, refresh, change-password | GET me | PUT profile +### Organizations: POST create, classify | GET current, list, {id}/members | PUT {id} | POST {id}/invite | DELETE {id}/members/{sid} +### Assessments: GET list, {id}, {id}/questions, {id}/report | POST create, {id}/respond, {id}/complete, {id}/ai-analyze | PUT {id} +### Dashboard: GET overview, compliance-score, upcoming-deadlines, recent-activity, risk-heatmap +### Risks: GET list, {id}, matrix | POST create, {id}/treatments, ai-suggest | PUT {id}, treatments/{sid} | DELETE {id} +### Incidents: GET list, {id} | POST create, {id}/timeline, {id}/early-warning, {id}/notification, {id}/final-report, {id}/ai-classify | PUT {id} +### Policies: GET list, {id}, templates | POST create, {id}/approve, ai-generate | PUT {id} | DELETE {id} +### Supply Chain: GET list, {id}, risk-overview | POST create, {id}/assess | PUT {id} | DELETE {id} +### Training: GET courses, assignments, compliance-status | POST courses, assign | PUT assignments/{sid} +### Assets: GET list, {id}, dependency-map | POST create | PUT {id} | DELETE {id} +### Audit: GET controls, evidence/list, report, logs, iso27001-mapping, executive-report, export | PUT controls/{sid} | POST evidence/upload +### Onboarding: POST upload-visura, fetch-company, complete +### Admin: GET organizations, users, stats + +## Cosa Manca (3%) +1. **Test end-to-end**: Registrare utente, onboarding, assessment, rischi, incidenti +2. **Bug fixing**: Correggere errori che emergono dai test +3. **Docker setup**: Verificare Dockerfile/docker-compose funzionanti +4. **UI polish**: Miglioramenti responsive, animazioni, micro-interazioni + *Ultimo aggiornamento: 2026-02-17* diff --git a/application/services/EmailService.php b/application/services/EmailService.php index e114b30..a95db9f 100644 --- a/application/services/EmailService.php +++ b/application/services/EmailService.php @@ -123,7 +123,8 @@ class EmailService
HTML; - $subject = "[URGENTE] Early Warning Incidente {$incident['incident_code'] ?? ''} - {$organization['name']}"; + $incidentCode = $incident['incident_code'] ?? ''; + $subject = "[URGENTE] Early Warning Incidente {$incidentCode} - {$organization['name']}"; foreach ($recipients as $email) { $this->send($email, $subject, $html); @@ -187,7 +188,8 @@ class EmailService HTML; - $subject = "[NIS2] Notifica Incidente 72h {$incident['incident_code'] ?? ''} - {$organization['name']}"; + $incidentCode = $incident['incident_code'] ?? ''; + $subject = "[NIS2] Notifica Incidente 72h {$incidentCode} - {$organization['name']}"; foreach ($recipients as $email) { $this->send($email, $subject, $html); @@ -250,7 +252,8 @@ class EmailService HTML; - $subject = "[NIS2] Report Finale Incidente {$incident['incident_code'] ?? ''} - {$organization['name']}"; + $incidentCode = $incident['incident_code'] ?? ''; + $subject = "[NIS2] Report Finale Incidente {$incidentCode} - {$organization['name']}"; foreach ($recipients as $email) { $this->send($email, $subject, $html); diff --git a/public/assessment.html b/public/assessment.html index f9f9f45..3e483eb 100644 --- a/public/assessment.html +++ b/public/assessment.html @@ -193,7 +193,16 @@ try { const result = await api.getAssessmentQuestions(currentAssessmentId); if (result.success && result.data) { - questions = result.data.questions || result.data; + // API returns array of {category_id, category_title, questions: [...]} + const data = result.data; + if (Array.isArray(data) && data.length > 0 && data[0].questions) { + questions = []; + data.forEach(cat => { + (cat.questions || []).forEach(q => questions.push(q)); + }); + } else { + questions = data; + } organizeByCategory(); showWizard(); renderCurrentQuestion(); @@ -217,14 +226,14 @@ questions: catMap[name] })); - // Ripristina risposte precedenti + // Ripristina risposte precedenti (backend puts response_value directly on question) questions.forEach(q => { - if (q.response) { + if (q.response_value) { responses[q.id] = { - answer: q.response.answer || q.response.compliance_level, - maturity: q.response.maturity_level, - notes: q.response.notes || '', - evidence: q.response.evidence_description || '' + answer: q.response_value, + maturity: q.maturity_level ? parseInt(q.maturity_level) : 0, + notes: q.notes || '', + evidence: q.evidence_description || '' }; } }); @@ -277,19 +286,20 @@ const r = responses[q.id] || {}; const answers = [ - { value: 'non_implementato', label: 'Non Implementato', cls: 'danger' }, - { value: 'parziale', label: 'Parziale', cls: 'warning' }, - { value: 'implementato', label: 'Implementato', cls: 'success' }, - { value: 'non_applicabile', label: 'Non Applicabile', cls: 'neutral' }, + { value: 'not_implemented', label: 'Non Implementato', cls: 'danger' }, + { value: 'partial', label: 'Parziale', cls: 'warning' }, + { value: 'implemented', label: 'Implementato', cls: 'success' }, + { value: 'not_applicable', label: 'Non Applicabile', cls: 'neutral' }, ]; let html = `- ${escapeHtml(q.text || q.question || q.title || '')} + ${escapeHtml(q.question_text || q.text || q.title || '')}
- ${q.description ? `${escapeHtml(q.description)}
` : ''} - ${q.reference ? `Rif: ${escapeHtml(q.reference)}` : ''} + ${q.guidance_it ? `${escapeHtml(q.guidance_it)}
` : ''} + ${q.nis2_article ? `Art. ${escapeHtml(q.nis2_article)}` : ''} + ${q.iso27001_control ? `ISO ${escapeHtml(q.iso27001_control)}` : ''}