*/ protected function getStats(): array { $tenant = Filament::getTenant(); if (! $tenant instanceof Tenant) { return $this->emptyStats(); } $tenantId = (int) $tenant->getKey(); $backupHealth = $this->backupHealthAssessment($tenant); $backupHealthAction = $this->resolveBackupHealthAction($tenant, $backupHealth->primaryActionTarget); $openDriftFindings = (int) Finding::query() ->where('tenant_id', $tenantId) ->openDrift() ->count(); $highSeverityActiveFindings = (int) Finding::query() ->where('tenant_id', $tenantId) ->highSeverityActive() ->count(); $activeRuns = (int) OperationRun::query() ->where('tenant_id', $tenantId) ->healthyActive() ->count(); $staleActiveRuns = (int) OperationRun::query() ->where('tenant_id', $tenantId) ->activeStaleAttention() ->count(); $terminalFollowUpRuns = (int) OperationRun::query() ->where('tenant_id', $tenantId) ->terminalFollowUp() ->count(); $openDriftUrl = $openDriftFindings > 0 ? $this->findingsUrl($tenant, [ 'tab' => 'needs_action', 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]) : null; $highSeverityUrl = $highSeverityActiveFindings > 0 ? $this->findingsUrl($tenant, [ 'tab' => 'needs_action', 'high_severity' => 1, ]) : null; $findingsHelperText = $this->findingsHelperText($tenant); return [ Stat::make('Backup posture', Str::headline($backupHealth->posture)) ->description($this->backupHealthDescription($backupHealth, $backupHealthAction['helperText'])) ->color($backupHealth->tone()) ->url($backupHealthAction['actionUrl']), Stat::make('Open drift findings', $openDriftFindings) ->description($openDriftUrl === null && $openDriftFindings > 0 ? $findingsHelperText : 'active drift workflow items') ->color($openDriftFindings > 0 ? 'warning' : 'gray') ->url($openDriftUrl), Stat::make('High severity active findings', $highSeverityActiveFindings) ->description($highSeverityUrl === null && $highSeverityActiveFindings > 0 ? $findingsHelperText : 'high or critical findings needing review') ->color($highSeverityActiveFindings > 0 ? 'danger' : 'gray') ->url($highSeverityUrl), Stat::make('Active operations', $activeRuns) ->description('healthy queued or running tenant work') ->color($activeRuns > 0 ? 'info' : 'gray') ->url($activeRuns > 0 ? OperationRunLinks::index($tenant, activeTab: 'active') : null), Stat::make('Likely stale operations', $staleActiveRuns) ->description('queued or running past the lifecycle window') ->color($staleActiveRuns > 0 ? 'warning' : 'gray') ->url($staleActiveRuns > 0 ? OperationRunLinks::index( $tenant, activeTab: OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, problemClass: OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION, ) : null), Stat::make('Terminal follow-up operations', $terminalFollowUpRuns) ->description('blocked, partial, failed, or auto-reconciled runs') ->color($terminalFollowUpRuns > 0 ? 'danger' : 'gray') ->url($terminalFollowUpRuns > 0 ? OperationRunLinks::index( $tenant, activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP, ) : null), ]; } /** * @return array */ private function emptyStats(): array { return [ Stat::make('Backup posture', '—'), Stat::make('Open drift findings', 0), Stat::make('High severity active findings', 0), Stat::make('Active operations', 0), Stat::make('Likely stale operations', 0), Stat::make('Terminal follow-up operations', 0), ]; } /** * @param array $parameters */ private function findingsUrl(Tenant $tenant, array $parameters): ?string { if (! $this->canOpenFindings($tenant)) { return null; } return FindingResource::getUrl('index', $parameters, panel: 'tenant', tenant: $tenant); } private function findingsHelperText(Tenant $tenant): string { return $this->canOpenFindings($tenant) ? 'Open findings' : UiTooltips::INSUFFICIENT_PERMISSION; } private function canOpenFindings(Tenant $tenant): bool { $user = auth()->user(); return $user instanceof User && $user->canAccessTenant($tenant) && $user->can(Capabilities::TENANT_FINDINGS_VIEW, $tenant); } private function backupHealthAssessment(Tenant $tenant): TenantBackupHealthAssessment { /** @var TenantBackupHealthResolver $resolver */ $resolver = app(TenantBackupHealthResolver::class); return $resolver->assess($tenant); } /** * @return array{actionUrl: string|null, helperText: string|null} */ private function resolveBackupHealthAction(Tenant $tenant, ?BackupHealthActionTarget $target): array { if (! $target instanceof BackupHealthActionTarget) { return [ 'actionUrl' => null, 'helperText' => null, ]; } if (! $this->canOpenBackupSurfaces($tenant)) { return [ 'actionUrl' => null, 'helperText' => UiTooltips::INSUFFICIENT_PERMISSION, ]; } return match ($target->surface) { BackupHealthActionTarget::SURFACE_BACKUP_SETS_INDEX => [ 'actionUrl' => BackupSetResource::getUrl('index', [ 'backup_health_reason' => $target->reason, ], panel: 'tenant', tenant: $tenant), 'helperText' => null, ], BackupHealthActionTarget::SURFACE_BACKUP_SCHEDULES_INDEX => [ 'actionUrl' => BackupScheduleResource::getUrl('index', [ 'backup_health_reason' => $target->reason, ], panel: 'tenant', tenant: $tenant), 'helperText' => null, ], BackupHealthActionTarget::SURFACE_BACKUP_SET_VIEW => $this->resolveBackupSetAction($tenant, $target), default => [ 'actionUrl' => null, 'helperText' => null, ], }; } /** * @return array{actionUrl: string|null, helperText: string|null} */ private function resolveBackupSetAction(Tenant $tenant, BackupHealthActionTarget $target): array { if (! is_numeric($target->recordId)) { return [ 'actionUrl' => BackupSetResource::getUrl('index', [ 'backup_health_reason' => $target->reason, ], panel: 'tenant', tenant: $tenant), 'helperText' => 'The latest backup detail is no longer available.', ]; } try { BackupSetResource::resolveScopedRecordOrFail($target->recordId); return [ 'actionUrl' => BackupSetResource::getUrl('view', [ 'record' => $target->recordId, 'backup_health_reason' => $target->reason, ], panel: 'tenant', tenant: $tenant), 'helperText' => null, ]; } catch (ModelNotFoundException) { return [ 'actionUrl' => BackupSetResource::getUrl('index', [ 'backup_health_reason' => $target->reason, ], panel: 'tenant', tenant: $tenant), 'helperText' => 'The latest backup detail is no longer available.', ]; } } private function backupHealthDescription(TenantBackupHealthAssessment $assessment, ?string $helperText): string { $description = $assessment->supportingMessage ?? $assessment->headline; if ($helperText === null) { return $description; } return trim($description.' '.$helperText); } private function canOpenBackupSurfaces(Tenant $tenant): bool { $user = auth()->user(); return $user instanceof User && $user->canAccessTenant($tenant) && $user->can(Capabilities::TENANT_VIEW, $tenant); } }