[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:
+18
-16
@@ -150,28 +150,30 @@
|
||||
const data = result.data;
|
||||
|
||||
// Compliance gauge
|
||||
const score = data.compliance_score != null ? data.compliance_score : 0;
|
||||
const score = data.compliance_score != null ? Math.round(data.compliance_score) : 0;
|
||||
document.getElementById('compliance-gauge').innerHTML = renderScoreGauge(score, 180);
|
||||
|
||||
// Stats
|
||||
document.getElementById('stat-risks').textContent = data.open_risks != null ? data.open_risks : 0;
|
||||
document.getElementById('stat-incidents').textContent = data.active_incidents != null ? data.active_incidents : 0;
|
||||
document.getElementById('stat-policies').textContent = data.approved_policies != null ? data.approved_policies : 0;
|
||||
document.getElementById('stat-training').textContent = (data.training_completion != null ? data.training_completion : 0) + '%';
|
||||
// Stats - map backend response structure to UI
|
||||
const openRisks = data.risks ? (parseInt(data.risks.total) || 0) : 0;
|
||||
const activeIncidents = data.active_incidents || 0;
|
||||
const approvedPolicies = Array.isArray(data.policies)
|
||||
? data.policies.reduce((sum, p) => p.status === 'approved' || p.status === 'published' ? sum + parseInt(p.count) : sum, 0)
|
||||
: 0;
|
||||
const trainingTotal = data.training ? (parseInt(data.training.total) || 0) : 0;
|
||||
const trainingCompleted = data.training ? (parseInt(data.training.completed) || 0) : 0;
|
||||
const trainingPct = trainingTotal > 0 ? Math.round((trainingCompleted / trainingTotal) * 100) : 0;
|
||||
|
||||
// Scadenze
|
||||
renderDeadlines(data.upcoming_deadlines || []);
|
||||
|
||||
// Attivita'
|
||||
renderActivity(data.recent_activity || []);
|
||||
} else {
|
||||
// Fallback: prova endpoint singoli
|
||||
loadIndividualData();
|
||||
document.getElementById('stat-risks').textContent = openRisks;
|
||||
document.getElementById('stat-incidents').textContent = activeIncidents;
|
||||
document.getElementById('stat-policies').textContent = approvedPolicies;
|
||||
document.getElementById('stat-training').textContent = trainingPct + '%';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Dashboard load error:', err);
|
||||
loadIndividualData();
|
||||
}
|
||||
|
||||
// Always load deadlines and activity from dedicated endpoints
|
||||
loadIndividualData();
|
||||
}
|
||||
|
||||
async function loadIndividualData() {
|
||||
@@ -179,7 +181,7 @@
|
||||
try {
|
||||
const scoreRes = await api.getComplianceScore();
|
||||
if (scoreRes.success && scoreRes.data) {
|
||||
const score = scoreRes.data.score || scoreRes.data.compliance_score || 0;
|
||||
const score = scoreRes.data.avg_implementation || scoreRes.data.score || 0;
|
||||
document.getElementById('compliance-gauge').innerHTML = renderScoreGauge(score, 180);
|
||||
} else {
|
||||
document.getElementById('compliance-gauge').innerHTML = renderScoreGauge(0, 180);
|
||||
|
||||
Reference in New Issue
Block a user