[FIX] Supply chain: coerenza risk_score + submit atomico (findings review)
Bug #1 (semantica): submitPublicQuestionnaire scriveva risk_score=100-score (rischio) e sovrascriveva criticality, divergendo da assessSupplier (risk_score=compliance, alto=buono). Ora: risk_score=score (compliance), security_requirements_met (soglia 70) settato, criticality NON toccata (è la criticità del fornitore, non l'esito questionario). Bug #4 (atomicita): UPDATE ... WHERE status='sent' + rowCount()==0 -> 409. Due submit concorrenti con lo stesso token non completano due volte. Verificato E2E: submit 201 (score 94 -> risk_score=94, sec_req_met=1, criticality=high invariata), re-submit -> 409. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9d3f8936e1
commit
a3f821122a
@ -261,13 +261,25 @@ class SupplyChainController extends BaseController
|
|||||||
$score = $maxScore > 0 ? (int) round($earned / $maxScore * 100) : 0;
|
$score = $maxScore > 0 ? (int) round($earned / $maxScore * 100) : 0;
|
||||||
$riskLevel = $score >= 80 ? 'low' : ($score >= 60 ? 'medium' : ($score >= 40 ? 'high' : 'critical'));
|
$riskLevel = $score >= 80 ? 'low' : ($score >= 60 ? 'medium' : ($score >= 40 ? 'high' : 'critical'));
|
||||||
|
|
||||||
Database::query(
|
// Completamento ATOMICO: vincola lo UPDATE a status='sent' così due submit
|
||||||
'UPDATE supplier_questionnaires SET status=?, answers=?, score=?, risk_level=?, completed_at=NOW() WHERE id=?',
|
// concorrenti con lo stesso token non possono completare due volte (la seconda
|
||||||
['completed', json_encode($clean, JSON_UNESCAPED_UNICODE), $score, $riskLevel, $q['id']]
|
// tocca 0 righe -> 409). Previene il doppio-submit senza transazione esplicita.
|
||||||
|
$upd = Database::query(
|
||||||
|
'UPDATE supplier_questionnaires SET status=?, answers=?, score=?, risk_level=?, completed_at=NOW()
|
||||||
|
WHERE id=? AND status=?',
|
||||||
|
['completed', json_encode($clean, JSON_UNESCAPED_UNICODE), $score, $riskLevel, $q['id'], 'sent']
|
||||||
);
|
);
|
||||||
|
if ($upd->rowCount() === 0) {
|
||||||
|
$this->jsonError('Questionario gia compilato', 409, 'ALREADY_COMPLETED');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coerenza con assessSupplier: suppliers.risk_score = punteggio di COMPLIANCE
|
||||||
|
// (alto = buono), e security_requirements_met soglia 70. NON sovrascriviamo
|
||||||
|
// suppliers.criticality (è la criticità del fornitore, non l'esito del questionario).
|
||||||
Database::query(
|
Database::query(
|
||||||
'UPDATE suppliers SET risk_score=?, criticality=?, last_assessment_date=CURDATE() WHERE id=? AND organization_id=?',
|
'UPDATE suppliers SET risk_score=?, security_requirements_met=?, last_assessment_date=CURDATE()
|
||||||
[100 - $score, $riskLevel, $q['supplier_id'], $q['organization_id']]
|
WHERE id=? AND organization_id=?',
|
||||||
|
[$score, $score >= 70 ? 1 : 0, $q['supplier_id'], $q['organization_id']]
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->jsonSuccess(['score' => $score, 'risk_level' => $riskLevel], 'Questionario inviato. Grazie.', 201);
|
$this->jsonSuccess(['score' => $score, 'risk_level' => $riskLevel], 'Questionario inviato. Grazie.', 201);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user