environmentId = $environmentId; $this->authorizeEnvironment(); } public function table(Table $table): Table { return $table ->heading('Resource instances') ->deferLoading(false) ->query(fn (): Builder => app(CoverageV2ReadinessReadModel::class)->resourceInstanceQuery($this->environment())) ->searchable() ->searchPlaceholder('Search resources') ->paginated(TablePaginationProfiles::productSurface()) ->columns([ TextColumn::make('source_display_name') ->label('Resource') ->searchable() ->sortable() ->description(fn (TenantConfigurationResource $record): string => (string) $record->canonical_resource_key) ->limit(48) ->tooltip(fn (TenantConfigurationResource $record): string => (string) ($record->source_display_name ?: $record->canonical_resource_key)) ->action($this->inspectAction()), TextColumn::make('resourceType.display_name') ->label('Resource type') ->searchable() ->sortable() ->description(fn (TenantConfigurationResource $record): string => (string) $record->canonical_type) ->wrap(), TextColumn::make('providerConnection.display_name') ->label('Provider connection') ->sortable() ->placeholder('Unassigned provider connection') ->limit(32) ->tooltip(fn (?string $state): ?string => filled($state) ? $state : null) ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('coverage_level') ->label('Coverage level') ->state(fn (TenantConfigurationResource $record): ?string => $record->latestEvidence?->coverage_level?->value) ->badge() ->placeholder('Not captured') ->formatStateUsing(BadgeRenderer::label(BadgeDomain::CoverageV2CoverageLevel)) ->color(BadgeRenderer::color(BadgeDomain::CoverageV2CoverageLevel)) ->icon(BadgeRenderer::icon(BadgeDomain::CoverageV2CoverageLevel)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::CoverageV2CoverageLevel)), TextColumn::make('latest_evidence_state') ->label('Evidence state') ->badge() ->sortable() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::CoverageV2EvidenceState)) ->color(BadgeRenderer::color(BadgeDomain::CoverageV2EvidenceState)) ->icon(BadgeRenderer::icon(BadgeDomain::CoverageV2EvidenceState)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::CoverageV2EvidenceState)), TextColumn::make('latest_identity_state') ->label('Identity state') ->badge() ->sortable() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::CoverageV2IdentityState)) ->color(BadgeRenderer::color(BadgeDomain::CoverageV2IdentityState)) ->icon(BadgeRenderer::icon(BadgeDomain::CoverageV2IdentityState)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::CoverageV2IdentityState)), TextColumn::make('latest_claim_state') ->label('Claim state') ->badge() ->sortable() ->formatStateUsing(BadgeRenderer::label(BadgeDomain::CoverageV2ClaimState)) ->color(BadgeRenderer::color(BadgeDomain::CoverageV2ClaimState)) ->icon(BadgeRenderer::icon(BadgeDomain::CoverageV2ClaimState)) ->iconColor(BadgeRenderer::iconColor(BadgeDomain::CoverageV2ClaimState)), TextColumn::make('latest_captured_at') ->label('Last captured') ->dateTime() ->sortable() ->placeholder('Not captured'), TextColumn::make('latest_payload_hash') ->label('Evidence hash') ->state(fn (TenantConfigurationResource $record): ?string => $record->latestEvidence?->payload_hash ?: $record->latest_payload_hash) ->copyable() ->limit(16) ->fontFamily(FontFamily::Mono) ->placeholder('No hash') ->toggleable(isToggledHiddenByDefault: true), ]) ->filters([ SelectFilter::make('resource_type_id') ->label('Resource type') ->options(fn (): array => \App\Models\TenantConfigurationResourceType::query() ->active() ->orderBy('display_name') ->pluck('display_name', 'id') ->mapWithKeys(fn (string $label, int|string $id): array => [(string) $id => $label]) ->all()), SelectFilter::make('provider_connection_id') ->label('Provider connection') ->options(fn (): array => app(CoverageV2ReadinessReadModel::class)->providerConnectionOptions($this->environment())), SelectFilter::make('coverage_level') ->label('Coverage level') ->options(CoverageV2ReadinessReadModel::coverageLevelOptions()) ->query(fn (Builder $query, array $data): Builder => filled($data['value'] ?? null) ? $query->whereHas('latestEvidence', fn (Builder $latestEvidence): Builder => $latestEvidence->where('coverage_level', $data['value'])) : $query), SelectFilter::make('latest_evidence_state') ->label('Evidence state') ->options(CoverageV2ReadinessReadModel::evidenceStateOptions()), SelectFilter::make('latest_identity_state') ->label('Identity state') ->options(CoverageV2ReadinessReadModel::identityStateOptions()), SelectFilter::make('latest_claim_state') ->label('Claim state') ->options(CoverageV2ReadinessReadModel::claimStateOptions()), SelectFilter::make('source_class') ->label('Source class') ->options(CoverageV2ReadinessReadModel::sourceClassOptions()), ]) ->recordUrl(null) ->bulkActions([]) ->emptyStateHeading('No captured Coverage v2 resources') ->emptyStateDescription('No Coverage v2 resource rows match this environment and provider scope. Capture prerequisites must be satisfied before this page can support activation-readiness review.') ->emptyStateIcon('heroicon-o-shield-exclamation'); } private function environment(): ManagedEnvironment { $environment = ManagedEnvironment::query() ->whereKey($this->environmentId) ->first(); if (! $environment instanceof ManagedEnvironment) { abort(404); } return $environment; } private function authorizeEnvironment(): void { $environment = $this->environment(); $user = auth()->user(); if (! $user instanceof User) { abort(403); } $decision = app(ManagedEnvironmentAccessScopeResolver::class) ->decision($user, $environment, Capabilities::EVIDENCE_VIEW); if (! $decision->allowed()) { abort($decision->denialHttpStatus ?? 403); } } private function inspectAction(): Action { return Action::make('inspect') ->label('Inspect') ->icon('heroicon-o-eye') ->color('gray') ->slideOver() ->modalSubmitAction(false) ->modalCancelActionLabel('Close') ->modalHeading(fn (TenantConfigurationResource $record): string => (string) ($record->source_display_name ?: $record->canonical_resource_key)) ->modalContent(fn (TenantConfigurationResource $record): View => view('filament.modals.tenant-configuration.coverage-v2-resource-inspect', [ 'details' => app(CoverageV2ReadinessReadModel::class)->inspectDetails($record, $this->environment(), auth()->user()), ])); } }