[FEAT] Services API, Webhook, Whistleblowing, Normative + integrazioni
Sprint completo — prodotto presentation-ready:
Services API (read-only, API Key + scope):
- GET /api/services/status|compliance-summary|risks-feed|incidents-feed
- GET /api/services/controls-status|assets-critical|suppliers-risk|policies-approved
- GET /api/services/openapi (spec OpenAPI 3.0.3 JSON)
Webhook Outbound (Stripe-like HMAC-SHA256):
- CRUD api_keys + webhook_subscriptions (Settings → 2 nuovi tab)
- WebhookService: retry 3x backoff (0s/5min/30min), delivery log
- Trigger auto in IncidentController, RiskController, PolicyController
- Delivery log, test ping, processRetry
Nuovi moduli:
- WhistleblowingController (Art.32 NIS2): anonimato garantito, timeline, token tracking
- NormativeController: feed NIS2/ACN/DORA con ACK tracciato per audit
Frontend:
- whistleblowing.html: form submit anonimo/firmato + gestione CISO
- normative.html: feed con presa visione documentata + progress bar ACK
- public/docs/api.html: documentazione API dark theme (Swagger-like)
- settings.html: tab API Keys + tab Webhook
- integrations/: guide per lg231, SustainAI, AllRisk, SIEM (widget + codice)
- Sidebar: Segnalazioni + Normative aggiunte a common.js
DB: migration 007 (api_keys, webhook_subscriptions, webhook_deliveries),
008 (whistleblowing_reports + timeline),
009 (normative_updates + normative_ack + seed NIS2/ACN/DORA/ISO)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
3f4b451e2a
commit
86e9bdded2
@@ -7,6 +7,7 @@
|
||||
|
||||
require_once __DIR__ . '/BaseController.php';
|
||||
require_once APP_PATH . '/services/AIService.php';
|
||||
require_once APP_PATH . '/services/WebhookService.php';
|
||||
|
||||
class RiskController extends BaseController
|
||||
{
|
||||
@@ -77,6 +78,23 @@ class RiskController extends BaseController
|
||||
|
||||
$this->logAudit('risk_created', 'risk', $riskId);
|
||||
|
||||
// Dispatch webhook per rischi HIGH/CRITICAL
|
||||
$riskScore = $likelihood * $impact;
|
||||
if ($riskScore >= 12) { // HIGH: 12-16, CRITICAL: >16 (su scala 5x5)
|
||||
try {
|
||||
$riskData = Database::fetchOne('SELECT * FROM risks WHERE id = ?', [$riskId]);
|
||||
$riskLevel = $riskScore >= 20 ? 'critical' : 'high';
|
||||
$riskData['risk_level'] = $riskLevel;
|
||||
(new WebhookService())->dispatch(
|
||||
$this->getCurrentOrgId(),
|
||||
'risk.high_created',
|
||||
WebhookService::riskPayload($riskData, 'created')
|
||||
);
|
||||
} catch (Throwable $e) {
|
||||
error_log('[WEBHOOK] dispatch error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
$this->jsonSuccess(['id' => $riskId], 'Rischio registrato', 201);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user