heading('Recent Drift Findings') ->query($this->getQuery()) ->poll(fn (): ?string => ($tenant instanceof Tenant) && ActiveRuns::existForTenant($tenant) ? '10s' : null) ->defaultSort('created_at', 'desc') ->paginated(\App\Support\Filament\TablePaginationProfiles::widget()) ->columns([ TextColumn::make('short_id') ->label('ID') ->state(fn (Finding $record): string => '#'.$record->getKey()) ->copyable() ->copyableState(fn (Finding $record): string => (string) $record->getKey()), TextColumn::make('subject_display_name') ->label('Subject') ->placeholder('—') ->limit(40) ->formatStateUsing(function (?string $state, Finding $record): ?string { if (is_string($state) && trim($state) !== '') { return $state; } $fallback = Arr::get($record->evidence_jsonb ?? [], 'display_name'); $fallback = is_string($fallback) ? trim($fallback) : null; return $fallback !== '' ? $fallback : null; }) ->description(function (Finding $record): ?string { if (Arr::get($record->evidence_jsonb ?? [], 'summary.kind') !== 'rbac_role_definition') { return null; } return __('findings.drift.rbac_role_definition'); }) ->tooltip(function (Finding $record): ?string { $displayName = $record->subject_display_name; if (is_string($displayName) && trim($displayName) !== '') { return $displayName; } $fallback = Arr::get($record->evidence_jsonb ?? [], 'display_name'); return is_string($fallback) && trim($fallback) !== '' ? trim($fallback) : null; }), TextColumn::make('severity') ->badge() ->sortable() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::FindingSeverity)) ->color(BadgeRenderer::color(BadgeDomain::FindingSeverity)) ->icon(BadgeRenderer::icon(BadgeDomain::FindingSeverity)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::FindingSeverity)), TextColumn::make('status') ->badge() ->sortable() ->toggleable(isToggledHiddenByDefault: true) ->formatStateUsing(BadgeRenderer::label(BadgeDomain::FindingStatus)) ->color(BadgeRenderer::color(BadgeDomain::FindingStatus)) ->icon(BadgeRenderer::icon(BadgeDomain::FindingStatus)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::FindingStatus)), TextColumn::make('created_at') ->label('Created') ->sortable() ->since(), ]) ->recordUrl(fn (Finding $record): ?string => $tenant instanceof Tenant ? FindingResource::getUrl('view', ['record' => $record], tenant: $tenant) : null) ->emptyStateHeading('No drift findings') ->emptyStateDescription('You\'re looking good — no drift findings to review yet.'); } /** * @return Builder */ private function getQuery(): Builder { $tenant = Filament::getTenant(); $tenantId = $tenant instanceof Tenant ? $tenant->getKey() : null; return Finding::query() ->addSelect([ 'subject_display_name' => InventoryItem::query() ->select('display_name') ->whereColumn('inventory_items.tenant_id', 'findings.tenant_id') ->whereColumn('inventory_items.external_id', 'findings.subject_external_id') ->limit(1), ]) ->when($tenantId, fn (Builder $query) => $query->where('tenant_id', $tenantId)) ->where('finding_type', Finding::FINDING_TYPE_DRIFT) ->latest('created_at'); } }