forked from fa/breadcrumb-the-shire
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>
87 lines
2.5 KiB
PHP
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,
|
|
]),
|
|
]));
|