1
0
Files
breadcrumb-the-shire/modules/helpdesk/pages/helpdesk/team-workload-data().php
fs fc98f2684a fix(helpdesk): consolidation fixes from drift/performance/security review
- Fix docblock: getTicketsForTeam() uses PBI_FP_Tickets, not LV
- Process_Stage check now uses isset() guard — FP entity does not
  expose this field, prevents false positives from default 0
- Remove exception message from JSON error response (security)
- Remove dead JS functions: formatAge(), formatDate()
- Remove debug console.error and verbose error display from JS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 20:25:51 +02:00

85 lines
2.3 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\DebitorDetailService;
use MintyPHP\Router;
use MintyPHP\Support\Guard;
Guard::requireLogin();
Guard::requireAbilityOrForbidden(HelpdeskAuthorizationPolicy::ABILITY_TEAM_WORKLOAD);
$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::teamWorkloadKey($tenantScope);
$cacheTtl = DebitorCacheControl::TTL_STANDARD_SECONDS;
$cached = $sessionStore->get($cacheKey);
$tickets = null;
$cacheUsed = false;
if (!$refreshRequested && is_array($cached) && isset($cached['fetched_at']) && (time() - (int) $cached['fetched_at']) < $cacheTtl) {
$tickets = is_array($cached['tickets'] ?? null) ? $cached['tickets'] : [];
$cacheUsed = true;
}
if ($tickets === null) {
if ($refreshRequested) {
$sessionStore->remove($cacheKey);
}
$gateway = app(BcODataGateway::class);
try {
$tickets = $gateway->getTicketsForTeam();
} catch (\Throwable) {
Router::json([
'ok' => false,
'error' => 'Failed to load team workload data',
]);
return;
}
if (!is_array($tickets)) {
$tickets = [];
}
$sessionStore->set($cacheKey, [
'tickets' => $tickets,
'fetched_at' => time(),
]);
}
$dashboard = DebitorDetailService::buildTeamWorkloadDashboard($tickets, $periodDays);
Router::json([
'ok' => true,
'kpis' => $dashboard['kpis'],
'members' => $dashboard['members'],
'meta' => array_merge($dashboard['meta'], [
'cache_used' => $cacheUsed,
'cache_bypassed' => $refreshRequested,
'cache_refreshed' => $refreshRequested,
]),
]);