1
0
Files
breadcrumb-the-shire/modules/helpdesk/pages/helpdesk/risk-radar-data().php
fs cacd1fb6d1 feat(helpdesk): refactor multi-tenant BC settings and risk radar improvements
Restructure helpdesk tenant settings into per-connection config with
improved token handling. Update risk radar data endpoint and UI.
Clean up ImageUploadTrait and update architecture contract tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 22:22:17 +02:00

87 lines
2.5 KiB
PHP

<?php
use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Module\Helpdesk\HelpdeskAuthorizationPolicy;
use MintyPHP\Module\Helpdesk\Service\BcODataGateway;
use MintyPHP\Module\Helpdesk\Service\DebitorCacheControl;
use MintyPHP\Module\Helpdesk\Service\RiskRadarService;
use MintyPHP\Router;
use MintyPHP\Support\Guard;
Guard::requireLogin();
Guard::requireAbilityOrForbidden(HelpdeskAuthorizationPolicy::ABILITY_RISK_RADAR);
$request = requestInput();
if ($request->method() !== 'GET') {
http_response_code(405);
Router::json(['ok' => false, 'error' => 'method_not_allowed']);
return;
}
$periodDays = (int) $request->query('periodDays', '90');
$refreshRequested = DebitorCacheControl::parseRefreshFlag($request->query('refresh', ''));
$allowedPeriods = [30, 90, 180, 365];
if (!in_array($periodDays, $allowedPeriods, true)) {
$periodDays = 90;
}
$sessionStore = app(SessionStoreInterface::class);
$session = $sessionStore->all();
$tenantScope = DebitorCacheControl::resolveTenantScope($session);
$cacheKey = DebitorCacheControl::riskRadarKey($tenantScope, $periodDays);
$cacheTtl = DebitorCacheControl::TTL_STANDARD_SECONDS;
$cached = $sessionStore->get($cacheKey);
$cacheUsed = false;
if (!$refreshRequested && is_array($cached) && isset($cached['fetched_at']) && (time() - (int) $cached['fetched_at']) < $cacheTtl) {
$radar = is_array($cached['radar'] ?? null) ? $cached['radar'] : null;
if ($radar !== null) {
$radar['meta']['cache_used'] = true;
Router::json(array_merge(['ok' => true], $radar));
return;
}
}
if ($refreshRequested) {
$sessionStore->remove($cacheKey);
}
$gateway = app(BcODataGateway::class);
try {
$ticketData = $gateway->getTicketsForRiskRadar($periodDays);
} catch (\Throwable) {
Router::json(['ok' => false, 'error' => 'Failed to load ticket data']);
return;
}
$tickets = $ticketData['tickets'] ?? [];
$truncated = (bool) ($ticketData['truncated'] ?? false);
// Load escalation definitions (cached separately with 30min TTL)
$escalationDefs = [];
try {
$escalationDefs = $gateway->getEscalationDefinitions();
} catch (\Throwable) {
// Continue without — SLA dimension will score 0
}
$radar = RiskRadarService::buildRiskRadar($tickets, $escalationDefs, $periodDays, $truncated);
$sessionStore->set($cacheKey, [
'radar' => $radar,
'fetched_at' => time(),
]);
Router::json(array_merge(['ok' => true], $radar, [
'meta' => array_merge($radar['meta'], [
'cache_used' => false,
'cache_bypassed' => $refreshRequested,
]),
]));