[FIX] E2E testing - fix router, EmailService, frontend data mapping

Critical fixes discovered during end-to-end testing:

Router (index.php):
- Rewrote route resolution engine to properly handle /{id}/subAction patterns
- All routes like GET /assessments/{id}/questions, POST /incidents/{id}/early-warning,
  GET /organizations/{id}/members now resolve correctly
- Routes with kebab-case sub-actions (early-warning, ai-analyze) now convert to camelCase
- Controller methods receive correct arguments via spread operator

EmailService.php:
- Fix PHP parse error: ?? operator cannot be used inside string interpolation {}
- Extract incident_code to variable before interpolation (3 occurrences)

assessment.html:
- Fix data structure handling: API returns categories with nested questions array
- Fix field names: question_code (not question_id), response_value (not compliance_level)
- Fix answer enum values: not_implemented/partial/implemented (not Italian)
- Fix question text field: question_text (not text/question/title)
- Show NIS2 article and ISO 27001 control references
- Fix response restoration from existing answers

dashboard.html:
- Fix data mapping from overview API response structure
- risks.total instead of open_risks, policies array instead of approved_policies
- Calculate training completion percentage from training object
- Load deadlines/activity from dedicated endpoints (not included in overview)

onboarding.html:
- Fix field name mismatches: annual_turnover_eur, contact_email, contact_phone,
  full_name, phone (matching OnboardingController expected params)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 19:40:26 +01:00
co-authored by Claude Opus 4.6
parent 6f4b457ce0
commit bcc5a2b003
6 changed files with 262 additions and 318 deletions
+8 -12
View File
@@ -1600,27 +1600,23 @@
const cl = wizardState.classification;
const payload = {
// Company data
// Company data (field names match backend OnboardingController)
name: c.name,
vat_number: c.vat_number,
fiscal_code: c.fiscal_code,
address: c.address,
city: c.city,
website: c.website,
company_email: c.email,
company_phone: c.phone,
contact_email: c.email,
contact_phone: c.phone,
sector: c.sector,
employee_count: parseInt(c.employee_count) || 0,
annual_turnover: parseInt(c.annual_turnover) || 0,
annual_turnover_eur: parseInt(c.annual_turnover) || 0,
// Profile data
user_full_name: p.full_name,
user_role: p.role,
user_phone: p.phone,
// Classification
classification: cl ? cl.classification : null,
classification_label: cl ? cl.label : null,
// Method used
data_source: wizardState.method
full_name: p.full_name,
phone: p.phone,
// Country
country: 'IT',
};
try {