From ff0b5889018f8deea724276819fe6778a9a3095b Mon Sep 17 00:00:00 2001 From: Ahmed Darrazi Date: Fri, 5 Jun 2026 00:38:03 +0200 Subject: [PATCH] feat: provider connections resolution guidance v1 (spec 353) Implemented the first version of provider readiness resolution guidance. Added the ProviderReadinessResolutionAdapter, provider readiness guidance card, and updated EnvironmentRequiredPermissions, ProviderConnectionResource, and ListProviderConnections/ViewProviderConnection. Added tests and updated the design coverage matrix. --- .../Pages/EnvironmentRequiredPermissions.php | 66 ++ .../Resources/ProviderConnectionResource.php | 36 +- .../Pages/ListProviderConnections.php | 133 ++- .../Pages/ViewProviderConnection.php | 104 ++- .../ProviderReadinessResolutionAdapter.php | 764 ++++++++++++++++++ apps/platform/lang/de/localization.php | 70 ++ apps/platform/lang/en/localization.php | 70 ++ .../provider-readiness-guidance.blade.php | 10 + ...environment-required-permissions.blade.php | 85 +- ...provider-readiness-guidance-card.blade.php | 257 ++++++ .../provider-readiness-guidance.blade.php | 7 + ...pec281ProviderConnectionScopeSmokeTest.php | 4 +- ...c353ProviderReadinessGuidanceSmokeTest.php | 269 ++++++ .../ProviderConnectionsUiEnforcementTest.php | 5 +- ...Spec353RequiredPermissionsGuidanceTest.php | 162 ++++ .../TenantRequiredPermissionsPageTest.php | 101 +-- .../Guards/ActionSurfaceContractTest.php | 6 +- .../Spec353ProviderConnectionGuidanceTest.php | 180 +++++ ...antRequiredPermissionsTrustedStateTest.php | 35 +- .../RequiredPermissionsCopyActionsTest.php | 8 +- .../RequiredPermissionsEmptyStateTest.php | 9 +- .../RequiredPermissionsFiltersTest.php | 83 +- .../RequiredPermissionsLinksTest.php | 10 +- .../TenantProviderConnectionsCtaTest.php | 3 +- ...ProviderReadinessResolutionAdapterTest.php | 181 +++++ .../design-coverage-matrix.md | 6 +- .../ui-009-provider-connections.md | 34 +- .../ui-077-required-permissions.md | 57 ++ .../ui-ux-enterprise-audit/route-inventory.md | 4 +- .../ui-072-provider-connections.png | Bin 0 -> 101416 bytes .../ui-077-required-permissions.png | Bin 0 -> 247300 bytes .../checklists/requirements.md | 36 + .../provider-readiness-signal-map.md | 43 + .../plan.md | 317 ++++++++ .../repo-truth-map.md | 100 +++ .../spec.md | 516 ++++++++++++ .../tasks.md | 177 ++++ 37 files changed, 3717 insertions(+), 231 deletions(-) create mode 100644 apps/platform/app/Support/ResolutionGuidance/Adapters/ProviderReadinessResolutionAdapter.php create mode 100644 apps/platform/resources/views/filament/infolists/entries/provider-readiness-guidance.blade.php create mode 100644 apps/platform/resources/views/filament/partials/provider-readiness-guidance-card.blade.php create mode 100644 apps/platform/resources/views/filament/widgets/provider-connections/provider-readiness-guidance.blade.php create mode 100644 apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php create mode 100644 apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php create mode 100644 apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php create mode 100644 apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php create mode 100644 docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-072-provider-connections.png create mode 100644 specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-077-required-permissions.png create mode 100644 specs/353-provider-connections-resolution-guidance-v1/checklists/requirements.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/contracts/provider-readiness-signal-map.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/plan.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/repo-truth-map.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/spec.md create mode 100644 specs/353-provider-connections-resolution-guidance-v1/tasks.md diff --git a/apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php b/apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php index ed124f82..bdbee28c 100644 --- a/apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php +++ b/apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php @@ -6,12 +6,19 @@ use App\Models\ManagedEnvironment; use App\Models\User; +use App\Services\Auth\CapabilityResolver; use App\Models\WorkspaceMembership; use App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder; +use App\Services\Verification\StartVerification; +use App\Support\Auth\Capabilities; use App\Support\Badges\BadgeDomain; use App\Support\Badges\BadgeRenderer; use App\Support\Filament\TablePaginationProfiles; use App\Support\ManagedEnvironmentLinks; +use App\Support\OperationRunLinks; +use App\Support\OpsUx\OpsUxBrowserEvents; +use App\Support\OpsUx\ProviderOperationStartResultPresenter; +use App\Support\ResolutionGuidance\Adapters\ProviderReadinessResolutionAdapter; use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration; use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile; use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot; @@ -223,6 +230,65 @@ public function manageProviderConnectionUrl(): ?string return ManagedEnvironmentLinks::providerConnectionsUrl($tenant); } + /** + * @return array + */ + public function guidanceCase(): array + { + $tenant = $this->trustedScopedTenant(); + + if (! $tenant instanceof ManagedEnvironment) { + return []; + } + + return app(ProviderReadinessResolutionAdapter::class) + ->forEnvironment($tenant, ProviderReadinessResolutionAdapter::SURFACE_REQUIRED_PERMISSIONS); + } + + public function canRunProviderVerification(): bool + { + $tenant = $this->trustedScopedTenant(); + $user = auth()->user(); + + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { + return false; + } + + /** @var CapabilityResolver $capabilityResolver */ + $capabilityResolver = app(CapabilityResolver::class); + + return $capabilityResolver->isMember($user, $tenant) + && $capabilityResolver->can($user, $tenant, Capabilities::PROVIDER_RUN); + } + + public function runProviderVerification(): void + { + $tenant = $this->trustedScopedTenant(); + $user = auth()->user(); + + if (! $tenant instanceof ManagedEnvironment || ! $user instanceof User) { + abort(404); + } + + $result = app(StartVerification::class)->providerConnectionCheckForTenant( + tenant: $tenant, + initiator: $user, + extraContext: [ + 'surface' => 'required_permissions.guidance', + ], + ); + + OpsUxBrowserEvents::dispatchRunEnqueued($this); + + app(ProviderOperationStartResultPresenter::class) + ->notification( + result: $result, + blockedTitle: __('localization.provider_guidance.verification_blocked_notification_title'), + runUrl: OperationRunLinks::view($result->run, $tenant), + ) + ->send(); + } + protected static function resolveScopedTenant(ManagedEnvironment|string|null $tenant = null): ?ManagedEnvironment { if ($tenant instanceof ManagedEnvironment) { diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource.php index e18fcdaf..6d5033ec 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource.php @@ -30,6 +30,7 @@ use App\Support\Providers\ProviderConnectionType; use App\Support\Providers\ProviderReasonCodes; use App\Support\Providers\ProviderVerificationStatus; +use App\Support\ResolutionGuidance\Adapters\ProviderReadinessResolutionAdapter; use App\Support\Providers\TargetScope\ProviderConnectionSurfaceSummary; use App\Support\Providers\TargetScope\ProviderConnectionTargetScopeNormalizer; use App\Support\Rbac\UiEnforcement; @@ -103,7 +104,7 @@ public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration ->satisfy(ActionSurfaceSlot::ListRowMoreMenu, 'Edit and provider operations are grouped under "More" while clickable-row view remains primary.') ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Provider connections intentionally omit bulk actions.') ->satisfy(ActionSurfaceSlot::ListEmptyState, 'List page defines empty-state guidance and CTA.') - ->satisfy(ActionSurfaceSlot::DetailHeader, 'View page keeps one primary consent CTA while shared connection actions remain grouped under "More".'); + ->satisfy(ActionSurfaceSlot::DetailHeader, 'View page keeps one primary readiness CTA while shared connection actions remain grouped under "More".'); } public static function canCreate(): bool @@ -635,6 +636,27 @@ private static function providerCapabilitiesLine(?ProviderConnection $record): s ->implode("\n"); } + /** + * @return array + */ + public static function providerReadinessGuidance( + ?ProviderConnection $record, + string $surface = ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW, + ): array { + if (! $record instanceof ProviderConnection) { + return []; + } + + $tenant = static::resolveTenantForRecord($record); + + if (! $tenant instanceof ManagedEnvironment) { + return []; + } + + return app(ProviderReadinessResolutionAdapter::class) + ->forConnection($tenant, $record, $surface); + } + /** * @param array $extra * @return array @@ -745,6 +767,18 @@ public static function infolist(Schema $schema): Schema { return $schema ->schema([ + Section::make(__('localization.provider_guidance.provider_readiness_section')) + ->schema([ + Infolists\Components\ViewEntry::make('provider_readiness_guidance') + ->hiddenLabel() + ->view('filament.infolists.entries.provider-readiness-guidance') + ->state(fn (ProviderConnection $record): array => static::providerReadinessGuidance( + $record, + ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW, + )) + ->columnSpanFull(), + ]) + ->columnSpanFull(), Section::make('Connection') ->schema([ Infolists\Components\TextEntry::make('display_name') diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php index e423e957..0bac8648 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php @@ -8,6 +8,8 @@ use App\Models\User; use App\Services\Auth\CapabilityResolver; use App\Support\Auth\Capabilities; +use App\Support\ManagedEnvironmentLinks; +use App\Support\ResolutionGuidance\Adapters\ProviderReadinessResolutionAdapter; use App\Support\Workspaces\WorkspaceContext; use Filament\Actions; use Filament\Resources\Pages\ListRecords; @@ -139,6 +141,18 @@ public function content(Schema $schema): Schema 'clearUrl' => $this->environmentFilterChip()['clear_url'] ?? null, ]) ->visible(fn (): bool => $this->environmentFilterChip() !== null), + View::make('filament.widgets.provider-connections.provider-readiness-guidance') + ->viewData(function (): array { + $guidance = $this->readinessGuidance(); + + return [ + 'guidance' => $guidance, + 'inlinePrimaryAction' => is_string(data_get($guidance, 'primary_action.url')) + && trim((string) data_get($guidance, 'primary_action.url')) !== '', + 'primaryActionMethod' => null, + ]; + }) + ->visible(fn (): bool => is_array($this->readinessGuidance()) && $this->readinessGuidance() !== []), RenderHook::make(PanelsRenderHook::RESOURCE_PAGES_LIST_RECORDS_TABLE_BEFORE), EmbeddedTable::make(), RenderHook::make(PanelsRenderHook::RESOURCE_PAGES_LIST_RECORDS_TABLE_AFTER), @@ -247,22 +261,12 @@ private function resolveTenantExternalIdForCreateAction(): ?string private function applyRequestedEnvironmentFilter(): void { - $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); - - if (! is_int($workspaceId)) { - return; - } - - $environment = ProviderConnectionResource::resolveRequestedEnvironment(); + $environment = $this->requestedEnvironmentInCurrentWorkspace(); if (! $environment instanceof ManagedEnvironment) { return; } - if ((int) $environment->workspace_id !== $workspaceId) { - abort(404); - } - $slug = (string) $environment->slug; if ($slug === '') { @@ -278,7 +282,7 @@ private function applyRequestedEnvironmentFilter(): void */ private function environmentFilterChip(): ?array { - $environment = ProviderConnectionResource::resolveRequestedEnvironment(); + $environment = $this->requestedEnvironmentInCurrentWorkspace(); if (! $environment instanceof ManagedEnvironment) { return null; @@ -303,13 +307,118 @@ private function resolveTenantForCreateAction(): ?ManagedEnvironment ->first(); } + /** + * @return array|null + */ + private function readinessGuidance(): ?array + { + $environment = $this->currentFilteredEnvironment(); + + if (! $environment instanceof ManagedEnvironment) { + return null; + } + + $guidance = app(ProviderReadinessResolutionAdapter::class) + ->forEnvironment($environment, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_INDEX); + + if (($guidance['key'] ?? null) === 'provider_readiness.connection_missing') { + $guidance['primary_action'] = $this->canManageProviderConnections($environment) + ? [ + 'label' => 'Create provider connection', + 'url' => ProviderConnectionResource::getUrl('create', [ + 'environment_id' => (int) $environment->getKey(), + ]), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ] + : [ + 'label' => __('localization.provider_guidance.action_open_environment_dashboard'), + 'url' => ManagedEnvironmentLinks::viewUrl($environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + return $guidance; + } + + private function canManageProviderConnections(?ManagedEnvironment $environment): bool + { + $user = auth()->user(); + + if (! $environment instanceof ManagedEnvironment || ! $user instanceof User) { + return false; + } + + /** @var CapabilityResolver $resolver */ + $resolver = app(CapabilityResolver::class); + + return $resolver->isMember($user, $environment) + && $resolver->can($user, $environment, Capabilities::PROVIDER_MANAGE); + } + + private function currentFilteredEnvironment(): ?ManagedEnvironment + { + $requestedEnvironment = $this->requestedEnvironmentInCurrentWorkspace(); + + if ($requestedEnvironment instanceof ManagedEnvironment) { + return $requestedEnvironment; + } + + $filterValue = data_get($this->tableFilters, 'tenant.value'); + + if (! is_string($filterValue) || $filterValue === '') { + return null; + } + + return ManagedEnvironment::query() + ->where('slug', $filterValue) + ->first(); + } + + private function requestedEnvironmentInCurrentWorkspace(): ?ManagedEnvironment + { + $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request()); + $user = auth()->user(); + + if (! is_int($workspaceId) || ! $user instanceof User) { + return null; + } + + $environment = ProviderConnectionResource::resolveRequestedEnvironment(); + + if (! $environment instanceof ManagedEnvironment) { + return null; + } + + if ((int) $environment->workspace_id !== $workspaceId) { + return null; + } + + if (! $user->canAccessTenant($environment)) { + return null; + } + + return $environment; + } + public function getTableEmptyStateHeading(): ?string { + if ($this->currentFilteredEnvironment() instanceof ManagedEnvironment) { + return __('localization.provider_guidance.connection_missing_title'); + } + return 'No provider connections found'; } public function getTableEmptyStateDescription(): ?string { + if ($this->currentFilteredEnvironment() instanceof ManagedEnvironment) { + return __('localization.provider_guidance.connection_missing_impact'); + } + return 'Start with a platform-managed provider connection. Dedicated overrides are handled separately with stronger authorization.'; } diff --git a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php index 4d451ae0..3bed9b36 100644 --- a/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php +++ b/apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php @@ -2,12 +2,16 @@ namespace App\Filament\Resources\ProviderConnectionResource\Pages; +use App\Models\OperationRun; use App\Filament\Resources\ProviderConnectionResource; -use App\Models\ProviderConnection; use App\Models\ManagedEnvironment; +use App\Models\ProviderConnection; use App\Support\Auth\Capabilities; use App\Support\Links\RequiredPermissionsLinks; +use App\Support\ManagedEnvironmentLinks; +use App\Support\OperationRunLinks; use App\Support\Rbac\UiEnforcement; +use App\Support\ResolutionGuidance\Adapters\ProviderReadinessResolutionAdapter; use Filament\Actions; use Filament\Resources\Pages\ViewRecord; @@ -18,35 +22,24 @@ class ViewProviderConnection extends ViewRecord protected function getHeaderActions(): array { $tenant = $this->currentTenant(); + $primaryAction = $this->primaryReadinessHeaderAction($tenant); + $primaryActionName = $primaryAction?->getName(); - return [ - UiEnforcement::forAction( - Actions\Action::make('grant_admin_consent') - ->label('Grant admin consent') - ->icon('heroicon-o-clipboard-document') - ->url(function () use ($tenant): ?string { - return $tenant instanceof ManagedEnvironment - ? RequiredPermissionsLinks::adminConsentPrimaryUrl($tenant) - : null; - }) - ->visible(fn (): bool => $tenant instanceof ManagedEnvironment) - ->openUrlInNewTab() - ) - ->requireCapability(Capabilities::PROVIDER_MANAGE) - ->apply(), - Actions\ActionGroup::make($this->sharedConnectionActions()) + return array_values(array_filter([ + $primaryAction, + Actions\ActionGroup::make($this->sharedConnectionActions($primaryActionName)) ->label('More') ->icon('heroicon-o-ellipsis-vertical') ->color('gray'), - ]; + ])); } /** * @return array */ - private function sharedConnectionActions(): array + private function sharedConnectionActions(?string $primaryActionName = null): array { - return [ + $actions = [ ProviderConnectionResource::makeEditNavigationAction(), ProviderConnectionResource::makeCheckConnectionAction(), ProviderConnectionResource::makeInventorySyncAction(), @@ -62,6 +55,77 @@ private function sharedConnectionActions(): array ProviderConnectionResource::makeEnableConnectionAction(), ProviderConnectionResource::makeDisableConnectionAction(), ]; + + if (! is_string($primaryActionName) || $primaryActionName === '') { + return $actions; + } + + return array_values(array_filter( + $actions, + static fn (Actions\Action $action): bool => $action->getName() !== $primaryActionName, + )); + } + + private function primaryReadinessHeaderAction(?ManagedEnvironment $tenant): ?Actions\Action + { + if (! $tenant instanceof ManagedEnvironment || ! $this->record instanceof ProviderConnection) { + return null; + } + + $guidance = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($tenant, $this->record, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW); + $primaryAction = is_array($guidance['primary_action'] ?? null) ? $guidance['primary_action'] : []; + $guidanceKey = (string) ($guidance['key'] ?? ''); + + return match ($guidanceKey) { + 'provider_readiness.admin_consent_required' => UiEnforcement::forAction( + Actions\Action::make('grant_admin_consent') + ->label((string) ($primaryAction['label'] ?? 'Grant admin consent')) + ->icon('heroicon-o-clipboard-document') + ->url(function () use ($tenant): ?string { + return RequiredPermissionsLinks::adminConsentPrimaryUrl($tenant); + }) + ->visible(fn (): bool => true) + ->openUrlInNewTab() + ) + ->requireCapability(Capabilities::PROVIDER_MANAGE) + ->apply(), + 'provider_readiness.required_permissions_missing', + 'provider_readiness.delegated_permissions_missing' => Actions\Action::make('open_required_permissions') + ->label((string) ($primaryAction['label'] ?? 'Open required permissions')) + ->icon('heroicon-o-key') + ->url($primaryAction['url'] ?? RequiredPermissionsLinks::requiredPermissions($tenant)), + 'provider_readiness.verification_required' => ProviderConnectionResource::makeCheckConnectionAction() + ->label((string) ($primaryAction['label'] ?? 'Run provider verification')), + 'provider_readiness.verification_failed' => $this->latestVerificationRun($tenant) instanceof OperationRun + ? Actions\Action::make('open_verification_operation') + ->label((string) ($primaryAction['label'] ?? 'Open verification operation')) + ->icon('heroicon-o-eye') + ->url(OperationRunLinks::view($this->latestVerificationRun($tenant), $tenant)) + : ProviderConnectionResource::makeCheckConnectionAction() + ->label('Run provider verification'), + 'provider_readiness.connection_review_required' => ProviderConnectionResource::makeEditNavigationAction() + ->label((string) ($primaryAction['label'] ?? 'Edit provider connection')), + default => Actions\Action::make('open_environment_dashboard') + ->label((string) ($primaryAction['label'] ?? 'Open environment dashboard')) + ->icon('heroicon-o-home') + ->url(ManagedEnvironmentLinks::viewUrl($tenant)), + }; + } + + private function latestVerificationRun(ManagedEnvironment $tenant): ?OperationRun + { + if (! $this->record instanceof ProviderConnection) { + return null; + } + + return OperationRun::query() + ->where('workspace_id', (int) $tenant->workspace_id) + ->where('managed_environment_id', (int) $tenant->getKey()) + ->where('type', 'provider.connection.check') + ->where('context->provider_connection_id', (int) $this->record->getKey()) + ->orderByDesc('id') + ->first(); } private function currentTenant(): ?ManagedEnvironment diff --git a/apps/platform/app/Support/ResolutionGuidance/Adapters/ProviderReadinessResolutionAdapter.php b/apps/platform/app/Support/ResolutionGuidance/Adapters/ProviderReadinessResolutionAdapter.php new file mode 100644 index 00000000..94da04ac --- /dev/null +++ b/apps/platform/app/Support/ResolutionGuidance/Adapters/ProviderReadinessResolutionAdapter.php @@ -0,0 +1,764 @@ + + */ + public function forEnvironment( + ManagedEnvironment $environment, + string $surface = self::SURFACE_PROVIDER_CONNECTIONS_INDEX, + ): array { + $resolution = $this->connections->resolveDefault($environment, 'microsoft'); + $connection = $resolution->connection; + + return $this->buildCase( + environment: $environment, + connection: $connection, + resolution: $resolution, + permissions: $this->permissionSignals($environment), + latestVerificationRun: $connection instanceof ProviderConnection + ? $this->latestVerificationRun($environment, $connection) + : null, + surface: $surface, + ); + } + + /** + * @return array + */ + public function forConnection( + ManagedEnvironment $environment, + ProviderConnection $connection, + string $surface = self::SURFACE_PROVIDER_CONNECTIONS_VIEW, + ): array { + $provider = trim((string) $connection->provider) !== '' + ? trim((string) $connection->provider) + : 'microsoft'; + + return $this->buildCase( + environment: $environment, + connection: $connection, + resolution: $this->connections->validateConnection($environment, $provider, $connection), + permissions: $this->permissionSignals($environment), + latestVerificationRun: $this->latestVerificationRun($environment, $connection), + surface: $surface, + ); + } + + /** + * @param array{ + * counts: array{missing_application:int,missing_delegated:int,present:int,error:int}, + * freshness: array{last_refreshed_at:?string,is_stale:bool} + * } $permissions + * @return array + */ + private function buildCase( + ManagedEnvironment $environment, + ?ProviderConnection $connection, + ProviderConnectionResolution $resolution, + array $permissions, + ?OperationRun $latestVerificationRun, + string $surface, + ): array { + $counts = $permissions['counts']; + $freshness = $permissions['freshness']; + $missingApplication = (int) ($counts['missing_application'] ?? 0); + $missingDelegated = (int) ($counts['missing_delegated'] ?? 0); + $errorCount = (int) ($counts['error'] ?? 0); + + if ($resolution->effectiveReasonCode() === ProviderReasonCodes::ProviderConnectionMissing) { + return $this->case( + key: 'provider_readiness.connection_missing', + severity: 'danger', + status: __('localization.provider_guidance.status_blocked'), + title: __('localization.provider_guidance.connection_missing_title'), + reason: __('localization.provider_guidance.connection_missing_reason'), + impact: __('localization.provider_guidance.connection_missing_impact'), + primaryAction: $this->providerConnectionsAction($environment), + secondaryActions: [ + $this->environmentDashboardAction($environment), + ], + technicalDetails: [ + $this->technicalDetail( + __('localization.provider_guidance.detail_provider_label'), + __('localization.provider_guidance.detail_provider_value'), + ), + $this->technicalDetail( + __('localization.provider_guidance.detail_verification_state_label'), + __('localization.provider_guidance.verification_not_run_detail'), + ), + ], + ); + } + + if ($this->isConsentBlocker($resolution->effectiveReasonCode())) { + return $this->case( + key: 'provider_readiness.admin_consent_required', + severity: 'danger', + status: __('localization.provider_guidance.status_blocked'), + title: __('localization.provider_guidance.admin_consent_required_title'), + reason: $this->consentReason($resolution->effectiveReasonCode()), + impact: __('localization.provider_guidance.admin_consent_required_impact'), + primaryAction: $this->adminConsentAction($environment), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeRequiredPermissions: true, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + if (! $resolution->resolved) { + return $this->case( + key: 'provider_readiness.connection_review_required', + severity: 'danger', + status: __('localization.provider_guidance.status_blocked'), + title: $connection instanceof ProviderConnection && ! (bool) $connection->is_enabled + ? __('localization.provider_guidance.connection_disabled_title') + : __('localization.provider_guidance.connection_review_title'), + reason: $connection instanceof ProviderConnection && ! (bool) $connection->is_enabled + ? __('localization.provider_guidance.connection_disabled_reason') + : (trim((string) ($resolution->message ?? '')) !== '' + ? trim((string) $resolution->message) + : __('localization.provider_guidance.connection_review_reason')), + impact: $connection instanceof ProviderConnection && ! (bool) $connection->is_enabled + ? __('localization.provider_guidance.connection_disabled_impact') + : __('localization.provider_guidance.connection_review_impact'), + primaryAction: $this->providerConnectionReviewAction($environment, $connection, $surface), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeRequiredPermissions: true, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + if ($missingApplication > 0) { + return $this->case( + key: 'provider_readiness.required_permissions_missing', + severity: 'danger', + status: __('localization.provider_guidance.status_blocked'), + title: $surface === self::SURFACE_REQUIRED_PERMISSIONS + ? __('localization.provider_guidance.required_permissions_missing_title') + : __('localization.provider_guidance.provider_readiness_blocked_title'), + reason: __('localization.provider_guidance.required_application_permissions_reason'), + impact: __('localization.provider_guidance.required_application_permissions_impact'), + primaryAction: $surface === self::SURFACE_REQUIRED_PERMISSIONS + ? $this->adminConsentAction($environment) + : $this->requiredPermissionsAction($environment), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeAdminConsent: $surface !== self::SURFACE_REQUIRED_PERMISSIONS, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + if ($missingDelegated > 0) { + return $this->case( + key: 'provider_readiness.delegated_permissions_missing', + severity: 'warning', + status: __('localization.provider_guidance.status_action_required'), + title: $surface === self::SURFACE_REQUIRED_PERMISSIONS + ? __('localization.provider_guidance.required_permissions_missing_title') + : __('localization.provider_guidance.provider_readiness_attention_title'), + reason: __('localization.provider_guidance.required_delegated_permissions_reason'), + impact: __('localization.provider_guidance.required_delegated_permissions_impact'), + primaryAction: $surface === self::SURFACE_REQUIRED_PERMISSIONS + ? $this->adminConsentAction($environment) + : $this->requiredPermissionsAction($environment), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeAdminConsent: $surface !== self::SURFACE_REQUIRED_PERMISSIONS, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + $verificationState = $this->verificationState($connection); + + if ($errorCount > 0 || in_array($verificationState, [ + ProviderVerificationStatus::Error->value, + ProviderVerificationStatus::Blocked->value, + ProviderVerificationStatus::Degraded->value, + ProviderVerificationStatus::Pending->value, + ], true)) { + return $this->case( + key: 'provider_readiness.verification_failed', + severity: $verificationState === ProviderVerificationStatus::Pending->value ? 'warning' : 'danger', + status: $verificationState === ProviderVerificationStatus::Pending->value + ? __('localization.provider_guidance.status_action_required') + : __('localization.provider_guidance.status_blocked'), + title: $verificationState === ProviderVerificationStatus::Pending->value + ? __('localization.provider_guidance.verification_in_progress_title') + : __('localization.provider_guidance.verification_failed_title'), + reason: $this->verificationFailureReason( + verificationState: $verificationState, + connection: $connection, + errorCount: $errorCount, + ), + impact: __('localization.provider_guidance.verification_failed_impact'), + primaryAction: $latestVerificationRun instanceof OperationRun + ? $this->verificationOperationAction($latestVerificationRun, $environment) + : $this->providerConnectionReviewAction($environment, $connection, $surface), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeRequiredPermissions: true, + includeRunVerification: $surface === self::SURFACE_REQUIRED_PERMISSIONS, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + $stalePermissionSnapshot = (bool) ($freshness['is_stale'] ?? true); + $lastHealthCheckAt = $connection?->last_health_check_at instanceof Carbon + ? $connection->last_health_check_at + : ($connection?->last_health_check_at !== null ? Carbon::parse((string) $connection?->last_health_check_at) : null); + $verificationNotRun = $verificationState === ProviderVerificationStatus::Unknown->value || $lastHealthCheckAt === null; + $verificationStale = $lastHealthCheckAt instanceof Carbon && $lastHealthCheckAt->lt(now()->subDays(30)); + + if ($verificationNotRun || $verificationStale || $stalePermissionSnapshot) { + return $this->case( + key: 'provider_readiness.verification_required', + severity: 'warning', + status: __('localization.provider_guidance.status_action_required'), + title: __('localization.provider_guidance.verification_required_title'), + reason: $this->verificationRequiredReason( + verificationNotRun: $verificationNotRun, + verificationStale: $verificationStale, + stalePermissionSnapshot: $stalePermissionSnapshot, + ), + impact: __('localization.provider_guidance.verification_required_impact'), + primaryAction: $this->verificationPrimaryAction( + environment: $environment, + connection: $connection, + surface: $surface, + ), + secondaryActions: $this->secondaryActionsFor( + environment: $environment, + connection: $connection, + latestVerificationRun: $latestVerificationRun, + surface: $surface, + includeRequiredPermissions: true, + ), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + return $this->case( + key: 'provider_readiness.ready', + severity: 'success', + status: __('localization.provider_guidance.status_ready'), + title: __('localization.provider_guidance.ready_title'), + reason: __('localization.provider_guidance.ready_reason'), + impact: __('localization.provider_guidance.ready_impact'), + primaryAction: $this->environmentDashboardAction($environment), + secondaryActions: array_values(array_filter([ + $surface === self::SURFACE_REQUIRED_PERMISSIONS ? null : $this->requiredPermissionsAction($environment), + $connection instanceof ProviderConnection ? $this->providerConnectionAction($environment, $connection, $surface) : null, + ])), + technicalDetails: $this->technicalDetails( + connection: $connection, + permissions: $permissions, + latestVerificationRun: $latestVerificationRun, + ), + ); + } + + /** + * @return array{ + * counts: array{missing_application:int,missing_delegated:int,present:int,error:int}, + * freshness: array{last_refreshed_at:?string,is_stale:bool} + * } + */ + private function permissionSignals(ManagedEnvironment $environment): array + { + $viewModel = $this->requiredPermissions->build($environment); + $overview = is_array($viewModel['overview'] ?? null) ? $viewModel['overview'] : []; + + return [ + 'counts' => array_replace([ + 'missing_application' => 0, + 'missing_delegated' => 0, + 'present' => 0, + 'error' => 0, + ], is_array($overview['counts'] ?? null) ? $overview['counts'] : []), + 'freshness' => array_replace([ + 'last_refreshed_at' => null, + 'is_stale' => true, + ], is_array($overview['freshness'] ?? null) ? $overview['freshness'] : []), + ]; + } + + private function latestVerificationRun(ManagedEnvironment $environment, ProviderConnection $connection): ?OperationRun + { + return OperationRun::query() + ->where('workspace_id', (int) $environment->workspace_id) + ->where('managed_environment_id', (int) $environment->getKey()) + ->where('type', 'provider.connection.check') + ->where('context->provider_connection_id', (int) $connection->getKey()) + ->orderByDesc('id') + ->first(); + } + + private function verificationState(?ProviderConnection $connection): string + { + $state = $connection?->verification_status; + + if ($state instanceof ProviderVerificationStatus) { + return $state->value; + } + + if (is_string($state) && trim($state) !== '') { + return trim($state); + } + + return ProviderVerificationStatus::Unknown->value; + } + + private function isConsentBlocker(string $reasonCode): bool + { + return in_array($reasonCode, [ + ProviderReasonCodes::ProviderConsentMissing, + ProviderReasonCodes::ProviderConsentFailed, + ProviderReasonCodes::ProviderConsentRevoked, + ], true); + } + + private function consentReason(string $reasonCode): string + { + return match ($reasonCode) { + ProviderReasonCodes::ProviderConsentFailed => __('localization.provider_guidance.admin_consent_failed_reason'), + ProviderReasonCodes::ProviderConsentRevoked => __('localization.provider_guidance.admin_consent_revoked_reason'), + default => __('localization.provider_guidance.admin_consent_required_reason'), + }; + } + + private function verificationFailureReason( + string $verificationState, + ?ProviderConnection $connection, + int $errorCount, + ): string { + if ($verificationState === ProviderVerificationStatus::Pending->value) { + return __('localization.provider_guidance.verification_in_progress_reason'); + } + + if ($verificationState === ProviderVerificationStatus::Degraded->value) { + return __('localization.provider_guidance.verification_degraded_reason'); + } + + if ($errorCount > 0) { + return __('localization.provider_guidance.verification_errors_reason', ['count' => $errorCount]); + } + + $message = trim((string) ($connection?->last_error_message ?? '')); + + if ($message !== '') { + return Str::limit($message, 180); + } + + return __('localization.provider_guidance.verification_failed_reason'); + } + + private function verificationRequiredReason( + bool $verificationNotRun, + bool $verificationStale, + bool $stalePermissionSnapshot, + ): string { + return match (true) { + $verificationNotRun => __('localization.provider_guidance.verification_not_run_reason'), + $verificationStale, $stalePermissionSnapshot => __('localization.provider_guidance.verification_stale_reason'), + default => __('localization.provider_guidance.verification_not_run_reason'), + }; + } + + /** + * @return array + */ + private function verificationPrimaryAction( + ManagedEnvironment $environment, + ?ProviderConnection $connection, + string $surface, + ): array { + if ($surface === self::SURFACE_REQUIRED_PERMISSIONS) { + return [ + 'label' => __('localization.provider_guidance.action_run_provider_verification'), + 'url' => null, + 'action_name' => 'runProviderVerification', + 'external' => false, + 'disabled' => false, + ]; + } + + if ($surface === self::SURFACE_PROVIDER_CONNECTIONS_VIEW || $surface === self::SURFACE_PROVIDER_CONNECTIONS_EDIT) { + return [ + 'label' => __('localization.provider_guidance.action_run_provider_verification'), + 'url' => null, + 'action_name' => 'runProviderVerification', + 'external' => false, + 'disabled' => false, + ]; + } + + if ($connection instanceof ProviderConnection) { + return $this->providerConnectionAction($environment, $connection, $surface, __('localization.provider_guidance.action_open_provider_connection')); + } + + return $this->providerConnectionsAction($environment); + } + + /** + * @return list> + */ + private function secondaryActionsFor( + ManagedEnvironment $environment, + ?ProviderConnection $connection, + ?OperationRun $latestVerificationRun, + string $surface, + bool $includeRequiredPermissions = false, + bool $includeAdminConsent = false, + bool $includeRunVerification = false, + ): array { + $actions = []; + + if ($includeRequiredPermissions && $surface !== self::SURFACE_REQUIRED_PERMISSIONS) { + $actions[] = $this->requiredPermissionsAction($environment); + } + + if ($includeAdminConsent) { + $actions[] = $this->adminConsentAction($environment); + } + + if ($latestVerificationRun instanceof OperationRun) { + $actions[] = $this->verificationOperationAction($latestVerificationRun, $environment); + } + + if ($includeRunVerification && $surface === self::SURFACE_REQUIRED_PERMISSIONS) { + $actions[] = [ + 'label' => __('localization.provider_guidance.action_run_provider_verification'), + 'url' => null, + 'action_name' => 'runProviderVerification', + 'external' => false, + 'disabled' => false, + ]; + } + + if ($connection instanceof ProviderConnection && ! in_array($surface, [ + self::SURFACE_PROVIDER_CONNECTIONS_VIEW, + self::SURFACE_PROVIDER_CONNECTIONS_EDIT, + ], true)) { + $actions[] = $this->providerConnectionAction($environment, $connection, $surface); + } + + $actions[] = $this->environmentDashboardAction($environment); + + return array_values(array_filter($actions, static fn (array $action): bool => ($action['url'] ?? null) !== null || ($action['action_name'] ?? null) !== null)); + } + + /** + * @param array{ + * counts: array{missing_application:int,missing_delegated:int,present:int,error:int}, + * freshness: array{last_refreshed_at:?string,is_stale:bool} + * } $permissions + * @return list + */ + private function technicalDetails( + ?ProviderConnection $connection, + array $permissions, + ?OperationRun $latestVerificationRun, + ): array { + $counts = $permissions['counts']; + $freshness = $permissions['freshness']; + $details = [ + $this->technicalDetail( + __('localization.provider_guidance.detail_missing_application_permissions_label'), + (string) ((int) ($counts['missing_application'] ?? 0)), + ), + $this->technicalDetail( + __('localization.provider_guidance.detail_missing_delegated_permissions_label'), + (string) ((int) ($counts['missing_delegated'] ?? 0)), + ), + $this->technicalDetail( + __('localization.provider_guidance.detail_verification_state_label'), + $this->verificationStateLabel($connection), + ), + ]; + + if (is_string($freshness['last_refreshed_at'] ?? null) && trim((string) $freshness['last_refreshed_at']) !== '') { + $details[] = $this->technicalDetail( + __('localization.provider_guidance.detail_permission_evidence_label'), + Carbon::parse((string) $freshness['last_refreshed_at'])->diffForHumans(), + ); + } else { + $details[] = $this->technicalDetail( + __('localization.provider_guidance.detail_permission_evidence_label'), + __('localization.provider_guidance.verification_not_run_detail'), + ); + } + + if ($connection instanceof ProviderConnection) { + $consent = $connection->consent_status; + + $details[] = $this->technicalDetail( + __('localization.provider_guidance.detail_consent_state_label'), + $consent instanceof ProviderConsentStatus + ? Str::headline($consent->value) + : Str::headline(trim((string) $consent)), + ); + } + + if ($latestVerificationRun instanceof OperationRun) { + $details[] = $this->technicalDetail( + __('localization.provider_guidance.detail_last_verification_operation_label'), + OperationRunLinks::identifier($latestVerificationRun), + ); + } + + return $details; + } + + private function verificationStateLabel(?ProviderConnection $connection): string + { + return match ($this->verificationState($connection)) { + ProviderVerificationStatus::Healthy->value => __('localization.provider_guidance.verification_ready_detail'), + ProviderVerificationStatus::Degraded->value => __('localization.provider_guidance.verification_degraded_detail'), + ProviderVerificationStatus::Blocked->value => __('localization.provider_guidance.verification_blocked_detail'), + ProviderVerificationStatus::Error->value => __('localization.provider_guidance.verification_failed_detail'), + ProviderVerificationStatus::Pending->value => __('localization.provider_guidance.verification_in_progress_detail'), + default => __('localization.provider_guidance.verification_not_run_detail'), + }; + } + + /** + * @return array + */ + private function requiredPermissionsAction(ManagedEnvironment $environment): array + { + return [ + 'label' => __('localization.provider_guidance.action_open_required_permissions'), + 'url' => RequiredPermissionsLinks::requiredPermissions($environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + /** + * @return array + */ + private function adminConsentAction(ManagedEnvironment $environment): array + { + $url = RequiredPermissionsLinks::adminConsentPrimaryUrl($environment); + $directConsent = RequiredPermissionsLinks::adminConsentUrl($environment) !== null; + + return [ + 'label' => $directConsent + ? __('localization.provider_guidance.action_open_admin_consent') + : __('localization.provider_guidance.action_open_admin_consent_guide'), + 'url' => $url, + 'action_name' => null, + 'external' => true, + 'disabled' => false, + ]; + } + + /** + * @return array + */ + private function providerConnectionsAction(ManagedEnvironment $environment): array + { + return [ + 'label' => __('localization.provider_guidance.action_open_provider_connections'), + 'url' => ManagedEnvironmentLinks::providerConnectionsUrl($environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + /** + * @return array + */ + private function providerConnectionReviewAction( + ManagedEnvironment $environment, + ?ProviderConnection $connection, + string $surface, + ): array { + if ($connection instanceof ProviderConnection) { + return $this->providerConnectionAction( + environment: $environment, + connection: $connection, + surface: $surface, + label: in_array($surface, [self::SURFACE_PROVIDER_CONNECTIONS_VIEW, self::SURFACE_PROVIDER_CONNECTIONS_EDIT], true) + ? __('localization.provider_guidance.action_edit_provider_connection') + : __('localization.provider_guidance.action_open_provider_connection'), + ); + } + + return $this->providerConnectionsAction($environment); + } + + /** + * @return array + */ + private function providerConnectionAction( + ManagedEnvironment $environment, + ProviderConnection $connection, + string $surface, + ?string $label = null, + ): array { + $page = $surface === self::SURFACE_PROVIDER_CONNECTIONS_EDIT ? 'view' : 'edit'; + + if ($surface === self::SURFACE_PROVIDER_CONNECTIONS_INDEX || $surface === self::SURFACE_REQUIRED_PERMISSIONS) { + $page = 'view'; + } + + return [ + 'label' => $label ?? __('localization.provider_guidance.action_open_provider_connection'), + 'url' => ManagedEnvironmentLinks::providerConnectionUrl($connection, $page, $environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + /** + * @return array + */ + private function verificationOperationAction(OperationRun $run, ManagedEnvironment $environment): array + { + return [ + 'label' => __('localization.provider_guidance.action_open_verification_operation'), + 'url' => OperationRunLinks::view($run, $environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + /** + * @return array + */ + private function environmentDashboardAction(ManagedEnvironment $environment): array + { + return [ + 'label' => __('localization.provider_guidance.action_open_environment_dashboard'), + 'url' => ManagedEnvironmentLinks::viewUrl($environment), + 'action_name' => null, + 'external' => false, + 'disabled' => false, + ]; + } + + /** + * @param list $technicalDetails + * @param list> $secondaryActions + * @return array + */ + private function case( + string $key, + string $severity, + string $status, + string $title, + string $reason, + string $impact, + array $primaryAction, + array $secondaryActions, + array $technicalDetails, + ): array { + return [ + 'key' => $key, + 'severity' => $severity, + 'status' => $status, + 'title' => $title, + 'reason' => $reason, + 'impact' => $impact, + 'primary_action' => $primaryAction, + 'secondary_actions' => array_values($secondaryActions), + 'technical_details' => array_values($technicalDetails), + ]; + } + + /** + * @return array{label:string,value:string} + */ + private function technicalDetail(string $label, string $value): array + { + return [ + 'label' => $label, + 'value' => $value, + ]; + } +} diff --git a/apps/platform/lang/de/localization.php b/apps/platform/lang/de/localization.php index b81cbea4..ff3600eb 100644 --- a/apps/platform/lang/de/localization.php +++ b/apps/platform/lang/de/localization.php @@ -354,6 +354,76 @@ 'recent_operation_fallback_summary' => 'Aktueller Vorgangskontext für diese Umgebung.', ], ], + 'provider_guidance' => [ + 'status_blocked' => 'Blockiert', + 'status_action_required' => 'Aktion erforderlich', + 'status_ready' => 'Bereit', + 'reason_label' => 'Grund', + 'impact_label' => 'Auswirkung', + 'primary_action_label' => 'Empfohlener nächster Schritt', + 'secondary_actions_label' => 'Weitere Aktionen', + 'details_label' => 'Details', + 'provider_readiness_blocked_title' => 'Provider-Bereitschaft blockiert', + 'provider_readiness_attention_title' => 'Provider-Bereitschaft benötigt Aufmerksamkeit', + 'required_permissions_missing_title' => 'Erforderliche Berechtigungen fehlen', + 'connection_missing_title' => 'Provider-Verbindung erforderlich', + 'connection_missing_reason' => 'Für diese Umgebung ist noch keine Provider-Verbindung konfiguriert.', + 'connection_missing_impact' => 'Evidence-Aktualisierung, Berechtigungsstatus, Inventarisierung und Review-Bereitschaft können erst als bereit gelten, wenn eine Provider-Verbindung vorhanden ist.', + 'connection_review_title' => 'Provider-Verbindung muss geprüft werden', + 'connection_review_reason' => 'Diese Provider-Verbindung ist derzeit nicht nutzbar.', + 'connection_review_impact' => 'TenantPilot kann diese Provider-Verbindung erst nach Prüfung des protokollierten Problems verifizieren oder verwenden.', + 'connection_disabled_title' => 'Provider-Verbindung deaktiviert', + 'connection_disabled_reason' => 'Diese Provider-Verbindung ist deaktiviert.', + 'connection_disabled_impact' => 'Provider-gestützte Evidence-Aktualisierung, Inventarisierung und Bereitschaftsprüfung bleiben blockiert, solange die Verbindung deaktiviert ist.', + 'admin_consent_required_title' => 'Provider-Zustimmung erforderlich', + 'admin_consent_required_reason' => 'Für diese Provider-Verbindung fehlt die Admin-Zustimmung.', + 'admin_consent_failed_reason' => 'TenantPilot konnte die Admin-Zustimmung für diese Provider-Verbindung nicht bestätigen.', + 'admin_consent_revoked_reason' => 'Eine zuvor erteilte Admin-Zustimmung ist für diese Provider-Verbindung nicht mehr gültig.', + 'admin_consent_required_impact' => 'TenantPilot kann die Provider-Verbindung erst wieder für Evidence-Aktualisierung, Inventarisierung und Review-Bereitschaft verwenden, wenn die Zustimmung wiederhergestellt ist.', + 'required_application_permissions_reason' => 'Erforderliche Anwendungsberechtigungen fehlen.', + 'required_application_permissions_impact' => 'TenantPilot kann Evidence, Berechtigungsstatus, Inventarisierung und Review-Outputs erst zuverlässig aktualisieren, wenn die fehlenden Anwendungsberechtigungen erteilt wurden.', + 'required_delegated_permissions_reason' => 'Erforderliche delegierte Berechtigungen fehlen.', + 'required_delegated_permissions_impact' => 'Provider-gestützte Workflows bleiben möglicherweise nur teilweise bereit, bis der delegierte Zugriff geprüft und bei Bedarf erteilt wurde.', + 'verification_required_title' => 'Provider-Verifikation erforderlich', + 'verification_required_impact' => 'TenantPilot kann erst nach einer erneuten Verifikation bestätigen, ob die erforderlichen Berechtigungen und der Provider-Zugriff derzeit nutzbar sind.', + 'verification_not_run_reason' => 'Diese Provider-Verbindung wurde noch nicht verifiziert.', + 'verification_stale_reason' => 'Gespeicherte Provider-Verifikationsdaten sind veraltet und sollten aktualisiert werden.', + 'verification_failed_title' => 'Provider-Verifikation fehlgeschlagen', + 'verification_failed_reason' => 'Die letzte Provider-Verifikation wurde nicht erfolgreich abgeschlossen.', + 'verification_failed_impact' => 'Provider-gestützte Vorgänge können fehlschlagen, bis das Problem geprüft wurde.', + 'verification_errors_reason' => ':count Berechtigungszeile(n) befinden sich in einem unbekannten oder fehlerhaften Zustand und benötigen Nachverfolgung.', + 'verification_degraded_reason' => 'Die letzte Provider-Verifikation wurde mit Warnungen abgeschlossen und sollte geprüft werden.', + 'verification_in_progress_title' => 'Provider-Verifikation läuft', + 'verification_in_progress_reason' => 'Für diese Verbindung läuft bereits eine Provider-Verifikation.', + 'verification_blocked_notification_title' => 'Provider-Verifikation blockiert', + 'ready_title' => 'Provider-Verbindung bereit', + 'ready_reason' => 'Erforderliche Provider-Berechtigungen und Verifikationsprüfungen sind aktuell erfüllt.', + 'ready_impact' => 'Derzeit ist keine dringende Aktion zur Provider-Bereitschaft erforderlich.', + 'action_open_required_permissions' => 'Erforderliche Berechtigungen öffnen', + 'action_open_admin_consent' => 'Admin-Zustimmung öffnen', + 'action_open_admin_consent_guide' => 'Leitfaden zur Admin-Zustimmung öffnen', + 'action_open_provider_connections' => 'Provider-Verbindungen öffnen', + 'action_open_provider_connection' => 'Provider-Verbindung öffnen', + 'action_edit_provider_connection' => 'Provider-Verbindung bearbeiten', + 'action_run_provider_verification' => 'Provider-Verifikation starten', + 'action_open_verification_operation' => 'Verifikationsvorgang öffnen', + 'action_open_environment_dashboard' => 'Umgebungs-Dashboard öffnen', + 'provider_readiness_section' => 'Provider-Bereitschaft', + 'detail_provider_label' => 'Provider', + 'detail_provider_value' => 'Microsoft', + 'detail_missing_application_permissions_label' => 'Fehlende Anwendungsberechtigungen', + 'detail_missing_delegated_permissions_label' => 'Fehlende delegierte Berechtigungen', + 'detail_verification_state_label' => 'Verifikationsstatus', + 'detail_permission_evidence_label' => 'Gespeicherte Berechtigungsevidenz', + 'detail_consent_state_label' => 'Zustimmungsstatus', + 'detail_last_verification_operation_label' => 'Letzter Verifikationsvorgang', + 'verification_ready_detail' => 'Bereit', + 'verification_degraded_detail' => 'Beeinträchtigt', + 'verification_blocked_detail' => 'Blockiert', + 'verification_failed_detail' => 'Fehlgeschlagen', + 'verification_in_progress_detail' => 'Läuft', + 'verification_not_run_detail' => 'Nicht ausgeführt', + ], 'review' => [ 'reporting' => 'Berichte', 'customer_reviews' => 'Kundenreviews', diff --git a/apps/platform/lang/en/localization.php b/apps/platform/lang/en/localization.php index 6e83c09b..33593563 100644 --- a/apps/platform/lang/en/localization.php +++ b/apps/platform/lang/en/localization.php @@ -354,6 +354,76 @@ 'recent_operation_fallback_summary' => 'Recent operation context for this environment.', ], ], + 'provider_guidance' => [ + 'status_blocked' => 'Blocked', + 'status_action_required' => 'Action required', + 'status_ready' => 'Ready', + 'reason_label' => 'Reason', + 'impact_label' => 'Impact', + 'primary_action_label' => 'Recommended next action', + 'secondary_actions_label' => 'Secondary', + 'details_label' => 'Details', + 'provider_readiness_blocked_title' => 'Provider readiness blocked', + 'provider_readiness_attention_title' => 'Provider readiness needs attention', + 'required_permissions_missing_title' => 'Required permissions missing', + 'connection_missing_title' => 'Provider connection required', + 'connection_missing_reason' => 'No provider connection is configured for this environment.', + 'connection_missing_impact' => 'Evidence refresh, permission posture, inventory sync, and review readiness cannot be treated as ready until a provider connection exists.', + 'connection_review_title' => 'Provider connection needs review', + 'connection_review_reason' => 'This provider connection is not currently usable.', + 'connection_review_impact' => 'TenantPilot cannot verify or use this provider connection until the recorded issue is reviewed.', + 'connection_disabled_title' => 'Provider connection disabled', + 'connection_disabled_reason' => 'This provider connection is disabled.', + 'connection_disabled_impact' => 'Provider-backed evidence refresh, inventory sync, and readiness verification stay blocked while the connection is disabled.', + 'admin_consent_required_title' => 'Provider consent required', + 'admin_consent_required_reason' => 'Admin consent is missing for this provider connection.', + 'admin_consent_failed_reason' => 'TenantPilot could not confirm admin consent for this provider connection.', + 'admin_consent_revoked_reason' => 'Previously granted admin consent is no longer valid for this provider connection.', + 'admin_consent_required_impact' => 'TenantPilot cannot use the provider connection for evidence refresh, inventory, or review readiness until consent is restored.', + 'required_application_permissions_reason' => 'Required application permissions are missing.', + 'required_application_permissions_impact' => 'TenantPilot cannot refresh evidence, permission posture, inventory, or review outputs reliably until the missing application permissions are granted.', + 'required_delegated_permissions_reason' => 'Required delegated permissions are missing.', + 'required_delegated_permissions_impact' => 'Provider-backed workflows may remain partially ready until delegated access is reviewed and granted where needed.', + 'verification_required_title' => 'Provider verification required', + 'verification_required_impact' => 'TenantPilot cannot confirm whether required permissions and provider access are currently usable until verification runs again.', + 'verification_not_run_reason' => 'This provider connection has not been verified yet.', + 'verification_stale_reason' => 'Stored provider verification evidence is stale and should be refreshed.', + 'verification_failed_title' => 'Provider verification failed', + 'verification_failed_reason' => 'The last provider verification did not complete successfully.', + 'verification_failed_impact' => 'Provider-backed operations may fail until the issue is reviewed.', + 'verification_errors_reason' => ':count permission row(s) are in an unknown or error state and require follow-up.', + 'verification_degraded_reason' => 'The latest provider verification completed with warnings and should be reviewed.', + 'verification_in_progress_title' => 'Provider verification in progress', + 'verification_in_progress_reason' => 'A provider verification is already running for this connection.', + 'verification_blocked_notification_title' => 'Provider verification blocked', + 'ready_title' => 'Provider connection ready', + 'ready_reason' => 'Required provider permissions and verification checks are currently satisfied.', + 'ready_impact' => 'No urgent provider readiness action is currently required.', + 'action_open_required_permissions' => 'Open required permissions', + 'action_open_admin_consent' => 'Open admin consent', + 'action_open_admin_consent_guide' => 'Open admin consent guide', + 'action_open_provider_connections' => 'Open provider connections', + 'action_open_provider_connection' => 'Open provider connection', + 'action_edit_provider_connection' => 'Edit provider connection', + 'action_run_provider_verification' => 'Run provider verification', + 'action_open_verification_operation' => 'Open verification operation', + 'action_open_environment_dashboard' => 'Open environment dashboard', + 'provider_readiness_section' => 'Provider readiness', + 'detail_provider_label' => 'Provider', + 'detail_provider_value' => 'Microsoft', + 'detail_missing_application_permissions_label' => 'Missing application permissions', + 'detail_missing_delegated_permissions_label' => 'Missing delegated permissions', + 'detail_verification_state_label' => 'Verification state', + 'detail_permission_evidence_label' => 'Stored permission evidence', + 'detail_consent_state_label' => 'Consent state', + 'detail_last_verification_operation_label' => 'Last verification operation', + 'verification_ready_detail' => 'Ready', + 'verification_degraded_detail' => 'Degraded', + 'verification_blocked_detail' => 'Blocked', + 'verification_failed_detail' => 'Failed', + 'verification_in_progress_detail' => 'In progress', + 'verification_not_run_detail' => 'Not run', + ], 'review' => [ 'reporting' => 'Reporting', 'customer_reviews' => 'Customer reviews', diff --git a/apps/platform/resources/views/filament/infolists/entries/provider-readiness-guidance.blade.php b/apps/platform/resources/views/filament/infolists/entries/provider-readiness-guidance.blade.php new file mode 100644 index 00000000..acb9d7cb --- /dev/null +++ b/apps/platform/resources/views/filament/infolists/entries/provider-readiness-guidance.blade.php @@ -0,0 +1,10 @@ +@php + $guidance = $getState(); + $guidance = is_array($guidance) ? $guidance : []; +@endphp + +@include('filament.partials.provider-readiness-guidance-card', [ + 'guidance' => $guidance, + 'inlinePrimaryAction' => false, + 'primaryActionMethod' => null, +]) diff --git a/apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php b/apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php index d2a682b7..90f25660 100644 --- a/apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php +++ b/apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php @@ -38,6 +38,11 @@ $reRunUrl = $this->reRunVerificationUrl(); $manageProviderConnectionUrl = $this->manageProviderConnectionUrl(); + $guidance = $this->guidanceCase(); + $guidancePrimaryAction = is_array($guidance['primary_action'] ?? null) ? $guidance['primary_action'] : []; + $canRunProviderVerification = $this->canRunProviderVerification(); + $showGuidancePrimaryAction = (is_string($guidancePrimaryAction['url'] ?? null) && $guidancePrimaryAction['url'] !== '') + || ($canRunProviderVerification && ($guidancePrimaryAction['action_name'] ?? null) === 'runProviderVerification'); $lastRefreshedAt = is_string($freshness['last_refreshed_at'] ?? null) ? (string) $freshness['last_refreshed_at'] : null; $lastRefreshedLabel = $lastRefreshedAt ? Carbon::parse($lastRefreshedAt)->diffForHumans() : 'Unknown'; $isStale = (bool) ($freshness['is_stale'] ?? true); @@ -53,7 +58,7 @@ 'links' => array_values(array_filter([ ['label' => $adminConsentLabel, 'url' => $adminConsentPrimaryUrl, 'external' => true], $manageProviderConnectionUrl ? ['label' => 'Manage provider connection', 'url' => $manageProviderConnectionUrl, 'external' => false] : null, - ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], + ['label' => 'Open environment dashboard', 'url' => $reRunUrl, 'external' => false], ])), ]; } @@ -65,7 +70,7 @@ 'description' => "{$missingDelegated} delegated permission(s) are missing.", 'links' => [ ['label' => $adminConsentLabel, 'url' => $adminConsentPrimaryUrl, 'external' => true], - ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], + ['label' => 'Open provider connection', 'url' => $manageProviderConnectionUrl ?? $reRunUrl, 'external' => false], ], ]; } @@ -76,7 +81,7 @@ 'title' => 'Verification results need review', 'description' => "{$errorCount} permission row(s) are in an unknown/error state and require follow-up.", 'links' => [ - ['label' => 'Re-run verification', 'url' => $reRunUrl, 'external' => false], + ['label' => 'Open provider connection', 'url' => $manageProviderConnectionUrl ?? $reRunUrl, 'external' => false], $manageProviderConnectionUrl ? ['label' => 'Manage provider connection', 'url' => $manageProviderConnectionUrl, 'external' => false] : ['label' => 'Admin consent guide', 'url' => RequiredPermissionsLinks::adminConsentGuideUrl(), 'external' => true], ], ]; @@ -90,7 +95,7 @@ ? "Permission data is older than 30 days (last refresh {$lastRefreshedLabel})." : 'No stored verification data is available yet.', 'links' => [ - ['label' => 'Start verification', 'url' => $reRunUrl, 'external' => false], + ['label' => 'Open provider connection', 'url' => $manageProviderConnectionUrl ?? $reRunUrl, 'external' => false], ], ]; } @@ -100,36 +105,33 @@
-
-
-
- Review what’s missing for this environment and copy the missing permissions for admin consent. -
-
- Stored-data view only. Last refreshed: {{ $lastRefreshedLabel }}{{ $isStale ? ' (stale)' : '' }}. -
- +
+
@if ($overallSpec) {{ $overallSpec->label }} @endif + + + Stored data · refreshed {{ $lastRefreshedLabel }}{{ $isStale ? ' · stale' : '' }} +
-
-
+
+
Missing (app)
{{ (int) ($counts['missing_application'] ?? 0) }}
-
+
Missing (delegated)
{{ (int) ($counts['missing_delegated'] ?? 0) }}
-
+
Present
{{ (int) ($counts['present'] ?? 0) }}
-
+
Errors
{{ (int) ($counts['error'] ?? 0) }}
@@ -141,11 +143,31 @@
No data available
No stored verification data is available for this environment. - Start verification. + @if ($canRunProviderVerification) + . + @elseif ($manageProviderConnectionUrl) + Open provider connection. + @else + Open environment dashboard. + @endif
@endif + @if (is_array($guidance) && $guidance !== []) + @include('filament.partials.provider-readiness-guidance-card', [ + 'guidance' => $guidance, + 'inlinePrimaryAction' => $showGuidancePrimaryAction, + 'primaryActionMethod' => 'runProviderVerification', + ]) + @endif + @if ($capabilityGroups !== [])
@@ -162,7 +184,7 @@ $primarySpec = BadgeRenderer::spec(BadgeDomain::ProviderCapabilityStatus, $primaryStatus); @endphp - + {{ (string) ($primaryCapabilityGroup['label'] ?? 'Provider capability') }}: {{ $primarySpec->label }} @endif @@ -185,7 +207,7 @@ @endphp
-
+
{{ $capabilityLabel }} @@ -195,7 +217,7 @@
- + {{ $capabilitySpec->label }}
@@ -210,7 +232,7 @@ @endif
-
Guidance
+
Permission handoff
Who can fix this? @@ -227,14 +249,25 @@ class="text-primary-600 hover:underline dark:text-primary-400" {{ $adminConsentLabel }}
- @if ($reRunUrl) + @if ($canRunProviderVerification) +
+ After granting consent: + +
+ @elseif ($manageProviderConnectionUrl) @endif diff --git a/apps/platform/resources/views/filament/partials/provider-readiness-guidance-card.blade.php b/apps/platform/resources/views/filament/partials/provider-readiness-guidance-card.blade.php new file mode 100644 index 00000000..2548dd74 --- /dev/null +++ b/apps/platform/resources/views/filament/partials/provider-readiness-guidance-card.blade.php @@ -0,0 +1,257 @@ +@php + $guidance = is_array($guidance ?? null) ? $guidance : []; + $primaryAction = is_array($guidance['primary_action'] ?? null) ? $guidance['primary_action'] : []; + $secondaryActions = is_array($guidance['secondary_actions'] ?? null) ? $guidance['secondary_actions'] : []; + $technicalDetails = is_array($guidance['technical_details'] ?? null) ? $guidance['technical_details'] : []; + + $inlinePrimaryAction = (bool) ($inlinePrimaryAction ?? false); + $severity = (string) ($guidance['severity'] ?? 'warning'); + $status = (string) ($guidance['status'] ?? ''); + $title = (string) ($guidance['title'] ?? ''); + $reason = (string) ($guidance['reason'] ?? ''); + $impact = (string) ($guidance['impact'] ?? ''); + $actionName = is_string($primaryAction['action_name'] ?? null) ? (string) $primaryAction['action_name'] : null; + $primaryActionUrl = is_string($primaryAction['url'] ?? null) ? (string) $primaryAction['url'] : null; + $primaryActionLabel = (string) ($primaryAction['label'] ?? ''); + $primaryActionExternal = (bool) ($primaryAction['external'] ?? false); + $primaryActionDisabled = (bool) ($primaryAction['disabled'] ?? false); + $primaryActionMethod = is_string($primaryActionMethod ?? null) ? (string) $primaryActionMethod : $actionName; + $canRunPrimaryActionMethod = $inlinePrimaryAction + && $primaryActionMethod !== null + && $actionName === $primaryActionMethod; + + [$badgeColor, $accentClasses] = match ($severity) { + 'success' => [ + 'success', + 'border-l-success-500 dark:border-l-success-400', + ], + 'danger' => [ + 'danger', + 'border-l-danger-500 dark:border-l-danger-400', + ], + default => [ + 'warning', + 'border-l-warning-500 dark:border-l-warning-400', + ], + }; +@endphp + +
+
+
+
+ @if ($status !== '') + + {{ $status }} + + @endif + + @if ($title !== '') +

+ {{ $title }} +

+ @endif +
+ +
+
+ {{ __('localization.provider_guidance.primary_action_label') }} +
+ + @if ($canRunPrimaryActionMethod) + + {{ $primaryActionLabel }} + + @elseif ($inlinePrimaryAction && $primaryActionUrl !== null) + + {{ $primaryActionLabel }} + + @elseif ($primaryActionLabel !== '') +
+ {{ $primaryActionLabel }} +
+ @endif + + @if ($secondaryActions !== []) +
+
+ {{ __('localization.provider_guidance.secondary_actions_label') }} +
+ +
+ @foreach ($secondaryActions as $secondaryAction) + @php + if (! is_array($secondaryAction)) { + continue; + } + + $secondaryUrl = is_string($secondaryAction['url'] ?? null) ? (string) $secondaryAction['url'] : null; + $secondaryLabel = (string) ($secondaryAction['label'] ?? ''); + $secondaryExternal = (bool) ($secondaryAction['external'] ?? false); + @endphp + + @if ($secondaryUrl !== null && $secondaryLabel !== '') + + {{ $secondaryLabel }} + + @endif + @endforeach +
+
+ @endif +
+ + @if ($reason !== '') +
+
+ {{ __('localization.provider_guidance.reason_label') }} +
+

+ {{ $reason }} +

+
+ @endif + + @if ($impact !== '') +
+
+ {{ __('localization.provider_guidance.impact_label') }} +
+

+ {{ $impact }} +

+
+ @endif +
+ + +
+ + @if ($technicalDetails !== []) +
+ + {{ __('localization.provider_guidance.details_label') }} + + +
+ @foreach ($technicalDetails as $detail) + @php + if (! is_array($detail)) { + continue; + } + @endphp + +
+
+ {{ (string) ($detail['label'] ?? '') }} +
+
+ {{ (string) ($detail['value'] ?? '') }} +
+
+ @endforeach +
+
+ @endif +
diff --git a/apps/platform/resources/views/filament/widgets/provider-connections/provider-readiness-guidance.blade.php b/apps/platform/resources/views/filament/widgets/provider-connections/provider-readiness-guidance.blade.php new file mode 100644 index 00000000..71fdfe58 --- /dev/null +++ b/apps/platform/resources/views/filament/widgets/provider-connections/provider-readiness-guidance.blade.php @@ -0,0 +1,7 @@ +@if (is_array($guidance ?? null) && $guidance !== []) + @include('filament.partials.provider-readiness-guidance-card', [ + 'guidance' => $guidance, + 'inlinePrimaryAction' => $inlinePrimaryAction ?? false, + 'primaryActionMethod' => $primaryActionMethod ?? null, + ]) +@endif diff --git a/apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php b/apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php index 973673b1..9b3fdd68 100644 --- a/apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php +++ b/apps/platform/tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php @@ -85,8 +85,10 @@ visit(ManagedEnvironmentLinks::viewUrl($tenant)) ->waitForText('Provider Health') ->assertScript("window.location.pathname === '{$tenantViewPath}'", true) - ->assertSee('Spec 281 Browser Connection') ->assertSee('Spec 281 Browser Environment') + ->assertSee('Healthy') + ->assertSee('Granted') + ->assertSee('Open Provider Connections') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); }); diff --git a/apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php b/apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php new file mode 100644 index 00000000..bd3f8256 --- /dev/null +++ b/apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php @@ -0,0 +1,269 @@ +browser()->timeout(40_000); + +beforeEach(function (): void { + config()->set('graph.client_id', 'spec353-platform-client'); + config()->set('graph.client_secret', 'spec353-platform-secret'); + config()->set('graph.managed_environment_id', 'organizations'); +}); + +function spec353BrowserApplicationPermissionKey(): string +{ + $permission = collect(spec283ConfiguredPermissionRows()) + ->first(static fn (mixed $row): bool => is_array($row) && ($row['type'] ?? null) === 'application'); + + expect($permission)->not->toBeNull(); + + return (string) $permission['key']; +} + +function spec353BrowserSeedPermissionRows( + ManagedEnvironment $environment, + array $missingKeys = [], + array $errorKeys = [], + ?\DateTimeInterface $lastCheckedAt = null, +): void { + foreach (spec283ConfiguredPermissionRows() as $permission) { + if (! is_array($permission)) { + continue; + } + + $permissionKey = (string) ($permission['key'] ?? ''); + + if ($permissionKey === '') { + continue; + } + + ManagedEnvironmentPermission::query()->updateOrCreate( + [ + 'managed_environment_id' => (int) $environment->getKey(), + 'permission_key' => $permissionKey, + 'workspace_id' => (int) $environment->workspace_id, + ], + [ + 'status' => in_array($permissionKey, $errorKeys, true) + ? 'error' + : (in_array($permissionKey, $missingKeys, true) ? 'missing' : 'granted'), + 'details' => ['source' => 'spec353-browser-test'], + 'last_checked_at' => $lastCheckedAt ?? now(), + ], + ); + } +} + +/** + * @return array{ + * user: User, + * workspace: Workspace, + * blockedEnvironment: ManagedEnvironment, + * blockedConnection: ProviderConnection, + * failedEnvironment: ManagedEnvironment, + * failedConnection: ProviderConnection, + * readyEnvironment: ManagedEnvironment, + * readyConnection: ProviderConnection, + * } + */ +function spec353BrowserFixture(): array +{ + [$user, $blockedEnvironment] = createUserWithTenant( + role: 'owner', + workspaceRole: 'owner', + ensureDefaultMicrosoftProviderConnection: false, + ); + + $workspace = $blockedEnvironment->workspace()->firstOrFail(); + + $failedEnvironment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'name' => 'Spec353 Verification Failed', + ]); + $readyEnvironment = ManagedEnvironment::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'name' => 'Spec353 Provider Ready', + ]); + + $user->tenants()->syncWithoutDetaching([ + (int) $failedEnvironment->getKey() => ['role' => 'owner'], + (int) $readyEnvironment->getKey() => ['role' => 'owner'], + ]); + + $blockedConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $blockedEnvironment->getKey(), + 'workspace_id' => (int) $workspace->getKey(), + 'display_name' => 'Spec353 Blocked Connection', + 'is_default' => true, + ]); + $failedConnection = ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $failedEnvironment->getKey(), + 'workspace_id' => (int) $workspace->getKey(), + 'display_name' => 'Spec353 Failed Connection', + 'is_default' => true, + 'verification_status' => ProviderVerificationStatus::Error->value, + 'last_error_message' => 'Spec353 verification failed during health check.', + ]); + $readyConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $readyEnvironment->getKey(), + 'workspace_id' => (int) $workspace->getKey(), + 'display_name' => 'Spec353 Ready Connection', + 'is_default' => true, + 'last_health_check_at' => now(), + ]); + + $missingPermissionKey = spec353BrowserApplicationPermissionKey(); + spec353BrowserSeedPermissionRows($blockedEnvironment, missingKeys: [$missingPermissionKey]); + spec353BrowserSeedPermissionRows($failedEnvironment); + spec353BrowserSeedPermissionRows($readyEnvironment); + + OperationRun::factory()->create([ + 'workspace_id' => (int) $workspace->getKey(), + 'managed_environment_id' => (int) $failedEnvironment->getKey(), + 'type' => 'provider.connection.check', + 'status' => OperationRunStatus::Completed->value, + 'outcome' => OperationRunOutcome::Failed->value, + 'context' => [ + 'provider_connection_id' => (int) $failedConnection->getKey(), + ], + ]); + + return [ + 'user' => $user, + 'workspace' => $workspace, + 'blockedEnvironment' => $blockedEnvironment, + 'blockedConnection' => $blockedConnection, + 'failedEnvironment' => $failedEnvironment, + 'failedConnection' => $failedConnection, + 'readyEnvironment' => $readyEnvironment, + 'readyConnection' => $readyConnection, + ]; +} + +function spec353BrowserActAs(User $user, Workspace $workspace, ManagedEnvironment $environment): void +{ + test()->actingAs($user)->withSession([ + WorkspaceContext::SESSION_KEY => (int) $workspace->getKey(), + WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [ + (string) $workspace->getKey() => (int) $environment->getKey(), + ], + ]); +} + +function spec353BrowserScreenshot(string $name): string +{ + return 'spec353-'.$name; +} + +function spec353CopyBrowserScreenshot(string $name): void +{ + $filename = spec353BrowserScreenshot($name).'.png'; + $source = \Pest\Browser\Support\Screenshot::path($filename); + $targetDirectory = repo_path('specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots'); + + if (! is_dir($targetDirectory)) { + @mkdir($targetDirectory, 0755, true); + } + + if (! is_dir($targetDirectory) || ! is_writable($targetDirectory)) { + return; + } + + if (is_file($source)) { + @copy($source, $targetDirectory.DIRECTORY_SEPARATOR.$filename); + } +} + +function spec353BrowserTextContainsScript(string $selector, string $text): string +{ + $encodedSelector = json_encode($selector); + $encodedText = json_encode($text); + + return << { + const element = document.querySelector($encodedSelector); + + if (! element) { + return false; + } + + return element.textContent.replace(/\\s+/g, ' ').trim().includes($encodedText); +})() +JS; +} + +it('smokes provider readiness guidance across dashboard, required permissions, provider connections, and screenshots', function (): void { + $fixture = spec353BrowserFixture(); + + spec353BrowserActAs($fixture['user'], $fixture['workspace'], $fixture['blockedEnvironment']); + + $blockedPermissionsPage = visit(ManagedEnvironmentLinks::requiredPermissionsUrl($fixture['blockedEnvironment'])) + ->resize(1440, 1100) + ->waitForText(__('localization.provider_guidance.required_permissions_missing_title')) + ->assertScript( + spec353BrowserTextContainsScript( + '[data-testid="provider-readiness-reason"]', + __('localization.provider_guidance.required_application_permissions_reason'), + ), + true, + ) + ->assertSee(__('localization.provider_guidance.action_open_admin_consent')) + ->assertScript('document.querySelector("[data-testid=\"provider-readiness-details\"]")?.open === false', true) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs() + ->screenshot(true, spec353BrowserScreenshot('01-required-permissions-blocked')); + + spec353CopyBrowserScreenshot('01-required-permissions-blocked'); + + $blockedPermissionsPage->resize(900, 1100) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); + + visit(EnvironmentDashboard::getUrl(panel: 'admin', tenant: $fixture['blockedEnvironment'])) + ->waitForText('Provider readiness blocks evidence refresh') + ->click('[data-testid="tenant-dashboard-primary-next-action"] a') + ->waitForText(__('localization.provider_guidance.required_permissions_missing_title')) + ->assertScript( + spec353BrowserTextContainsScript( + '[data-testid="provider-readiness-reason"]', + __('localization.provider_guidance.required_application_permissions_reason'), + ), + true, + ) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); + + visit(ManagedEnvironmentLinks::providerConnectionUrl($fixture['failedConnection'], 'view', $fixture['failedEnvironment'])) + ->resize(1440, 1100) + ->waitForText(__('localization.provider_guidance.verification_failed_title')) + ->assertSee(__('localization.provider_guidance.action_open_verification_operation')) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs() + ->screenshot(true, spec353BrowserScreenshot('02-provider-connection-verification-failed')); + + spec353CopyBrowserScreenshot('02-provider-connection-verification-failed'); + + visit(ManagedEnvironmentLinks::providerConnectionUrl($fixture['readyConnection'], 'view', $fixture['readyEnvironment'])) + ->resize(1440, 1100) + ->waitForText(__('localization.provider_guidance.ready_title')) + ->assertSee(__('localization.provider_guidance.ready_reason')) + ->assertSee(__('localization.provider_guidance.action_open_environment_dashboard')) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs() + ->screenshot(true, spec353BrowserScreenshot('03-provider-connection-ready')); + + spec353CopyBrowserScreenshot('03-provider-connection-ready'); +}); diff --git a/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php b/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php index 057d0e08..fd248885 100644 --- a/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php +++ b/apps/platform/tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php @@ -17,7 +17,7 @@ Http::preventStrayRequests(); }); -test('unauthorized tenant filter yields an empty list without leaking metadata', function () { +test('unauthorized provider-connections route scope resolves deny-as-not-found without leaking metadata', function () { $tenant = ManagedEnvironment::factory()->create(); $otherTenant = ManagedEnvironment::factory()->create(); @@ -31,8 +31,7 @@ $this->actingAs($user) ->get(ProviderConnectionResource::getUrl('index', tenant: $tenant)) - ->assertOk() - ->assertDontSee('Unauthorized ManagedEnvironment Connection'); + ->assertNotFound(); }); test('non-members cannot reach provider connection detail target-scope metadata', function (): void { diff --git a/apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php b/apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php new file mode 100644 index 00000000..bbe208d2 --- /dev/null +++ b/apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php @@ -0,0 +1,162 @@ +set('graph.client_id', 'spec353-platform-client'); + config()->set('graph.client_secret', 'spec353-platform-secret'); + config()->set('graph.managed_environment_id', 'organizations'); +}); + +function spec353RequiredPermissionsApplicationPermissionKey(): string +{ + $permission = collect(spec283ConfiguredPermissionRows()) + ->first(static fn (mixed $row): bool => is_array($row) && ($row['type'] ?? null) === 'application'); + + expect($permission)->not->toBeNull(); + + return (string) $permission['key']; +} + +function spec353RequiredPermissionsSeedRows( + ManagedEnvironment $environment, + array $missingKeys = [], + array $errorKeys = [], + ?string $lastCheckedAt = null, +): void { + foreach (spec283ConfiguredPermissionRows() as $permission) { + if (! is_array($permission)) { + continue; + } + + $permissionKey = (string) ($permission['key'] ?? ''); + + if ($permissionKey === '') { + continue; + } + + ManagedEnvironmentPermission::query()->updateOrCreate( + [ + 'managed_environment_id' => (int) $environment->getKey(), + 'permission_key' => $permissionKey, + 'workspace_id' => (int) $environment->workspace_id, + ], + [ + 'status' => in_array($permissionKey, $errorKeys, true) + ? 'error' + : (in_array($permissionKey, $missingKeys, true) ? 'missing' : 'granted'), + 'details' => ['source' => 'spec353-required-permissions-test'], + 'last_checked_at' => $lastCheckedAt ? Carbon::parse($lastCheckedAt) : now(), + ], + ); + } +} + +function spec353RequiredPermissionsComponent(User $user, ManagedEnvironment $environment, array $query = []) +{ + test()->actingAs($user); + setAdminPanelContext($environment); + session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id); + + return Livewire::withQueryParams($query)->test(EnvironmentRequiredPermissions::class, [ + 'environment' => $environment, + ]); +} + +it('renders guidance before the raw permissions matrix on the required-permissions page', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + ]); + + $missingPermissionKey = spec353RequiredPermissionsApplicationPermissionKey(); + spec353RequiredPermissionsSeedRows($environment, missingKeys: [$missingPermissionKey]); + + $response = $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(RequiredPermissionsLinks::requiredPermissions($environment)) + ->assertSuccessful(); + + $content = $response->getContent(); + $primaryActionUrl = RequiredPermissionsLinks::adminConsentPrimaryUrl($environment); + + expect($content)->toContain(__('localization.provider_guidance.required_permissions_missing_title')) + ->and($content)->toContain($missingPermissionKey) + ->and(strpos($content, 'data-testid="provider-readiness-guidance-card"'))->toBeLessThan(strpos($content, $missingPermissionKey)) + ->and($content)->toContain('data-testid="provider-readiness-primary-action"') + ->and($content)->toContain('href="'.e($primaryActionUrl).'"'); +}); + +it('shows run-verification guidance when stored verification evidence is stale or absent', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'verification_status' => ProviderVerificationStatus::Unknown->value, + 'last_health_check_at' => null, + ]); + + spec353RequiredPermissionsSeedRows( + $environment, + lastCheckedAt: now()->subDays(45)->toIso8601String(), + ); + + $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(RequiredPermissionsLinks::requiredPermissions($environment)) + ->assertSuccessful() + ->assertSee(__('localization.provider_guidance.verification_required_title')) + ->assertSee(__('localization.provider_guidance.action_run_provider_verification')) + ->assertSee('wire:click="runProviderVerification"', false) + ->assertDontSee('Start verification'); +}); + +it('renders required-permissions guidance without Graph, outbound http, or queue dispatches', function (): void { + bindFailHardGraphClient(); + + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + ]); + + spec353RequiredPermissionsSeedRows($environment); + Queue::fake(); + + assertNoOutboundHttp(function () use ($user, $environment): void { + $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(RequiredPermissionsLinks::requiredPermissions($environment)) + ->assertSuccessful(); + }); + + Queue::assertNothingPushed(); +}); diff --git a/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php b/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php index da7f23b8..7e5fa64b 100644 --- a/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php +++ b/apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php @@ -2,13 +2,12 @@ declare(strict_types=1); -use App\Filament\Pages\EnvironmentRequiredPermissions; use App\Models\ManagedEnvironment; use App\Models\ManagedEnvironmentPermission; use App\Models\User; +use App\Support\Links\RequiredPermissionsLinks; use App\Support\Workspaces\WorkspaceContext; use Illuminate\Foundation\Testing\RefreshDatabase; -use Livewire\Livewire; uses(RefreshDatabase::class); @@ -53,74 +52,56 @@ function seedEnvironmentRequiredPermissionsFixture(ManagedEnvironment $tenant): ]); } -function tenantRequiredPermissionsComponent(User $user, ManagedEnvironment $tenant, array $query = []) -{ - test()->actingAs($user); - setAdminPanelContext(); - session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); - - $query = array_merge([ - 'tenant' => (string) $tenant->external_id, - ], $query); - - return Livewire::withQueryParams($query)->test(EnvironmentRequiredPermissions::class); -} - -it('uses native table filters and search while keeping summary state aligned with visible rows', function (): void { +it('uses route-seeded filters and search while keeping the visible permission matrix aligned', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); seedEnvironmentRequiredPermissionsFixture($tenant); - $component = tenantRequiredPermissionsComponent($user, $tenant) - ->assertTableFilterExists('status') - ->assertTableFilterExists('type') - ->assertTableFilterExists('features') - ->assertCanSeeTableRecords([ - 'DeviceManagementApps.Read.All', - 'Group.Read.All', - ]) - ->assertCanNotSeeTableRecords(['Reports.Read.All']) - ->assertSee('Missing application permissions') - ->assertSee('Guidance'); + $this->actingAs($user) + ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) + ->get(RequiredPermissionsLinks::requiredPermissions($tenant)) + ->assertSuccessful() + ->assertSee('DeviceManagementApps.Read.All') + ->assertSee('Group.Read.All') + ->assertDontSee('Reports.Read.All') + ->assertSee('data-testid="provider-readiness-guidance-card"', false); - $component - ->filterTable('status', 'present') - ->filterTable('type', 'application') - ->searchTable('Reports') - ->assertCountTableRecords(1) - ->assertCanSeeTableRecords(['Reports.Read.All']) - ->assertCanNotSeeTableRecords([ - 'DeviceManagementApps.Read.All', - 'Group.Read.All', - ]); - - $viewModel = $component->instance()->viewModel(); - - expect($viewModel['overview']['counts'])->toBe([ - 'missing_application' => 0, - 'missing_delegated' => 0, - 'present' => 1, - 'error' => 0, - ]) - ->and(array_column($viewModel['permissions'], 'key'))->toBe(['Reports.Read.All']) - ->and($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All'); + $this->actingAs($user) + ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) + ->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ + 'status' => 'present', + 'type' => 'application', + 'search' => 'Reports', + ])) + ->assertSuccessful() + ->assertSee('Reports.Read.All') + ->assertSee('1 permission(s) currently pass.'); }); it('keeps copy payloads feature-scoped and shows the native no-matches state', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); seedEnvironmentRequiredPermissionsFixture($tenant); - $component = tenantRequiredPermissionsComponent($user, $tenant) - ->set('tableFilters.features.values', ['backup']) - ->assertSet('tableFilters.features.values', ['backup']); + $this->actingAs($user) + ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) + ->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ + 'status' => 'all', + 'features' => ['backup'], + ])) + ->assertSuccessful() + ->assertSee('DeviceManagementApps.Read.All') + ->assertSee('Group.Read.All') + ->assertDontSee('Reports.Read.All') + ->assertSee('Copy missing application permissions') + ->assertSee('Copy missing delegated permissions'); - $viewModel = $component->instance()->viewModel(); - - expect($viewModel['copy']['application'])->toBe('DeviceManagementApps.Read.All') - ->and($viewModel['copy']['delegated'])->toBe('Group.Read.All'); - - $component - ->searchTable('no-such-permission') - ->assertCountTableRecords(0) + $this->actingAs($user) + ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) + ->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ + 'status' => 'all', + 'features' => ['backup'], + 'search' => 'no-such-permission', + ])) + ->assertSuccessful() ->assertSee('No matches') - ->assertTableEmptyStateActionsExistInOrder(['clear_filters']); + ->assertSee('Clear filters'); }); diff --git a/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php b/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php index 310296f8..c736f826 100644 --- a/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php +++ b/apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php @@ -1765,7 +1765,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser $response->assertOk() ->assertSee('Copy missing application permissions') ->assertSee('Copy missing delegated permissions') - ->assertSee('Re-run verification') + ->assertSee('Permission handoff') ->assertSee('Start verification'); $declaration = EnvironmentRequiredPermissions::actionSurfaceDeclaration(); @@ -2196,7 +2196,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser Filament::setTenant($tenant, true); $component = Livewire::test(ViewProviderConnection::class, ['record' => $connection->getKey()]) - ->assertActionVisible('grant_admin_consent'); + ->assertActionVisible('open_required_permissions'); $instance = $component->instance(); @@ -2219,7 +2219,7 @@ function actionSurfaceSystemPanelContext(array $capabilities): PlatformUser ->values() ->all(); - expect($primaryHeaderActions)->toEqual(['grant_admin_consent']) + expect($primaryHeaderActions)->toEqual(['open_required_permissions']) ->and($moreGroup)->toBeInstanceOf(ActionGroup::class) ->and($moreGroup?->getLabel())->toBe('More') ->and($moreActionNames)->toEqualCanonicalizing([ diff --git a/apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php b/apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php new file mode 100644 index 00000000..56fe97b3 --- /dev/null +++ b/apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php @@ -0,0 +1,180 @@ +set('graph.client_id', 'spec353-platform-client'); + config()->set('graph.client_secret', 'spec353-platform-secret'); + config()->set('graph.managed_environment_id', 'organizations'); +}); + +function spec353FeatureApplicationPermissionKey(): string +{ + $permission = collect(spec283ConfiguredPermissionRows()) + ->first(static fn (mixed $row): bool => is_array($row) && ($row['type'] ?? null) === 'application'); + + expect($permission)->not->toBeNull(); + + return (string) $permission['key']; +} + +function spec353FeatureSeedPermissionRows( + ManagedEnvironment $environment, + array $missingKeys = [], + array $errorKeys = [], +): void { + foreach (spec283ConfiguredPermissionRows() as $permission) { + if (! is_array($permission)) { + continue; + } + + $permissionKey = (string) ($permission['key'] ?? ''); + + if ($permissionKey === '') { + continue; + } + + ManagedEnvironmentPermission::query()->updateOrCreate( + [ + 'managed_environment_id' => (int) $environment->getKey(), + 'permission_key' => $permissionKey, + 'workspace_id' => (int) $environment->workspace_id, + ], + [ + 'status' => in_array($permissionKey, $errorKeys, true) + ? 'error' + : (in_array($permissionKey, $missingKeys, true) ? 'missing' : 'granted'), + 'details' => ['source' => 'spec353-feature-test'], + 'last_checked_at' => now(), + ], + ); + } +} + +function spec353ProviderConnectionDetailComponent(User $user, ManagedEnvironment $environment, ProviderConnection $connection) +{ + test()->actingAs($user); + setAdminPanelContext($environment); + Filament::setTenant($environment, true); + session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id); + + return Livewire::test(ViewProviderConnection::class, ['record' => $connection->getKey()]); +} + +it('shows decision-first guidance on the provider-connections list when no connection exists', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(ManagedEnvironmentLinks::providerConnectionsUrl($environment)) + ->assertSuccessful() + ->assertSee(__('localization.provider_guidance.connection_missing_title')) + ->assertSee('Create provider connection') + ->assertSee('data-testid="provider-readiness-primary-action"', false) + ->assertSee(ProviderConnectionResource::getUrl('create', [ + 'environment_id' => (int) $environment->getKey(), + ], panel: 'admin')) + ->assertDontSee('Fix provider') + ->assertDontSee('Grant permissions automatically'); +}); + +it('shows required-permissions guidance on provider-connection detail when application permissions are missing', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + ]); + + spec353FeatureSeedPermissionRows($environment, missingKeys: [spec353FeatureApplicationPermissionKey()]); + + spec353ProviderConnectionDetailComponent($user, $environment, $connection) + ->assertSee(__('localization.provider_guidance.provider_readiness_blocked_title')) + ->assertSee(__('localization.provider_guidance.required_application_permissions_reason')) + ->assertActionVisible('open_required_permissions') + ->assertDontSee('Fix provider') + ->assertDontSee('Grant permissions automatically'); +}); + +it('shows verification-operation guidance on provider-connection detail when verification failed', function (): void { + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'verification_status' => ProviderVerificationStatus::Error->value, + 'last_error_message' => 'Verification job failed for this provider connection.', + ]); + + spec353FeatureSeedPermissionRows($environment); + + OperationRun::factory()->create([ + 'workspace_id' => (int) $environment->workspace_id, + 'managed_environment_id' => (int) $environment->getKey(), + 'type' => 'provider.connection.check', + 'context' => [ + 'provider_connection_id' => (int) $connection->getKey(), + ], + ]); + + spec353ProviderConnectionDetailComponent($user, $environment, $connection) + ->assertSee(__('localization.provider_guidance.verification_failed_title')) + ->assertActionVisible('open_verification_operation'); +}); + +it('renders provider connection guidance without Graph, outbound http, or queue work on the render path', function (): void { + bindFailHardGraphClient(); + + [$user, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + ]); + + spec353FeatureSeedPermissionRows($environment); + Queue::fake(); + + assertNoOutboundHttp(function () use ($user, $environment, $connection): void { + $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(ManagedEnvironmentLinks::providerConnectionsUrl($environment)) + ->assertSuccessful(); + + $this->actingAs($user) + ->withSession([ + WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id, + ]) + ->get(ProviderConnectionResource::getUrl('view', [ + 'record' => $connection, + 'environment_id' => (int) $environment->getKey(), + ], panel: 'admin')) + ->assertSuccessful(); + }); + + Queue::assertNothingPushed(); +}); diff --git a/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php b/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php index 52058eea..e54437f0 100644 --- a/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php +++ b/apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php @@ -10,7 +10,6 @@ use App\Models\WorkspaceMembership; use App\Support\Links\RequiredPermissionsLinks; use App\Support\Workspaces\WorkspaceContext; -use Livewire\Livewire; it('keeps the route tenant authoritative when tenant-like query values are present', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); @@ -127,24 +126,18 @@ 'last_checked_at' => now(), ]); - $this->actingAs($user); - setAdminPanelContext(); - session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); - - $component = Livewire::withQueryParams([ - 'tenant' => $tenant->external_id, - 'managed_environment_id' => (string) $otherTenant->getKey(), - 'status' => 'present', - 'type' => 'application', - 'features' => ['backup'], - 'search' => 'ManagedEnvironment', - ])->test(EnvironmentRequiredPermissions::class); - - $component - ->assertSet('tableFilters.status.value', 'present') - ->assertSet('tableFilters.type.value', 'application') - ->assertSet('tableFilters.features.values', ['backup']) - ->assertSet('tableSearch', 'ManagedEnvironment'); - - expect($component->instance()->currentTenant()?->is($tenant))->toBeTrue(); + $this->actingAs($user) + ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) + ->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ + 'tenant' => $tenant->external_id, + 'managed_environment_id' => (string) $otherTenant->getKey(), + 'status' => 'present', + 'type' => 'application', + 'features' => ['backup'], + 'search' => 'ManagedEnvironment', + ])) + ->assertSuccessful() + ->assertSee($tenant->getFilamentName()) + ->assertDontSee($otherTenant->name) + ->assertSee('ManagedEnvironment.Read.All'); }); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php index 33a00921..fc7a8245 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php @@ -5,7 +5,7 @@ use App\Models\ManagedEnvironment; use App\Support\Links\RequiredPermissionsLinks; -it('renders guidance, admin consent link, re-run verification, and copy actions on the required permissions page', function (): void { +it('renders provider guidance, admin consent handoff, and copy actions on the required permissions page', function (): void { $tenant = ManagedEnvironment::factory()->create([ 'external_id' => 'tenant-copy-actions-a', 'app_client_id' => null, @@ -16,11 +16,13 @@ $this->actingAs($user) ->get(RequiredPermissionsLinks::requiredPermissions($tenant)) ->assertSuccessful() - ->assertSee('Guidance') + ->assertSee('Permission handoff') ->assertSee('Who can fix this?', false) ->assertSee('Admin consent guide') ->assertSee('learn.microsoft.com/en-us/entra/identity/enterprise-apps/grant-admin-consent', false) - ->assertSee('Re-run verification') + ->assertDontSee('Start verification') + ->assertSee('Open provider connection') + ->assertSee('Open provider connection to run verification') ->assertSee('Copy missing application permissions') ->assertSee('Copy missing delegated permissions'); }); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php index c6662091..d6bda851 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php @@ -2,18 +2,19 @@ declare(strict_types=1); -use App\Filament\Resources\ManagedEnvironmentResource; use App\Support\Links\RequiredPermissionsLinks; +use App\Support\ManagedEnvironmentLinks; -it('renders the no-data state with a canonical start verification link when no stored permission data exists', function (): void { +it('renders the no-data state with a canonical provider connection link when no stored permission data exists', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - $expectedUrl = ManagedEnvironmentResource::getUrl('view', ['record' => $tenant]); + $expectedUrl = ManagedEnvironmentLinks::providerConnectionsUrl($tenant); $this->actingAs($user) ->get(RequiredPermissionsLinks::requiredPermissions($tenant)) ->assertSuccessful() ->assertSee('No data available') ->assertSee($expectedUrl, false) - ->assertSee('Start verification'); + ->assertSee('Open provider connection') + ->assertDontSee('Start verification'); }); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php index 9d8c7dea..48d64634 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php @@ -2,10 +2,9 @@ declare(strict_types=1); -use App\Filament\Pages\EnvironmentRequiredPermissions; use App\Models\ManagedEnvironmentPermission; +use App\Support\Links\RequiredPermissionsLinks; use App\Support\Workspaces\WorkspaceContext; -use Livewire\Livewire; it('narrows required permissions results using filters and search', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); @@ -60,67 +59,45 @@ setAdminPanelContext(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); - Livewire::withQueryParams([ - 'tenant' => (string) $tenant->external_id, - ]) - ->test(EnvironmentRequiredPermissions::class) - ->assertSet('tableFilters.status.value', 'missing') + $this->get(RequiredPermissionsLinks::requiredPermissions($tenant)) + ->assertSuccessful() ->assertSee('All required permissions are present') - ->assertCanNotSeeTableRecords([ - 'Alpha.Read.All', - 'Beta.Read.All', - 'Gamma.Manage.All', - ]); + ->assertDontSee('Alpha.Read.All') + ->assertDontSee('Beta.Read.All') + ->assertDontSee('Gamma.Manage.All'); - Livewire::withQueryParams([ - 'tenant' => (string) $tenant->external_id, + $this->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ 'status' => 'present', - ]) - ->test(EnvironmentRequiredPermissions::class) - ->assertSet('tableFilters.status.value', 'present') - ->assertCanSeeTableRecords([ - 'Alpha.Read.All', - 'Beta.Read.All', - 'Gamma.Manage.All', - ]); + ])) + ->assertSuccessful() + ->assertSee('Alpha.Read.All') + ->assertSee('Beta.Read.All') + ->assertSee('Gamma.Manage.All'); - Livewire::withQueryParams([ - 'tenant' => (string) $tenant->external_id, + $this->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ 'status' => 'present', 'type' => 'delegated', - ]) - ->test(EnvironmentRequiredPermissions::class) - ->assertSet('tableFilters.status.value', 'present') - ->assertSet('tableFilters.type.value', 'delegated') - ->assertCanSeeTableRecords(['Beta.Read.All']) - ->assertCanNotSeeTableRecords([ - 'Alpha.Read.All', - 'Gamma.Manage.All', - ]); + ])) + ->assertSuccessful() + ->assertSee('Beta.Read.All') + ->assertDontSee('Alpha.Read.All') + ->assertDontSee('Gamma.Manage.All'); - Livewire::withQueryParams([ - 'tenant' => (string) $tenant->external_id, + $this->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ 'status' => 'all', 'features' => ['backup'], - ]) - ->test(EnvironmentRequiredPermissions::class) - ->assertSet('tableFilters.features.values', ['backup']) - ->assertCanSeeTableRecords([ - 'Alpha.Read.All', - 'Gamma.Manage.All', - ]) - ->assertCanNotSeeTableRecords(['Beta.Read.All']); + ])) + ->assertSuccessful() + ->assertSee('Alpha.Read.All') + ->assertSee('Gamma.Manage.All') + ->assertDontSee('Beta.Read.All'); - Livewire::withQueryParams([ - 'tenant' => (string) $tenant->external_id, + $this->get(RequiredPermissionsLinks::requiredPermissions($tenant, [ 'status' => 'all', 'search' => 'delegated', - ]) - ->test(EnvironmentRequiredPermissions::class) - ->assertSet('tableSearch', 'delegated') - ->assertCanSeeTableRecords(['Beta.Read.All']) - ->assertCanNotSeeTableRecords([ - 'Alpha.Read.All', - 'Gamma.Manage.All', - ]); + ])) + ->assertSuccessful() + ->assertSee('Beta.Read.All') + ->assertDontSee('Alpha.Read.All') + ->assertDontSee('Gamma.Manage.All'); }); diff --git a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php index 7292af22..37ffb1d4 100644 --- a/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php +++ b/apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php @@ -2,19 +2,21 @@ declare(strict_types=1); -use App\Filament\Resources\ManagedEnvironmentResource; +use App\Support\ManagedEnvironmentLinks; use App\Support\Links\RequiredPermissionsLinks; -it('renders re-run verification and next-step links using canonical manage surfaces only', function (): void { +it('renders no-data navigation and next-step links using canonical manage surfaces only', function (): void { [$user, $tenant] = createUserWithTenant(role: 'readonly'); - $expectedUrl = ManagedEnvironmentResource::getUrl('view', ['record' => $tenant]); + $expectedUrl = ManagedEnvironmentLinks::providerConnectionsUrl($tenant); $this->actingAs($user) ->get(RequiredPermissionsLinks::requiredPermissions($tenant)) ->assertSuccessful() - ->assertSee('Re-run verification') + ->assertSee('Open provider connection') ->assertSee($expectedUrl, false) + ->assertDontSee('Start verification') + ->assertDontSee('wire:click="runProviderVerification"', false) ->assertDontSee('/admin/t/', false); }); diff --git a/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php b/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php index 9a778bdf..e929f667 100644 --- a/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php +++ b/apps/platform/tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php @@ -40,7 +40,7 @@ ->assertSee('Provider Health'); }); -it('renders the environment dashboard provider health summary from the default connection', function (): void { +it('renders the environment dashboard provider health summary from the default connection posture', function (): void { $tenant = \App\Models\ManagedEnvironment::factory()->active()->create(); [$user, $tenant] = createUserWithTenant( tenant: $tenant, @@ -63,7 +63,6 @@ ->get(ManagedEnvironmentResource::getUrl('view', ['record' => $tenant], tenant: $tenant)) ->assertOk() ->assertSee('Provider Health') - ->assertSee('Canonical Summary Connection') ->assertSee('Disabled') ->assertSee('Healthy') ->assertDontSee('Connected') diff --git a/apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php b/apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php new file mode 100644 index 00000000..9f7402b6 --- /dev/null +++ b/apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php @@ -0,0 +1,181 @@ +set('graph.client_id', 'spec353-platform-client'); + config()->set('graph.client_secret', 'spec353-platform-secret'); + config()->set('graph.managed_environment_id', 'organizations'); +}); + +function mockSpec353PermissionOverview(array $overview = []): void +{ + mock(ManagedEnvironmentRequiredPermissionsViewModelBuilder::class, function ($mock) use ($overview): void { + $mock->shouldReceive('build')->andReturn([ + 'overview' => array_replace_recursive([ + 'counts' => [ + 'missing_application' => 0, + 'missing_delegated' => 0, + 'present' => 12, + 'error' => 0, + ], + 'freshness' => [ + 'last_refreshed_at' => now()->toIso8601String(), + 'is_stale' => false, + ], + ], $overview), + ]); + }); +} + +it('returns connection-missing guidance when no default provider connection exists', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + mockSpec353PermissionOverview(); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forEnvironment($environment, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_INDEX); + + expect($case['key'])->toBe('provider_readiness.connection_missing') + ->and(data_get($case, 'primary_action.url'))->toBe(ManagedEnvironmentLinks::providerConnectionsUrl($environment)) + ->and((string) data_get($case, 'status'))->toBe(__('localization.provider_guidance.status_blocked')); +}); + +it('distinguishes admin-consent blockers from missing-permission blockers', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'consent_status' => ProviderConsentStatus::Required->value, + 'verification_status' => ProviderVerificationStatus::Unknown->value, + ]); + + mockSpec353PermissionOverview([ + 'counts' => [ + 'missing_application' => 3, + ], + ]); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($environment, $connection, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW); + + expect($case['key'])->toBe('provider_readiness.admin_consent_required') + ->and((string) data_get($case, 'primary_action.label'))->toBe(__('localization.provider_guidance.action_open_admin_consent')) + ->and((string) data_get($case, 'reason'))->toBe(__('localization.provider_guidance.admin_consent_required_reason')); +}); + +it('returns required-permissions guidance when application permissions are missing', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->consentGranted()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + ]); + + mockSpec353PermissionOverview([ + 'counts' => [ + 'missing_application' => 2, + 'present' => 10, + ], + ]); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($environment, $connection, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW); + + expect($case['key'])->toBe('provider_readiness.required_permissions_missing') + ->and((string) data_get($case, 'primary_action.label'))->toBe(__('localization.provider_guidance.action_open_required_permissions')) + ->and((string) data_get($case, 'reason'))->toBe(__('localization.provider_guidance.required_application_permissions_reason')); +}); + +it('returns verification-required guidance when verification has not run yet', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'verification_status' => ProviderVerificationStatus::Unknown->value, + 'last_health_check_at' => null, + ]); + + mockSpec353PermissionOverview([ + 'freshness' => [ + 'last_refreshed_at' => null, + 'is_stale' => true, + ], + ]); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($environment, $connection, ProviderReadinessResolutionAdapter::SURFACE_REQUIRED_PERMISSIONS); + + expect($case['key'])->toBe('provider_readiness.verification_required') + ->and((string) data_get($case, 'primary_action.action_name'))->toBe('runProviderVerification') + ->and((string) data_get($case, 'primary_action.label'))->toBe(__('localization.provider_guidance.action_run_provider_verification')); +}); + +it('returns verification-failed guidance with an operation link when a failed run exists', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'verification_status' => ProviderVerificationStatus::Error->value, + 'last_error_message' => 'Graph verification failed for this connection.', + ]); + + $run = OperationRun::factory()->create([ + 'workspace_id' => (int) $environment->workspace_id, + 'managed_environment_id' => (int) $environment->getKey(), + 'type' => 'provider.connection.check', + 'context' => [ + 'provider_connection_id' => (int) $connection->getKey(), + ], + ]); + + mockSpec353PermissionOverview(); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($environment, $connection, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW); + + expect($case['key'])->toBe('provider_readiness.verification_failed') + ->and((string) data_get($case, 'primary_action.url'))->toBe(OperationRunLinks::view($run, $environment)) + ->and((string) data_get($case, 'reason'))->toContain('Graph verification failed'); +}); + +it('returns a ready case when provider signals are satisfied', function (): void { + [, $environment] = createUserWithTenant(role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false); + + $connection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ + 'managed_environment_id' => (int) $environment->getKey(), + 'workspace_id' => (int) $environment->workspace_id, + 'is_default' => true, + 'last_health_check_at' => now(), + ]); + + mockSpec353PermissionOverview(); + + $case = app(ProviderReadinessResolutionAdapter::class) + ->forConnection($environment, $connection, ProviderReadinessResolutionAdapter::SURFACE_PROVIDER_CONNECTIONS_VIEW); + + expect($case['key'])->toBe('provider_readiness.ready') + ->and((string) data_get($case, 'primary_action.url'))->toBe(ManagedEnvironmentLinks::viewUrl($environment)) + ->and((string) data_get($case, 'status'))->toBe(__('localization.provider_guidance.status_ready')); +}); diff --git a/docs/ui-ux-enterprise-audit/design-coverage-matrix.md b/docs/ui-ux-enterprise-audit/design-coverage-matrix.md index 3100da08..80a193ca 100644 --- a/docs/ui-ux-enterprise-audit/design-coverage-matrix.md +++ b/docs/ui-ux-enterprise-audit/design-coverage-matrix.md @@ -7,8 +7,8 @@ ## Summary | Metric | Count | Notes | | --- | ---: | --- | | UI route/page inventory rows | 98 | Includes dynamic route families and utility/auth endpoints. | -| Unique page reports | 16 | `page-reports/*.md`; two inventory rows share existing reports where routes resolve to the same surface. | -| Desktop screenshots | 15 | 12 rendered product pages and 3 blocker evidence screenshots. | +| Unique page reports | 18 | `page-reports/*.md`; some inventory rows intentionally share existing reports where routes resolve to the same surface. | +| Desktop screenshots | 15 | Route-inventory-linked desktop evidence, including strategic runtime captures and blocker evidence screenshots. | | Tablet screenshots | 0 | Deferred to later strategic mockup/implementation specs. | | Mobile screenshots | 0 | Deferred to later strategic mockup/implementation specs. | | Strategic Surface rows | 44 | Individual target treatment or explicit product decision required. | @@ -56,7 +56,7 @@ ## Coverage By Area | Reviews | 6 | Review register and customer workspace captured; review pack/detail routes remain unresolved. | | Backup / restore | 6 | High-risk area; backup sets and restore runs were blocked by fixture capability. | | Settings / admin | 5 | Workspace and environment access are RBAC-sensitive and need later review. | -| Provider / integration | 5 | Provider connections captured; create/edit/onboarding remain high-risk unresolved surfaces. | +| Provider / integration | 5 | Provider connections and required permissions are captured; create/edit/onboarding remain high-risk unresolved surfaces. | | Findings | 5 | Queue/inbox patterns captured; finding detail needs individual triage target. | | Auth/access | 4 | Mostly flow/guard surfaces; copy and denial states should be pattern-reviewed. | | App shell | 4 | Workspace overview captured; chooser/context routes need domain pattern pass. | diff --git a/docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md b/docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md index ca3717ad..474b62b0 100644 --- a/docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md +++ b/docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md @@ -8,41 +8,49 @@ # UI-009 Provider Connections | Archetype | Provider / Integration | | Design depth | Strategic Surface | | Repo truth | repo-verified | -| Screenshot | `../screenshots/desktop/ui-009-provider-connections.png` | -| Browser status | Reached through workspace route. | +| Screenshot | `specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-072-provider-connections.png` | +| Browser status | Guidance-integrated; desktop screenshot saved under the Spec 353 artifact path. | ## First Five Seconds -The surface is the main integration authority. It should make connection health, scope, credentials/consent state, and safe next action legible without exposing secrets or raw provider errors by default. +The surface now leads with one provider-readiness case, one dominant primary action, and only then the existing provider truth and safe secondary actions. ## Productization Review -- Decision-first: medium; table needs stronger next-action state. -- Evidence-first: provider health and verification can support decisions. +- Decision-first: strong; list and detail now explain the primary blocker before secondary operator actions. +- Evidence-first: provider health and verification remain visible, but subordinate to the blocker and next step. - Context: workspace-owned provider connection surface. - Customer/auditor safety: internal/operator only. -- Diagnostics: raw provider details must stay hidden or support-gated. +- Diagnostics: technical details remain available without taking over the first-screen hierarchy. ## Information Inventory -Default content should include provider, connection type, target scope, health, permissions/consent, last verification, and next action. Diagnostic details should explain missing policy/scopes without raw secrets. +Default content now includes: + +- one dominant provider-readiness case +- one primary action +- provider, target scope, consent, verification, and capability truth +- grouped secondary actions under `More` +- technical details on demand + +Diagnostic detail continues to explain missing permission, consent, and verification context without exposing raw provider payloads or secrets. ## Dangerous Actions -Credential rotation, disconnect/disable, reverify, and delete are high-impact. Target design must include authorization, confirmation, audit, and recovery guidance. +Credential rotation, disable/enable, revert, and secret mutations remain grouped and capability-gated. The new guidance layer does not introduce auto-fix or auto-consent actions. ## Scores | IA | Density | User Clarity | Sellability | Disclosure | Hierarchy | DS Fit | A11y | Responsive | Components | UX Writing | Perf | | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | -| 3 | 4 | 3 | 4 | 3 | 3 | 4 | 3 | 3 | 4 | 3 | 4 | +| 4 | 4 | 4 | 5 | 4 | 5 | 4 | 4 | 4 | 4 | 4 | 4 | ## Top Issues -1. Needs stronger health/permission summary over raw integration detail. -2. Dangerous provider actions require target confirmation and audit treatment. -3. Provider-specific terminology should not leak into platform-core copy. +1. Edit-page guidance is intentionally deferred; the primary operator journey is list/detail first. +2. Existing `More` action density remains high, even though the primary readiness CTA is now clearer. +3. Provider capability/detail language still assumes operator familiarity with Microsoft-style readiness concepts. ## Target Direction -P0 individual target mockup. This is a trust-critical setup and recovery surface. +Implemented in Spec 353 as a bounded operator-guidance layer over existing provider readiness truth. Follow-up should focus on secondary-action density, not on another provider state framework. diff --git a/docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md b/docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md new file mode 100644 index 00000000..0d781417 --- /dev/null +++ b/docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md @@ -0,0 +1,57 @@ +# UI-077 Required Permissions + +| Field | Value | +| --- | --- | +| Route | `/admin/workspaces/{workspace}/environments/{environment}/required-permissions` | +| Source | `EnvironmentRequiredPermissions` | +| Area / scope | Provider readiness / permission posture / environment | +| Archetype | Provider / Integration | +| Design depth | Domain Pattern Surface | +| Repo truth | repo-verified | +| Screenshot | `specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-077-required-permissions.png` | +| Browser status | Guidance-integrated; desktop screenshot saved under the Spec 353 artifact path. | + +## First Five Seconds + +The page now answers the operator case first: what blocks readiness, why it matters, and what the safest next step is before the raw matrix appears. + +## Productization Review + +- Decision-first: strong; provider-readiness guidance and permission handoff sit above the matrix. +- Evidence-first: counts, capability groups, freshness, and copy payloads still support the operator after the primary decision. +- Context: environment-owned; route scope stays authoritative. +- Customer/auditor safety: operator-only diagnostics, no fake remediation. +- Diagnostics: raw permission detail stays secondary and technical details stay collapsed by default. + +## Information Inventory + +Default content now includes: + +- one dominant provider-readiness case +- one primary action +- permission handoff guidance +- permission counts and freshness +- capability-group posture +- copy payload actions +- the native permission matrix +- collapsed technical details + +## Dangerous Actions + +No direct consent execution or automatic repair is introduced. Verification starts only through the existing safe path and only when capability-gated. + +## Scores + +| IA | Density | User Clarity | Sellability | Disclosure | Hierarchy | DS Fit | A11y | Responsive | Components | UX Writing | Perf | +| ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | +| 4 | 4 | 5 | 5 | 4 | 5 | 4 | 4 | 4 | 4 | 4 | 4 | + +## Top Issues + +1. Summary and issues sections still carry some duplicate readiness language under the new top guidance. +2. The page still asks the operator to understand Microsoft permission semantics in the detailed matrix. +3. Browser artifacts should remain part of the spec evidence path because this page is highly hierarchy-sensitive. + +## Target Direction + +Implemented in Spec 353 as a bounded readiness-guidance layer over the existing permission-truth builder. Future work should refine copy and density, not rebuild the permission model. diff --git a/docs/ui-ux-enterprise-audit/route-inventory.md b/docs/ui-ux-enterprise-audit/route-inventory.md index 3272f718..6ea4cb8c 100644 --- a/docs/ui-ux-enterprise-audit/route-inventory.md +++ b/docs/ui-ux-enterprise-audit/route-inventory.md @@ -77,12 +77,12 @@ # Route Inventory | UI-069 | `/admin/workspaces/{workspace}/environments/{environment}/policy-versions/{record}` | resource | Policy Version Detail | Inventory | environment record | route exists | environment + record entitlement | Drift / Diff | Evidence / Audit | Strategic Surface | repo-verified | - | - | Snapshot/diff detail, high evidence value. | | UI-070 | `/admin/workspaces/{workspace}/environments/{environment}/entra-groups` | resource | Entra Groups | Directory | environment-bound | route exists | environment entitlement | Inventory | Provider / Integration | Domain Pattern Surface | repo-verified | - | - | Provider-bound directory cache list. | | UI-071 | `/admin/workspaces/{workspace}/environments/{environment}/entra-groups/{record}` | resource | Entra Group Detail | Directory | environment record | route exists | environment + record entitlement | Inventory | Provider / Integration | Design-System Cleanup Surface | repo-verified | - | - | Detail page likely pattern-covered. | -| UI-072 | `/admin/provider-connections` | resource | Provider Connections | Provider / integration | workspace hub | reachable | workspace provider capability | Provider / Integration | Settings / Admin | Strategic Surface | repo-verified | [desktop](screenshots/desktop/ui-009-provider-connections.png) | [report](page-reports/ui-009-provider-connections.md) | Critical integration and credential surface. | +| UI-072 | `/admin/provider-connections` | resource | Provider Connections | Provider / integration | workspace hub | reachable | workspace provider capability | Provider / Integration | Settings / Admin | Strategic Surface | repo-verified | [desktop](../../specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-072-provider-connections.png) | [report](page-reports/ui-009-provider-connections.md) | Critical integration and credential surface. | | UI-073 | `/admin/provider-connections/create` | resource | Create Provider Connection | Provider / integration | workspace | route exists | provider manage capability | Provider / Integration | Settings / Admin | Strategic Surface | repo-verified | - | - | Credential/consent flow; individual review needed. | | UI-074 | `/admin/provider-connections/{record}` and `/edit` | resource | Provider Connection Detail/Edit | Provider / integration | workspace record | route exists | provider capability | Provider / Integration | Support / Diagnostics | Strategic Surface | repo-verified | - | - | Health/permission details must avoid raw-first UX. | | UI-075 | `/admin/settings/workspace` | page | Workspace Settings | Settings / admin | workspace hub | route exists | workspace settings view/manage capability | Settings / Admin | Commercial / Entitlements | Domain Pattern Surface | repo-verified | - | - | Workspace settings and lifecycle copy. | | UI-076 | `/admin/cross-environment-compare` | page | Cross Environment Compare | Governance | workspace analysis | route exists | workspace member + environment access | Drift / Diff | Workspace / Tenant Context | Strategic Surface | repo-verified | - | - | Portfolio comparison/promotion workflow. | -| UI-077 | `/admin/workspaces/{workspace}/environments/{environment}/required-permissions` | page | Required Permissions | Provider / integration | environment-bound | route exists | environment entitlement | Provider / Integration | Support / Diagnostics | Domain Pattern Surface | repo-verified | - | - | Permission explanation/assist surface. | +| UI-077 | `/admin/workspaces/{workspace}/environments/{environment}/required-permissions` | page | Required Permissions | Provider / integration | environment-bound | route exists | environment entitlement | Provider / Integration | Support / Diagnostics | Domain Pattern Surface | repo-verified | [desktop](../../specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-077-required-permissions.png) | [report](page-reports/ui-077-required-permissions.md) | Permission explanation and readiness-handoff surface. | | UI-078 | `/admin/consent/start` and `/admin/consent/callback` | controller/view | Admin Consent Flow | Provider / integration | workspace/onboarding | route exists | auth/onboarding state | Provider / Integration | Auth / Access | Domain Pattern Surface | repo-verified | - | - | External Microsoft consent handshake; not a normal product page. | | UI-079 | `/admin/rbac/start` and `/admin/rbac/callback` | controller | RBAC Delegated Auth Flow | Auth/access | workspace/onboarding | route exists | auth/RBAC state | Auth / Access | Provider / Integration | Domain Pattern Surface | repo-verified | - | - | External auth handshake. | | UI-080 | `BreakGlassRecovery` page class | file discovery | Break-glass Recovery | Support | admin/internal | hidden/unregistered in provider list | privileged use only | Support / Diagnostics | Utility / Internal | Manual Review Required | plausible-existing | - | - | File exists; no confirmed route in current route list. | diff --git a/specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-072-provider-connections.png b/specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-072-provider-connections.png new file mode 100644 index 0000000000000000000000000000000000000000..b705a6f8b98ce6194572a86a182f905737960aab GIT binary patch literal 101416 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 literal 0 HcmV?d00001 diff --git a/specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-077-required-permissions.png b/specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/ui-077-required-permissions.png new file mode 100644 index 0000000000000000000000000000000000000000..d13b6104a5d4af7cb0a3588f2a595bfca527b48e GIT binary patch literal 247300 zcmeFZA$AAl)Fb>F(~%clx~N`ED$wqG&HX7?2AkPUTIy+8(;Yk|8^~*Hi)6R{d)y>7zN%H zpG>|LwW_bItaRPD^L720l5d@&{;cFXAnf`!P=t&EyzWEyocUS}n9+4Y(>{oU*QJwb zRzRs79XiIp*Uzipnv(zC7UrKG>~GShr~G#iMOFUp^x&mut7Zvw?{cvn9Ow`w>MtCW zmNqyV1s9Eu@e}I(5{-VYEiGNBTUJ?LuU4cknh)_3 z43$zf?-h|6f=Dh}+S&2(SMA3C-Xto3uDdb9NU-DKS^9_g3K2v~l2xUj$e8PvF|n}x z?dgHlVDk?Np>2bQhgU6%8y!`Ajqzlb1g^5JpdRf|xtkf6@*M_74?6;8gH=S$zf&@V zIaY~&LMdVpd9C&D&}9clM?@5qt#qmElYA(m@3ZKa5Rr-(8v!8=CMLxCZ?7?Q!pJt?xgkaJjcwOs`;^l0L7F~JZR!Hl z#-gQbT;}h=H#E|3-6XFuWZG!r5x^tH7CY@CAR>A^+mNa$z@oYS^5qM9NH+XQ_Mbl= z3=IuwXlS^(xl3T!C(U1!QDSjrlK9lq-WOCooS=@8?7xsy$fT+y*B72;N=nfLwYQU3 z!np~e`*c(%hlYfdzKz_=%p?=95)Z{}Y-oTNUx8(1@DHsB4Gxw%gk!JORi5+ln6TY( zc_u|Zx}WFgL8MbHnXpjh^YIO&*XZ@Dk}T2mo--P$P-i>%J@oc6@aDvaMA&zI zFB#EKl&Vyxy6uDiBd?3d0|&4W$0sM%1_C=iy}1@|^EE!b zX3HJQJ(b2JBz(^y?(VE~vP)&wPvN5+L21~2TU<~^HGqw;gXa~V0Uvb3$|;dcDIKv0~Hlce)jG@cT&?oq*@UonSlUsAIG zbdQp+Op;a)+ESJ^i8z+A8%wQ4^(DN7l(cpEtNj}{H`h#D(^Jy|&64r&iYXj)vP7>{ zYRIGSZf|ez?s|NCkcDN=cf78qek`h0n%26$XqM?wY+yue*?3>|gjD#DI~Li!JU>~E zrMG(B9H(;Ii;9V*rKPFm$;Pu=j$*!-jic96Bn!i{V~rPdKmBrh%35LQ70N9aN6Tk7 zYjpUG;hU7ke>0rKs@39|87!5JfF)@;_E}zBtNi2B(+$Qs-NVgGo=9L5euKlt^xrH> zVc*Lxmg~<^M7%ZHm7NJr;OXoSCtsusctDmJ)M;P7zIswExQ;L~e*OCO^PQzm8XqTv z+FUaGPH$vtjY&_t^+YbN$@oBQ0gZeTWXajl(Qc~Hccz@!V?NMDu&pA4M||VzT#X3w zQTFOU+G_?z_)E^=O1>VCLXHYymwa}2n6VmB)g}vd24Uir>DzCE1&7b6J|mL76^To! zH81ir`_8?=xiS?*LQwJ`%UL=1s{mg!zYY0kgOfNmmpH?ol%DzU0_X60Uf8$znoLug zWhJ5zubb&F-Wlcc8X8sD+w4SwWS2(=N=5Q{s%8U4w=QN4L%8o#HLWnj8P(?C48>kt zvs!)K3N@qog9oGq5|K5kz9C?-#i$_5{^F@jOvGDOM@2=|e9U{^HFdw6`T;3>z8OHB zVcty~Q7@1^NaA$EE|2p%Tki=%!YemuonKiIZn2J`QCe2HNvD!R7_Py9X8qevYoJA()lfGp=UT)>~IFA@jTi~>rBIDt~ue6-~J$^9F z*oQZ_P`{jHG*=Zwiyn#<9>i9r`S5Vkg@ng6+wNx{FUxB=8erTd`FXiz8hTX{sKoTK z;oD{cjnc89?_L6vzHZ#m_L$*R#mXPQm$Z}PW8CF)GQZDrRlPku+vV`Vj4`aHZ@t-% zSNyD?#V)gw8pZ0^{j$z{#%6vl_rrt6v1yB#2yUNu3!?rqq~sq7uS>abJ+4Oi9>cgC ze7>$toezQ`%#WUsztwNGs>bp?TWMwOP30~5MI>}H2EiRX{Q;}SapcEJ&9UP4U8ZYl zQmTlC0lpb)#`M9t5s_Bqp1(?KCVTS6kCQx+X<=`7-Q?p}Zf2CBZR@H{Ro#3xT4i~t z?eA6t`%-SE!7cN;Wn%nb0t=CmRVe zAw&pnxIJbBwg&zX3P0c1S*mqvlFnz#9V8d~&Y)AZnX1<2^WfSf19nAj+tW(Bxrx2W0=c;UR_8rTB)rkjQ-vhQO+F8b8@*+U8A9A&R{ze|60WT* z)St+rfdj@f{G!VA>aA0`(zxuGnXY6p@$q>+%^xN(F3gn7TvoJGheH_~%?4sdGK8yL z4siR`Wn!u6bZdTBRM<;P!ylhtU-vS}Gsq0a(RB-hh8pp5x+Zos&)MX>_qCJ2QFkN- zI%R```^Ro{D531~QvPbjkdk!_n=U4iRt4-gV|RE&s|L5O?<4NK_hVYxAAhf|D5iOa zbP@AkYd57(nt!* zeC-@_psp$0EtC@~k8_xaloRd5`t?r-N{_eOfq`I~HJk}E&Yczp;V^W4dIeeQ=8nN;zA z75v}Jr0-8=R9nNr9)FshFE?=Fr?Dj0(3PmHDt@R(Hm1gPDRk(NjZ?#6F5zq1k;_|*I*vVMV=AW^Bs73i?$Zyv3y6o}OLWRO^f`;z!mtE%G^@Y>rEK@%< zJ)xqU*sl^2`luCo4to48VSP6dN>h0v{dJu4bY0L9$T#=Y*E_v0HE;L`GOYIDufhv@ zS+%Jc1{$#pab1T0yUKWq7-Ms)@tl{gtx2Xv)u=DSVEZk%d(mg;Q}w%(Ci!?DD&RcR zt2D&iX25WlS)L`B8ia`L7aCNRnQ3HcY3Wa!Z;WQItc*U7uX&iur~}zJW`XVmzG2CX zUL+||NaflZN#$nyDgU`Q;@#c(7QgrH?+@7Aa~~mcY4hw}*QH=B&eqyi;ESS%Ic^V= zH3rT3Y5#;b}I5iKge6X>uw<}ZYLs@CK9=PghnY6;oF*p z%9<<&la%<(Qcd(^WPkhmw1|4$y^~E=_a-g7f}?wn%R%8aZJ(LQqtD%|RDZZ8wpwmE zTkUA~eY{oSn>b%;zL7Rh(&+l`a)zBF8HtzCvp`s4wF|C+&&5Wo)@I9mNRv^giXlJ) zkEAq@({{QTGq#S;xq7 zcd=h~e|fsemW>}wWYm+q9mti<>5oxsbgjJpgQ~Cmb?^2Ma+qDd&kxj zVYq2W%PnjXgt@*apMGr*@;=3_rI^v-==;@5C5Rb$S%e{;tPn`P6#L!{|1B=j585ww zk>ek;0Ui{wS;7`y=ys`R~b6HodOqo|%nOw&r$v?>F zd5P|=4O70KF}fXA^KPCiD%J|6yr43W*ct)_nykAY* z^|4L_{$j^yx>P5UkQ-OeO~nOt8rgVAnQpBtSy-UmnU>$|?+#j`tb~C75`_Jhdm{<6 zO{kajs?5&Xe7ubRgDpfQZX)J$1`t?Mul`tk(r>-H^46n7B?m(AB#r8_Kh@%T^j4O> zP&uC2-mbPlE)m!C2mPju%;kDd2`J*GnIHVU#ez|>rPhaFUDzM>%5>u?rJ~5uVPDctrHNffjRxxP<)v)$T8>Xhsj z9B=jGh{ACh15QJYVOZ3Ax$I`o7wn&4)Gmp6e*2{hGzMi%ygWPK+NWEL8t&g=;q(i; zq?9PL#vV&_?%fM-j7Rjp@zD+b#Zy?a(uwMTSltNd25#ypa+yBc27#hRiJnChA-`^yk z+7;~^b{$sREm>K(lB-4ge9$+F@^IRd^Wa=GNhdf7`GK$h5l71Ppvv!n7LS29d+5ZE zch#-cL_y>uq!BwkOtw}X&dr8?T6K#NyLS=&ddkL>hA8@YZ-yC~`Ck&(Q-M|*Yl-77 z)kcX}?AxHKl*q%TOYZWT>^zP38hF7PxtYR9{YIN&A3c{4gTlr%zEUv*M#G~LtlrNb zr*p`z`(T3Cw<0#Mnh;(_AE!j;n{|SHdb z?~G-vR2T}Ad+OGIj>J`rrB;B+=IO!pLskwX;J+S|iYB4-&zudQohZ}m(=1B~zsVM1 zM$P=50Kgg?8VO>rQ`hmsy>Ak)Q@T6e{FATmb3Yn>biV4@xg-q;wIX2(N zLOf=Ja-HfdspvMRozX824kT=5WY66Q1l;8-<@z%kCDQ|MprGU{4~c$K&=o)s4Kd=I zR%!9r8C}w;jtIxY#0;~-7*PMNl}M-dmNiCXtrIp+J%Ptz9b5&mfIG~P_tm~j$CLs* zK{h^mGsOR6qvN_EDJkhBq$wDlMv~2Hs<4d*eYv>$a2tb{MWZ+_D{FtUU`+9sm4L}_ zixHc3eOfMAC-$<_?DdiLp73OY2SIgy*7L#ml6AFJf0I3A4WU|Hwd`*WRo-{!WExTU zthnSv6*aoGgI1-xSKkk2?AHy>-odJkqunX!LN*20EaUmoUNb%ypk3`K?nWO$pE#wL z>I!@|>N2=~Y1d=ObJpb2VMm|5LnFpUgZ(9Vtj6VjGkv-q>M-2Je}9>bV?q@;uh8{m z@xl2W*W4P^scTzf-ak!@hQYb}qCd-ng&T6DqVzeACciiM%0&ANsLHUcFH_PjqobK%hxj75 zG@6{ET%WFOw0fZ#lQ~&z9Ix&}>2(x0HffCjqE!De$~yYfkk>ldRQYSi)C+JT^8j3Kcrh(6?{qs?7Ih?EeCgtjrUmw7S0! zir8l}LTlvpzxM4YB7$(WoI~mBfGJeXm5y4aS}s*Ddi~5npa5X9N++T%M(6FmI80Uj z%em)Pm)Q45kG0PCFrwbV6n*8|m6AQ!XTC)j-r)-qDE*4fvKU`>Bk&!!7LR8IU>M8tuReV6g`^Ao6b{|4cjtTIOe zILqgJa}SL8Oa_mnkl4by(CV0k-yRpeChMGD`x%<|!?KU$5s~jQms>=`38Humu0=Zd zrLs^tt%OO}6HlEC*->=o8)>-OWC8+FqN0B87a-liY49LtDso;X{$-bPE)*Z2`J-e% z>OBbO*4C0SMg$#6%PgAdELW`lEgVXN_D*cnpIG-%hLSmbd_c}G!#ll1(ekmnTC3k6 z2VJ8a0b3AmVM8s3D~IjV_X<8ptk7Tb{HblSl2c=zDGoL@F7tc&LA7A#-Vg3-D{e`5 zJ4gyxL8|0wYQ`t0TL_{7krm?e=XdO z4U-Aq{q6V|6bf7B9Wk?aNxQl^`l*ya(D!lk`6(C&5*NP{3(f!zH@@7(FhO3o+j`;Y~<@JKQfXCQsLfncWIU9M-Mb&zWGd%B>@jdA72-# zT3yC4(axPD|CmgCmvlidV_vvY7(LTpd7vXH}BM5%aqu zt;7g=O$&OVe*5Ol7rZu{>~uRJ{sd{!z&l$!)sCC$^h~JGyal5#tSRr1b~C+d?ho0# z#oxwqF;twmKxRmdb#3c zboTXeyD}MDZbXs(WlYX{$2vkThHHvNa&!wYs$01qZ{qzkqZsStoGYmhia`Z3j&1P| zJvIxC{E@=lzdLFHBA;Yi26YmM2D_S_rODPkOz@NrSnHGrDmpvLQRas%uL55j(J#_x zGlKD{(3@hY*wa_uD~8IZIFD4?;$5n}OvRNH@6XaK&N@41I53%7@P}zNjTZ)uw|^&@ z`y_9Upun%Df`*Nxz?|V@W42nGY4IMX@3eS}_wPrZn@zf02DLlFv?)ujbSE2uXhi`s zEH7_E0oJKc*Ly0oiJxwjQXd*d$7NKi0`5xL%rtgg-eOOqtHG)%kr-N}irrn;W<4=q zo4Aag1ir#h>3K8fE3}e0*wWHc@v(7l>q?VAE%U>199?XIe6l>*J%c2h@C4p7dav(Y zUbXgnEO}lOa)k&>iw@+iDr`FJlNG`#n+;TvY9DzkJ!8DA>ewGtm3O{>gkK&nmRr3< zhk0EOXInfjOp0$Mv61Y`ag;MZ_)aNFMw3J{#PK*}%O#d)TN|`_>p*viM*#(?l*U(E zU|9@?^Gs^BCTE$5Qq{b5@Cftelb36(bN>AK)Bcl%yqB740|EjP8FZrJ-jf6-lKIoyDEC|QI$5mLpOA$Km<*u$ zZ`Q9oe_*kluOUR#T=zyN$$b_U_j$M$7ZOoH;>-hxICJznObB`mcLi&FXz=n#x*+M0 z_s*!GdIrOcWKWoR{ig+9-^aM^k<`UzH$bGAuDb(fd51A=50c; z27PF?4YWA9{^kJzD?gJfB=H?++`qcOAc{d87!c4M+t(>@Bd@#G{y0HQXM26vj#1eC zhEBz9IF^PxAxjd)^aqnR3+Xv@q24|iYdtZm^-oUg{r>q%B2u_cYBnEO_#KK619$57Ep>$;}e5#_?=Id2{5%kF7hb6jVs39i8>I7 zflTDSq=#P{;n^33_3j4!O=YV!d15pD%AmG2smr9LU;Ai3(v&xkxuu~vYHUaOZTT*i zBkg`ZhdcmAiT%aIz^!x;0M!tf)Z1?4Mt!ltw-4Xm8G;wggUCbI5+L zRfZ9&slU5ZQ**HXma$gYT&HTt)r5gTB+q)AR=PraxaRm zT;_w=`D|fgzUmP6quz_&bb&{^r0cc!u_p`RtBG&SfABixE2MDv3@0HJMw82GlxXJp zy%^>q{Fp}n^}|?MjF8Rj$Ltbp$|0o`s(!;4nZ78&2pUK1{+ELa9~d>vBms{_Lq7!) z0e5^G9-V57bQa^9IaYgV>aO6I=P_Y9I8>srq~Jm5V&i1DT4R&zQQ^4N^Mk#)k&$w- zI^A33UA;y}*pAtOu|TkgOpQi=wddVk?v6J~gy*00(n$aK@9eFU(3jOyz(~f@C~1~x zMhf|OhDh)-I3+R>YgQNpC#jU_ZULU)WWILB?$hR2#);p{LFD7z5c7*%hLHZw=+Vxw z4p~wZ^5H@~9wu=W#lFkc!HhwZa~^t@-CWi4-OdkKr01jMR%T6=xvIQ}n-k)W;_8|& zYbG7;*S|64CR#j9ONoZ8b8&>M{wl}eJMN5fI`5Jdj2ZrUFNX^TM!sURfW05%Egnvk zOEQ-CfMZ@8O?yDXd*-)a7L}5Mo5KIu$3k-T=j+$6oVHx6wWe>#*SS7_G`!u*Y7~C9 z59ZzARFkq%{vnc=C#s-P|H^P*g^_=u>{;q!dgzBhUiJ$7!)0=${e!N;k5}IqOKM(5 zr)KBqATyd!)-=)Y6C;0EuU|$cpQq`t?cbOo-<68PTfdRyE&W(XJSU7DJ(8rsYV0qz zp4(eESy#|1Nnfg$E%8Tst>}<*R;1^MnsoQbv09-O4S$id7kLCKBh^ zn!RX$u)EoFT*thOC7c}Ym9M}D&zVBuwcHu^*y&UlVNO=dk}|NB%nFV z<=*-Pbp2}Q&^DEh7koP>hm^rt;JB*&u;pj_P>0ZgIHo2IHC>Hv`up*)tG@NJf;MJu zct!X>FPmY>b-86{x+u$8HA?$O>ss9i`4}phZ1H2!!xZil!!xV$exwWSiW4$Pw!L5t zg6LFL-EdVFG2Wgr=KtCqW>NMxH)$V@NQG`2oA?$M`ZC>UFur6 z{pp`6nwjl@{;`fgXMBEo`iJJJBM?p$8vq#hqxo7uA>xIszm`x(TD+BYaZ|b-k?UdB zZz>mqGvyRRHs!QY|C2<(2?=Ybm}tfLvxD`XuE-6sV>ahLvdzaYmFtsemME;ZkIxxh zt#@2T1}SE^xl|WzKoN95#IHq#u2U&!Yd}j|B7ZVt@tf5jTh@bImE0LZWwk1S&>_25 zzX=DYie+~jd+Yivzgxr#a_C=_G7JpdC@6^x zqM`j`w3GQ;Kn`Q&{VU(MXZPc*7@Yo#|H}m^mf?2tF;C1!n@GbKn_&pjxlY?~1gKpy zAqL438{FQs^0lM&9yA8c!Ew~3wFY+5MSc8@xS|EGc#8mU|Jr-)WX=gcS%j;%!5;NR zcI5?Qw%YRL8-m)1G&jt04#v??d(E5}APfYUA(QGE-rgv$wv!em=sb=kELDqTS7p-Mv9rpg>43 zuCzCi2hf5!Z`tA)YuLD*ueJ5K*v2X7AbA9Rn9F8rw=)PS z!O3dAW)H|^-}*zhkPy(5@5oU;KC;NQ59UMW^sH|$J~&QtU_9BaTJq>reYsf(dN%+w zndM^~B?VtOOm3mPgWx34Hku9I)v?5}K-Z5Ow9n|q**?%HQm4g7RG~V7h~3&Cyx|n9gnRP20Z~*Pz-~UV@6Hnncj;BU zPS27qf-TII+E|nt6(^@7s`$tA)jMSkH0mMW0^yX*2IEMgJDF8Jd{{kRk~*EGkeK~M zERj%jfwp07VZl$F4H=gHem^^1rdO%eWZ3R2Bqa3mu=3)0bNqCJpBUN?%tsKkOU`|_KlR~rTvhwQ|t_mPH5cV~1MT}-1K)~acIE@xK<_3Mqu zfF2kf?KP!yxY!+M_w{`R&<4Fh3wqlelL3bTj#|YGDbJVJC|mo`A+1vF`z<+Uab}0l z9UbJ-4)56W%T#-2Z|Hkhnp~K*%1hyQ+$kQ9 zeqPL2XR%=bo&;Lmn$ycYr}LfYLlsx|$aBj3?)1WJPvyL1K)i&Sf9n_9;Joh>41;?? zVui~(n6F)UxFL1>@>?!-n%(XAFckA0nz`T2=*~#08xT2h#ym8O;(}4r7*wf92Tl4- zfeFcE37NA7a1t_3Lq92zo?+BBZb3N$Um{LB@=yY!>&Y@@nj*6hA|<;emw{>T=;-I0 zW3dn?6YSgu`W95-Z0nhFeW39&>(w#r>)S84@H+4QO=2}YUc9TJ{Ik5=rd??gP#L~g z3|uO`Oo7l6EhKS=xoBDQbqod|Gvr&CZYsRWcJJ!xdG{&q&mS@^Ej<7JI+@n%&^Myk z569t2k2bpNUm^)`ZVq{gk_)UB>f)VyOSg3LpB`Q&vcztJkX}A5H3gv~te1!Zr%_>q zFIBa}iol@C==gY+)%YVQhwf+VSD-4?eO}UPbhO6)yWIZrb#OCJZl(vwBT%dJ`v6D3m36dGpSWKs z?l1*z{`RWJ{%eo}O?# zVW5`Wo^AA~Z=ak*4}W(fkOZR{4!tJ4xWghE?}hlH7LDeBycA;_ju0t2b5!VA7fVQ~ zVuTsj#2TCmRcK#ApAi+i%jhwq>nIa*A410DPxMdH=3tJ~ZT0loB&BHUZ7_I`70Vc) zw0*Z7dE@`4Z)*#dyB-E!J)p8n4-F0uZn(gxL*RBOLzr9j9UDGLz=Y=0Jyh9v zD23D19nbviRQg-p`NNH&r_Kirg@Q>WY`2ia;3#>B7(V+|H~!X;g!iN$ko&+c-fO}r zj1cs>S3i7j$dYE|xiuI+l*k-Sz&SWF^67AP_j**x%;ga6E3L)mXj&S0RN43f<5~ArJLSPiHl&yMI{lSc+xQt=?9y@?`0VngmAJce2Fs2+YqOohR+$Ni)S-r zH_;3)PrpcM^Equ}1|(>f0He!QB%#|x-UYV2fNwfP}C$voOCQE#KeLaHi z>G3s;T1EAmzAT|em3;C<8n4schLoSc{`QDhh+m-vJhqfH#zAU<^16Y;>y~%fo>g1i zV2^MDkqF%2!E_nnpgH(Cl*F3jJe6(M`3(Woa3CMYye3p3x)O^r!uE^qSwVhO4{4{k zE&9<5|I-Q%=IvV#505qWYvROB%m`up-bpVuGwGe3oqFrZI?pQ`8pT6$bd|#i>!2Ma zp(9Ey2oBw(x69og4cg@~31T$WiW8NZGl`sVh%-f{xImmr)81D6VXD@oZo`+*$L$10 zTdenNCjza~KSgoq6NH_23yn~$e7@sJcbaj*cY9l-|Wh7f@5O^YMI0xy$ojbFWzdq zg*v4?Rq`zJ!8oB|N_<#TZbk`~ouh>t$|>?y(CSlYqI<|qLXl6LCMB{XO*;iV`0jocX;q~2Fq}A40uBT$mOeAU*m0%G z0A3n4n@1D_8YM35ed^??)$EN0jJEDD-5ZF7s| z7QdX7!N0?t{P@ViZG36RpfDGy=5;zDs8Fp8(Rm9wDcyRj8pcJ*Lal0O&4N5cOQ)rG zHaBmtr1h<=tjrWMC8&^4QAK>!PKnrT-JkAjQ&UsJ!{wZ(+qJo|(5&L3`=mYybhApj za$laT_-zj-uPvnlG2hMYMz8)ef(p0w1l5_z znDjUXqmeed9(iu^i`1!Si&uVHm=2$*X!)`>0Xzh{HCCO5@Y%Cdr8z#(CdlLRQd@oo zw@9^fRQ}8=Ew>omD8dE5Fp0DOEhXQp=;BjfrJgetzK-GLWyQl+D=}%IJ<{=M`nmTU zs*w1@C)#qcV>X--7?1yA?_Y-&kqFJ#eIgWrcv(|;Cvtt72W9MAWV)8?#Wo{z1$UV) zr&1!*$Z{)O-Wh0`){70$T3hb!R2s!!y(4(cLOz<@pXLEU7yT9`C1;cx`X5*k3zepB z0%prCK_O=NlZ7gB>T56*VT=e%-vI9lxR!X^lB!L00Y9Q%j~6A9T^cmC`U+yU-%h*J zP+e*+;CT##Ffg+B?TIP1LTqpq=^0&zR zs;39E_cAd&atZPPckp;#4(W6fL|#96k(OPng)5Yy_9#>$(FvGMmjbJ$%kJOp`>Rv{ zj4=v2y4S@3BNq$NK#bU1Zgm325O9C`o~>V=za6jXi|xrms+*VFIU}Amp3alAJfxZ# zc;n?PY`H2}e1~0hjXTj%Ce-7binr4anKGaXw_Pn`UxOw&ETi_kkgKFly?~eEpFydw z?K(&nf~N>QT>1Ry`^WA33ICh?;s5aupn2xHGm$v+$Z)}$vtsvwnF+A3FYAWLFXwW| zS`oo0gw)-%VCCUw(2S#*hnHbd6#|Jep4m_{OF52F&lBiC;7-bv*9doPKQA`C2T;be zH$oYL1EyzCIAiBv0B|ifXoU=#gKe^g5g}e_J@@hGyuH?wSZL|{KFXmD7uU=7T(bt= zDzp4^AGwUU<%B?~vC|E+p)8N@&_Z{{7zGP|92KD02Xt*ec%;&6@F z=YAORpI{p^_-3J&IUS#5aoQA5wqrfRM8n@i_E9E!zFy&>qwfcMhU&20>1q^-DXzkU zbMN()oaamQ+oPR}`s(e?+7JD8MtH{R4~rCGx%exuo^mQOp8H7s7Mon?CClNS4l3FK zb*@4drUv}CM=SOMu6MxPCuhoJ(DHbelhNFqIu|!#pFAqQ90_%Eww4eVmYzpO^hYhL z{a-Esh7lQ?k29A)3xP1{jSS$dgqoeovvg?6^^6Pu)LU-?# z)Ab^9g?lA54Ech}P{<5he(hMW0Fvx?wklRvS62}c5!CYo3G^QHNXZh_qHjFrz^HXA zZZ}^e6Y?E29)&bM4YDv>yYioyL`2>|)dQ0WaO|l(9!!t8Gi1B#6L52z+9H{=I;;bQ zKKxC;k@aMLe3&V1+7j?!v=prR%23c_-Ymbp_2XodL*1GTzW=eR#C@{(w?sV*Stnk{ z5#r4E24b{+YZ;9!b-kNgGCpl%$L$rLlM`E6k5(zRG0Yn$6H7n;VzQDIeO95O*IXxf zl=cgjg7BN__rO3?BcmT5uqSJD%M2>Q!@UZ@GY8~`(wY|vF`s%%+dGwCSX=7XIb;36 zkZ5LA*kr$A0E@JZ_X1#S0z_lb=K*zf*?DiGp`oGFu-yYVOZeT6JGv*{&}%V8$IP$y zyezf(xZPj!E-#-jSfXAHP#1n)>HFVv(pekDq2wn_xfETA|u1 zDH0V6(lLeJ*zcj8OcUma0d`jIn!1w2IYL=$o5`DAG-0j2$n)`YxA2rE*W|c2k`1!?lgGn1OVg@ zJY!VFmO(I3erQsU`8C$Iu#g!UQ31B}SKOR}xiChvPBF%Wn1m6jMP= z74W$42n=4Rv8Gc9Tx)W%Edy2_%Q4?uHc$eJw}#~s7z~Ql&qA>Zm_IgXlV#63y4Sl7 zez}Sm-brc&PcH+}Of&3Pva)MnCSe?gxRe0y$WQKgcv zn;ckDasaLtCOaudvqaeUad$g`<@oy3be32!=$XLKKmm%?$}b*J!2n&|=5}HLpdB!S z&=2ms^LyMq*-rSgpW)=a@y&y*O)>`s0YRiZe6^CCJPQ&JX$iN${E2ht!$S2%O*{QR zTp}u~ske7URu~sAR=?epPiK3Q@@5DhpWZAkVIiLBgT>X_+8Wpu9eH{C)T1c*_{%sW zCpA?s4149X52jD7Vu9E5Bk!`x@$vC&A~70Y8c?$)fj~C)ix-$ji1$=wn3$Lv9k(Dr zq*TBnr?%oC@bC9rw}DVnWX}c*8VYwYm1)bFo3J1uB6>dEbB0*}H#|m2HaYMZ4hWl7xf=3}%kb&YLF;66u;H zDDd#Nw`Y`&5`d}2q?RvKEy5qj4l9Z%4VO9tnIE0tSu4pm^8*8P03%A9Tj>dVU4JZr z?mBz=(_$)PR##Vx#YiW%^dN{a; zXi_mEVq#@lypWKP^~4`Plxb+BItXTSsVVNQB|HqteA$1cr2%CSmI4HMU_seG_H#xD zpEVi3AO$HH&cE7LgNpK)1B!Estlnu41+)??LSkezW5z6D?P>&>KnZ(gQl$T;Z zZ$JX?dm+DV1?xwng!u62*RNmh_~hebp)>T92dd%)IWz*Arn#K@nnA>p;Do<&Kre;F zFYO3Mh+oEn=X9X@`$7L-lInhdHU6hdkIh*7zm%1@xY_rj2yj&)A^j;yga7l7kkSDr z4)qbWp?|;aT3T2Zn8YTP_A`iRkb2y#(SQGNUQKWFi^ zkj;xpq^F{<>e5qY(f5%5znQN)TKQQLYWgaymp-32|Be?I*X$6&2SFY1Dh>UAU%~(X z*8e_>|Ics2gfiae_Ozp~ug{1D{w$@Ug4v)5onFZIF{A)%{hv?)jIB8!m}V!oPx zQ!6?%8S&G@$@-^-x|J3WHSgr8s3=%OY~T$u?u#O3vEzCIl~1?M4kwuxNE7rb+2ZG{ zfPi^98z2|TRaA#wfj4!u7 zfDw#t37GU*rc*OA45Nq|-@JL#{S(Z5qsi>S=q?12`5zn4jhFM(i-Ec5Cts~4v{<89 ztKxHGrCmp*Y2W^I88d2uZ2bQHRmm-p&xOkJ@-m=Q6F)1aa+R44V2U#A1I`YZSUX#W zCfQv`au#pL98-b8a(3vTmS+*10iX=T%KoM?MRD=zJZ0K-9|V89eUH3tbg;Sa$Mz%1+r^}UOhGFZldb94-dc>!A3ll_u|a#x-Q`N{E?{l z0LLWJB_j>&OJ56CZy3sJR{1o(GKYFMc!Ao#O<4?6X}GoJ$$1RqQsA3pWHEy4QfPrMJT zKay8U1iT+= zA>bB~HDNqaF&_1((IN2R$VwZb1F82 zwsOneby+<}EYRFg2)Qm($6SsVJ%&Y^<{F)LfGR;56Ur?WMFfbs0+;8rjXn?paNV2G z34zIN=n6)YNXa))sr@Nk5p}B$VbLMExDWkT@U2OxW25C(ao8pf_RbB z-MM)Hql2rf&0@n(bjx@~Jy2Sp6AGnA;17=^v5FA{-VmyR@GQpDrU_d-EF7GiIRz*# zSwONR41rBhXh0&-2iR?;rLFSi-+>ex zU_CF&ax7P!S~!4Jqga|a(sh3-ahXS%_oozF zN7CTw$CBk156a~h->2{BybE=o5(C~FxPzLT3tYE1s~vBKs;6GRc>}~t$Wkfbu0bYh z6YH0--x_eEOWAq4yK74x&s4NtA1^)Jp2dP3l1Umiohna@5Z7>e3D~1iQK(>Zu`XS0 zF%$uoH>|b-IGr|!5|u&_@$eF3-pd`%R+gFc47$UGQQjQR1s1rvxWu>9U{QU+;bvWi zfC==E7k-J{e15>5Stl44vJNlquWVb!)Cv?MX#@5X9{13b@+Lmc*H{Bm!Lm`BMk!s? zM}w%Yy1J{nA5V;h_%H3seZZbrz0*!Puu7N;;1+3DX8%0A=@~j0`AI3Id?i85uUBVx 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�#>D#t%$NWUE+O5;9VJFzQ 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%0D}XY%#8gKDZPDb(h-Yk@N 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

a+N+@421ol!>R`c5Lf|=!d3az%Z@+Ck(X3% zr2I8>t0Ugd@^4PkQ5zq5@J^s`sy4pOCZp@ltied}0%X>zq=|G@y{l7_LjI@&(P;2P ze^Nd}_*Xu2H-ws+enbv|WSj^#15Lb!I%jk?FVZRg#fJAq)W2wE9uU<&M{ zL90Id*muqWtg2bBK(=AflSpaOHxDh=y*qa>{g(^F8E^~4Bg?a1M}JpvjjyU&T~Sz* zsUzWc$=6t57w;d>8B(#hj8H>P42<1ZJ7IYL&eOQujo*IWe6*9FR%Y&?V`T5i;uC)p zvcqLP+4$94UkkT3M7m^XUpu6kK8CpQm*r)8E!}|RzzpDyL%2v<5t^tp46G7CLI#5@ zOF)@n{=xJnXCH!4AQvZabbW702D}v|!ztc?auX;cfja=$1hC$QOwsvCt#4?2CHjF= zl@goXmd1nNvE` zj405!|2L+~5xpfMVovxW5*F6NL1(eb*@Sqo3 zP4RDTZW>!B6B9H70{$TeWt1AeLw6kOTokHU@RkE&o9raRUTnxIu%im)J(-`J@RPG zG)ilxCj7&-5phEHZp)R^16!ngD#fh+fY=1D^OIc4dV;Lh{N7X*gmpns(sia#w!9CZ z=P5USxOsoRo)&$hh0Zz_vL#B@d?Y%jrpQ)`!L&DEZu%AY^a9C_ximWzc1ZxSk z8E`pZ2_Z3KYIl9*!NSLG?xJ_otTQIPpc$|KQQfA7=%LBwFk*%e~1_{JUZgVQdhz*zb2*LOJvASpY_) zZgVg_X0LX#%kIA81&zo@!M#Jx4?pw&sOKG>oxTVP<#DW_l87^(huDIYx%hdLi^8dG zZjU}{of|f9b5)~ki=aNU_ zby`V>>yqqNO8b4(tbdjUR+3R5atF*&48DE3HsH(tl$WH5gM;$}GMs^NF?Z1Ym8a>w zYS&^Hw9EGo2z;qtf4TEj=|cJxh@hX`$4gNTuw9aa)hu><8}kKRs$AT^h#bJ8<2U5{ zXt3tzLj`Hl(DydPT>fL<_>nWUFD~#-$ryw_&TQnA-WjX5T|5?WJwh55p186(XRA`D zbKSb1y8c+f*Zj8JPr70@b4{)%fpE54(kUW@fsHMqw6U|6CKML4&IN=himA zUWGhdTdy(bA{xz*G@{1+p$2g(GHqVMJgSSZ?7~<(%h4U7U+z_$ku(n2di_yE5vzd23=<7^P_EOj>uifkZClfoidsfY3vJeC_-93Y1>CJMArL z&remv+kL^94egEVPAq9@I*DaSc|EP1TJD#{W^$zQIDtbHECXW}TMzOY-Wm^oe}AK1 zeSWj|&3(Nx&Wp-AP0=X|pM^V7r;433lp~*?%K2S%L>0dhZTZTRWSy>Elv=PrWsYV5 zZ-xG2Bbl@&qM1eVBdy-2hg|v{G~qDR&OKmM6GjT_tzH6(bZ?yXqbE;Z2lOZduj_2H zY73CczEU&%q2F?Ha;Hx8Of1izGwAryke_|+Pg0C%Pp6Ht-k?$Va$_24k6!jsx>A?F zrmKdY+dW(s?do*&jvc+V5Mut@_ozr#SQ0d2{T9}b&1*dhNywfFyK|;1h5WJ#$s_g{ zJYk;we9peume#u>^={GO@ozoxs(0_~<|$-MIEZe04TVqZcYbBG9kLuEFgXGr?A*pa zM-yn5HplOZsx>xlWR49P{PQj2%V&MbG(&WJw(552!=`NaGB3Idz2cr|DIxSZw!{tU zu4<(p4p$C3+YRq7bTD@BImblP$>|OiJlv`|vaE5rN(@q|ur-Km`{8=DacBnliSW?d zer*5)$R08e6@wxbmwhKW>32Y4h_3UzSg0QJlXBdiPVvtDsg}>Q zE4#}=qMgcxU%zs)OV(7Xk)@fXKc-m}>rwt>zm@U&%XiiRqJ4m;__^#pJ*9XVG4}rO zYk~WL#hwl1BdB=b!%9|Y6&nfV!-tBFkZm30SH*v z9;uLx!RGPHI{>l*fT{*FK{Ijh=H5Wnnj7Lo^mC4E8lnd6j*%meKYuHD!FN zv2btOTnVQoT}$*p7AhL4@pD&4t2D#DWS@b&CmV@&^SL(%!ha4A*9V41s}}t({pKB_ zlbsRt$==n*b;s70ic#`{wuB>(S+rb&S<~L_PuRV^so0w;s@(WQP6&>>R$tx7sN!3( zXJ@5gUaipAW%*86M8wzoR+dS@Oyg7>&r!|ody9Z+%m8KUU;Eilmss>Rv588DI#6xD zeLL-sW%Y@GwHU_VKqM<9RxMri0}ut`6@`71TvoF&_?-lxRstT`%Ac8vvMEw7^I_TS z2=KjJf-Q2&^GXx)cVNU0d2KJjBsEuACc6a0H&=gBZUQkBlCch9ysjSte7Eo&NXI%p zo?8IMni3*CbYq>{;;ol0tzbsL!QaR3F-!p>?W}rfKNLr!y0OBv{GWpV+vkHsNre$B zAF~qu-dndBvh_;D37I*c9h3G;_7jnk##2j<5(({WR@uSSpFTtjW_xQxp7QA2?iUBK za1_ewISE{axslZ7Yx6ok&AA~NZD%Q|%*<@Ax#pq)B?!V?Y!*9BObBohmIgfUwC1)7 zSu-nG?Nyi}+U=2$0z{sxb01I?;V2P3p!CcTjC6kWof}5N5jZ62lnP!?HF^-*sgQHh0z_hPO%s#+p_4Hs(Buz$k)kU%I zgV^Kl?J54$+(Nw~6*anP7r9_>tE=Joq@v%Z=b$hy;R9YeYqAz7m-Z~ znY~6*nenYaQj*QVuHj^l^+d)pTjV3BS`V256vs<5k`6h#B20Mj{O8T2>le1>*r2RP2Job zP!YVN#%M@eO%7n;gg{KchBt#h*0l13*MFBk$VR*Vdptl9`TFlo0FsKK3shzLtN41| z`Wd(=Wg)zV#1-@)t`h9{QxOQS;5oR+&z~DM2OlLmXRalAZc6nB>orROUwTXNHB(K@ zkd`YWFYikvMCiUXQR9@y*kL!19S#B!W>YFQD_pt&POn>!Qw zHK3GFeCv&b#xb7HRZwO40Qj%=E4yE$whzY?fcOUqe7zt@eWJ2G1J+llIIUc7>pQUP zb#-;|o@juG@qK;0*XD%wH>G@eMaBK;1}l&4hN|LW*j9`>@G5QQ7D>2^F$ntvlncH{ zxUm9WwE*}knA+-ETU%eApFnP4A)>x<*P2L3b#$>y-4Fd?n1)`t-BKcR?J+0Qy2#j1 znGT|}eP_8C;L3Wt!~o2SSxe~uWUf3+u_s+oEk4I_ZC8Re(Fc|SF_w& zj>bPYxOl{z?Ys3%1jPA0R^8PCa_isxGu38r@KQ>Qm}|K>tJ|M=m%HIu6^w=vs)%1@ z)Wd&Qvp+MWC!XDpNlB#rw?bwoL=p@@g97CG3XcnB!xB{_FTdp(4&UM*%ge^p@y)WI zWV*gqebZ}kWH)*pZNa$UobgT0?+QEo z1%mHpY~0@FZ1M9}9Wl~_tVAIq&q@05>D7Pkr;A%rtC<@c$3T1C_M#)E3kY7cH(_Io z4FK~Y#zxrgpiu})eTIYBM#IQw9j|e)%yEAnI$jT@7BtZv2@==lUew zym6kvOriJT<40t4H-okaXIlcNU*0RMtVQ(9_cnv&?=4QT2%;VS&Hghk9O85^|oJ%o^+)lFUE)K!I2w2Rx57Arrcqn{Oal_j9 zug(*`e_t~jvV>gD;2Vf|311Fhwh=PV_4BH{uKz| zWpg_o4hx$ejvKzbsTC6rly8WhpIl1vB*wxTsddj?9}!ARO;u3w2W~mv>46OYiSGGv zHZG&mHwbb`HO4`-^2(180AH2C#|MWl%xZhuL*V@T;op4!tRxRp2+t@u+qwyNsd1lk z?h9^v21)-Qb{KL?U=b3oRLaiiM11@m9xkU^>`g`Dyr$%2Z7s_XdN5gTqkztm z+X$Lduxfn;{-?MIu@|2|FE0;IPuEA$MrJ9r*#@-Kq)xf9&1w!AgD#9*$rd=(1k4 zi;B?aTro#0)V$}qQCgPhl9Qr12-ucZfd(N3EN(}_`Am&*Qkh)|o^@^~63}(84rJ4} zMB^fknR^POGqho?c&vUI_CXzttU#(l&nkoDb(N}wO!X382nLxP7NfFAUZM#k>A=6w zxPd^(hg9joQiSm032(n%EbG6D{m&QGNTZ35a%pnq)bt2u8flH^n`3B*$&byLVyz{n z2CIcq+j>}t>gWl}A=9mi?LLAV+m?LJ z#d>SHG~GQ?={1tIUrPqtM?tG16?k++`f67WvY$I>(4@it$Y;VcV;~lq#+tFo?lk6z z>%!|ELz;G{GBDxz3@O+#&42VcVRP8#$8O^w@=+rU3xl_UOkVf!@@J7Z5Ra!W5V_b zkenjVjM3hUzNgJ(3lW*y+QNVMurYcQQT?&aQ&n#E-?M;u-T|t|>Yo=Y`w5!W@<}po zOyA#xe0b8^q%Jb@9|f7GhQEEIqyJ2g2#arfuM^pZgNd0eepa~mEks9OpCg3atMdt8 z2*?XZ2Bv8#1eXmmW*vENkLn7bbIFF)Nsd(P}!){3u=I_1c76o5Qkk-i5Y7`5oh*_pw*d(sw% zuM#X<^^JVx@M#k9i$`Z@J2(iZAL1!em-KME1UW5F@L%6J(^!HGH?RNkjsl+V|AQOq z|Gi5K|HsSw7~{RW49nE=ITN~OtmzQb4S>a6>wouQH3r{z_y$2JqXaj!Xda}qm5k`J z#lu!HDW2PFd}4ZYTO}eoy(Yq!@i|SiF$>)A%LmV?DgO}MXcg87(UFo0CKntB%ZY?m{t|>-e_DL7DV(pxilJ!L z{GY9@bliE^I5=WdH^T_U{ZY};BcyO~aowkANt(HQdrkHJ`Nf0@+QStSC{Y$uvO5h+ z+K&FpeEN2LN{0wDfjid=;raD7+)iof6JMME#5QBT$i$l>I2G3;z;zJ#=VsuDhW1~A z**onQ+;1Gla4u+Ql*B3HeVQ@7hQg4gv#OHda=0YMwd?B5%@eQ9=_w-W)sN54RGE}c zVoz0}frwau63OX-30nT&A5VSj)9UBs;~QsK;yX3aQ0vbCse)zXp9dqIjYtSF*)lZ5 zbr3?n?Y~{FXvnFKhFn8Js)VSo0_-HA>&cZoJ8K9z!V2PuXNiRpZcL+xo^91M>CT{{ zA|@q1#0;8>cSYd^MUVB|*jDNzu*IhQ=Sk$YP8~A(F!dAJ>+I1+!rSlx^15== zdLD5-v3xXGJ9a}G+nl!);Q`{ zzpzMkFz!Xhh|bA{%tRkIvlyZKXxE_h`CZ;Z^emJ+cX+JDaGK%Cz}cZ;`GfV)g2z)( z`B7c!Tv;L#ugWL&nZpDw-ZIu|>u^{(X$u%{PQ(4d&63xJJsa=$_9+sQd_#%$Jq5({ zdp7m;p#qZqRz!p{%{F{d&z-ce`iKW2uKWb4rr_OVFYH8`f0GKNq>p|o4%JpG zmJ$ytQ82oEQ`YM#V!{#FyX+sNQ2n9H5Zp8W#%gj5> zj;jRww;$IrV&t-pPo2gqP)x!s6?iy(!vk41T?yN^I= zd^=4$U>1eP@n=G3;F&Q;AHgVmMhCI{2&kw7@gPKSt{KX=rMAecc%$bed@h{_>s(WA zW1uA?yxQ-7Tz5R%QDp?FU25>|SC?m7-u+AM(OL2t?Hw`Pp`)@oY68l6x((*05qVUo?i zYoQ;gVQ^?%;~=?XZmL%fUmRRzpzl{{hJIPE-b)Z>`j6$)Rq8x$T246M1sKM-KT{I| zwu5jPciI`<_0Qoyz*!@gxi}odQ*BM;bJceObg%Cihe@SeDgQZ4Vt=+w1*@xZ$G=d! z&H-HL{%SSXoMbSstnEIL+63l-OVRX01)8}Cr|ta)!9D_HrM$4CXsw^i#*)LH1?!c^ zm$Q6NS2ySsc7Fev`NX4n&tabIB3V{r(_AaW6MoI3IKTH(jU!0Px?&m69SkL_Of#5xw3f7Ov z_fMD8u5(`qIgF>Fu}PnzlzgpoS4U?^Ch5}Xc$*81LGyc!`7e(jtSGlRMYav3G}=LP zk`J801Q3iv?U?h1xXS39|L(Nb&$!`MK2Pxgsplw=c3RANd6f5S_yH}3!zPyEN&p*U zj9A|D;gk}4W(`Wl^X*b{^`AmtD;eI^O7xy#kZ$&sO#e|9G99Wu9ON>hm43{z+SNzq zZtcEtTGDUWeyarq?bD=Z^1$rvkwi;J?hx7&UN=)S8fS<-`L2}zxi1*vOji131T1Jo z-9K|_7wNtN3Zemsrz?O|PG@7m#L_$L9d!5q}{(gO=M6!RN(n0;M zCV;2=dwU5$>0K+tP&SG!&C{w;8?8J&NJ6{c#qiiDl$4J;|6pY=FmHdvi0AV1jPrK= zO~VQoX`)8;1kW?0@!#f;)sN>p)?6fre!wJjacwH=czuP7%kufoXu@i%0%gnm#*xHG zkCO1l#5>dDx)TN+J*V9RtnjMCD6Qgee_Cf~{X(lNR+L@M*Bh3qR&LyAcdH)IDJ?%j zyIrsD-1Bt@Mk`PCn(YY*c%7Edw(6Mq?ygu!#j&&v4ZUmhO@gU0?Sy{|Ss{nVxi{3- zRAph_{gSUFpL6Vjxw0wP?5aZ|;h^c@+JU@O|BC(B=Y06Y#IDfG4OMg7Ek=Fn(DuA| zd;#X2S+L>4P1Xk+{O`8Mf?szQyNLTU-QVP^J>_=MESjCOO;!_;(1Etw0vOWZVDy<6 z1h1eHubOvqG&cTrgLicHlH0D_4#RK4vex#g_SB^9k6}E*Y<>s#gHZn4yZG_XUIz&D z?)0Q)q#csoncA(AxpZ4?#kMn&5L576ZLy!3t+m2D=@`xa(cZD13gMC$Db)PyZ zG73t~*`@~lhlQ?$BN#B=CmJB*?i-OagWmgxQ$s@oNO?5?03{jw%sb+2F7^ozgbW)c zJ^ays-=N=pYW&9-)(orK6W@mE>fs)Jwk@FR!mN=^BTeM7>Mt3A{AkBQ7_$P<46#{; z8>6K-2#mf1vLW#*D$!&TJV_X>KHzs)=x4TbSo@N@c2DB`X=TePIuone=ittX8p%z| zuLk-fGO<-Omoj?BW!kDI6~BKbGej>WapdSsc@*yLv4dOCZ!6;aBQHw^vK`#-A6P${ zbCzL|$ z(%XJf*_B^tkM=lOz^Aus>*F*Zew4v7v_9pw7flitL-)*}od;G&i@x+CbNMPq3x^$n zsqlI10mA#pLh#5NBnt=3+PbOrrJ-$2Zt%K`q08m=SD&t4;UIQyw8wbpb}+L&s`0Lo zR$uw}(T?AS+_ptNDQ$+I}3@EI6x!}#tHjx3_{!KvLRNgtC z+p!p&e(*gkHR(6xmVHy_;m-Y1FqqBa!Kb5U5tEYb_c`u(7$n8d@UP80_-7{YP z=khYlj2?X2XH*&}{o)NR7|q7y`=1XjuVhOb!!sHpSzA647aK&1Es~@Sp5i`EMYI}E zMz#lw=>0+h4XzXo{hO21OV=?9GBR!MSz>(rgn8`E#K{F8{KQzPgGP*8X3a|dB9%&e z8&V?%m6PWOGj*CZ)nm^?If zNv>Q<*p|qbpr&UvIuKu&E}QwR=kKKs5H_^kb{2{aI>32;0CYpJLsF@I>MRJ&;#W*a zTV9UiF{|L4v|lPPE0DO9WUh(Q7ebvz`cDu|nIY1#$9|>wIg>@Kh$-kWXh}@&V+@_1 zn#^t4oh3E1yt9lyE+VVLD9{=#Jx@sRC>^gh2@M%MJ!uo_Z|Zn2Lx*6CIZ7{{@|;qF z=@j9A;%Smaxv*uq9&HAF`h&|*{*-r_kG2-EO^*;Us#UU+p#CIpw02JrZ z6ht5IH}HGj3U;%Bd(AK!rLc%nTv40pM_i4Z{)0GJ83pd$sdUL!$&d&*(>3j&-vgnl0-AFl~2t4ToWrC~ z<;FbEmQ=Kk>VUdcNO(aXu@#!Km#7wCs#Od;GO2sfADMc7JlZhoE;GybF{vepFiM) zT>~1bm76GsZSS+dAx50qvoo&Da*xoaxoFOibA4bp02wpK|{u9MZ zlYN(~2Oa{}=G#T$Ktu&&>{Ghi8q<&%<2l9p6Pd*;A1j>n)Iu=Gqh0;zCJ$U4r@CtWLMK4k21pLW<807KOudEsAdR1>*4L!%Gn1jln1s(oj{(^OG=!CdBiDXdBi4HyC4Ok;xjMpWxtcaw zTvYgF5Xq7B?h_xF%y-4JXGNGsK>lyXVx^Mw@8)KJcsRh{$Ts~Xaq0w`|CLed(Fl&m z4b*Bx`NPBW-Iceh<2Hc&5-K-0*Q-o7Vl_Ts*pqo;l|_3SgCm++bTlk3j=-cJI|Lfg zz~7Irt_~}sj>#mWuxr+4z|e$BcSWI>GO9QsugN+K=k6n+XT(Bja&sfGX8g&`EYV^H z+czfdkkhcQ93(cIcT58HDZpy&E*T^<8I1j$qGkng75!7~<0=g7EQh;KkalpUA-w6x zPPm0G@k_foXOsEg@n}=t5bf%!7U-!N+g2Wkuu(Ty@NTv_n5iNN#n!gA`~&5Axudf~ zW@-w$5n(s1#0+eWf5NtevFYezV`Bpwhz|)ZDUYKRunMAnNM2!kiH6Zg;+=J=OMGe5 z3&k9xq%0kI8EsGU`L>s9pMIBa9d(G#mu7{nPV>;TwN>O*e^~T@M zVTS=R;fm)nD&BV=&376#nFRNVdcH|;n>#k?4*DAQrk@V*Bg8O5>XHiH3aYEbwLJAT zEaBu(j0}On4>JIjJ&SW`9kI%njm!?t*;$OFFVeWgFvMXt)z(5VMW9Av7>V-K*Q54J z(|!Fr@`PTU^~M8K<+Kb4-qdti!+FjuFZ|g`sq1;`|8KBo_c6$AAc{yL0J}+^y(p?$ zqpqg>ZG%(|f2r#u?b>QaWsk7a6{Kl$*JmL*ku)HO`<4p>JAhgV_5LI)!$bj?w<*GN z3x5hp`Ug!*fqY{*u-pc)dS_zIBc^qiAUx?xd*|0QPG=k0z;IyDs$K?5E_|lr?ap|+ z+oa5QrDM)iY=!D?U`*le$Hh2Sc?GBm&Q>!Pevjnfnjh{pBH= z*CZE>7;8^7%IO{ei(|x`lTfAHT6{1kI)=%)5X`pM{$4QY!DxU{1}p_GFSJiLs|Fpb zG(~*Qb$0e{dsu3^i9QdByQ z<@zKcAzk+2hqE>`2;M}gh0Tta8;w`z*M3~wa8zs<&%5sHqMKB!3NI7!!Z4CNB!y_n zd!A!c{T||lX;}N0Sa0Z$ubI{u-?mxW1ZP`YzcH!4#Qs$6z{vaT8C`UX3y^5&QQ`(?K>rO} zc&bwVDk_5Nk+ihEy}7mZ+xAHDYo^XhOi(e~ch;zns?2q~#=vw4h(Sic@hGhP@(Jo& zZ%xVACqa&IuHeBM_g5RS*p;rWnhHBj^q#OxdS>JDue=KP`PLnngz^EVd>g@*V9)70 zRNzx{II1qgHz=E93PTfSDsk!)S{ov!EqyMt{oL|9=kNu z-p9XG{GD z>WP=z^j2&zdyXx>=_TM0U(-uyHTiGXKO~KXe)waX{$lk*z-Y{W8b2Kc+>?_a`1+F~ zgaMgM8&Y7rdAVSd4Waa>r>9UL0L-ch08njhv*PQ#LDOp(h}r}V=m9v0yH2wXF@0D? zDtWfDsz?Yc@)L=yej+sAfu7l=C9~3N*p{J>pq<<)jrBf&L3G={6=_~=cp>VRmkA2& zQKlcx*MBE5-#t1~=o2#xZw|ZHiE#2evqVEGTuM2jf{EGt_m|<}y)@T+j7}+ZG|3vt zQ4Z-*&#$5uXlZF_(lh`y#jCpz3DvJTZ%$aDAq&AhB_);DWPWgPFcTq*i2t-N0H5(X z>mDj<`IeSHhp(XEPDl#iUN183vsec*0XMEr5S@zTsAYTr^c|qQ%x(=*+7sQcy&-bV1oisTN$=Kq51D)=Hqk&Gk?+Rjlog|AIF zH-wDDy9&QWZ1aCX{DXXM{u{#l{{#UAY=bjF6Y$Rp4z+xd!XXd<=EqQK!%8>FCdj~^ z&_xqDGGi@?ewj~;FSwQAre&SHgR|;y%f#03S0&4Hqh=p&od$92P6=Je^ zXlO{E?fPX`aAS9x{}hW3COZM(AD#t(hDXe=5BLTtz6TSYxWTv$me)Hrg8eVQ?;sG^ zI{;snjvhC?0bFvF%M`c_kFa{$1y;9CjDd&zA1LF-Kd=8UXpy9j=03c3CX)z0@_)l8 zbNzF3+es;blC4jNjhlqj=ICYqWb*Ne$&H)91oH~UGu1QA6tM!XhPa6YX8Wk;%A=W-a`RUMctb zeb7U78F;{`xHG=w^4!if0>h~5^F=q0!rbgEjul*D%^H_3Ky=>xKXF6xs(f|N*oRJ+ z=g!w6qf_w72Q;e?v0@lon9>XI-~SbwC^uUqk~W8B`~;Tfn+J56#o(C*aYd)V1`^+$ z=@GDc2K!uLVc{-aJe$F8!$%aLzvQP+K*?x;lJm3-nqIJ}Sq5(l$^#<@CMgxwa2$+raCkv)kJKx*iyl78-Mb;VxoNC#n)uF;VCI*?rbAVKy zyB%BGCh*zJQpE$dtEpLO-w|8*78EKlELwAUrI1+-BBF^Kw^1E7#~q;UxoZ^urlZ4r z_X$zTpRoyfFHGRplA=H4?bs;pZV#Vn%If{GwPg(4$Ll#C!bX_2!^l8oeBwy1~* zLXjkvl5@^cK|&EFODb~CIl~=gckg}9-urvL`{Ul{oc`0cT}2gZ%{Av3ZyK>GwI7ty zwTqT!+6{6K0b~pyqrQGUu@$n(+LVO*Zh-@g1Li7PYp{ksy2r&t~MfF(mDAp~Wub70DtLsMsTQlN5zglz7a0boAmD#POACN*p(ZI}zC$yXKwa zFGu{S<6=$|5@9#<&aC~2qN6;U6mfQY-r6u5UD~2art&O_$j@>0B#Nki$!~IEZrmYqYq~&EF>c(O7-fB>UrvH$l1x$2vdm9(24k|$ae;~lb4B&vZ zE=cnL*5j_ZY4@C|%tN3=0-46g_HF(fMF?WRFdbY#0Il66nxn*YMi`}Cb+o4qL}Yi8 zp#RD_kp7 z@?Qi3F=LH8mMzfO9yWSX5RFxuTC{=QRYy5F%- z+P$qGSn+7L)2gnq%^wgXX_p;m7QjC8zYv>I)Eq9YvKLXzRN@eZcP5$M+@$?l)JBCU&l`*j6PooP}rVfw+|fQbsW z$q9)^@{5e_p4})Zwt4yWO4hJOQDs-`?pGx~xz5pnqxV8DW#NnjRw$q`J`5&Pqd_bQ zoRoAUHzfCjJ)%o79j^3PvslJ?bYTtUFHDotC&4$SLt|fE^`FSnk{l>=%9=<3!9!#A zMZrxK(#=7U+f0!A<0Kn)cOYJ79DH(3h1k=%a~wvEC84`>X~&UVvyKI+AQf0spOeTv z0G@)Ll~o>@@FpK#J3D4A#Blp(eZ5qwU1lHNPVq*Yu}zjP=ua@)Hs~|WGp&ACid8Xm zS66)p+KHptB#exzB_z73rEzm_YaOgLWyN#!l&lj0Z~COZ0S#e}cQ<+as`0jqx;NfQ z`B6h<(F}UvaYcGCo4&{iNoepL@{BeEy?UzKm=`9}1 z1merByY5n(DKj-vhjL*^?@N7o|uImU^FkmIP z{Ml)c8mG0rd-pE&6nn)68f1!EWSLd#;xc=ut3K0xmn2p4NbWvzyE6lTf2LkVKe!5d zGY@56KZf(V5TId_hQC<4O81h}O}z+;fc`KNOhK17y2a4Z!7!Fd*%VePNH|#bze4m; zo5=8NGm5=hrlUQses7!RG4%0Zj7c$|V+3*!X{HbDTqbBHpoN|2PACrmspal`sr84_ z^|&~LF7Mn<9f8MfpH{{ycdj!2flM?0ktvj^GNqmTEkmIyrDp3v&}Q8w%F6QCV$IT*KGRW)*UE#)M{-^ijFgI&=boL zQJPGgFvhSdN#%l4OW*lroCl9FH#Eh_0#Iq|G0a^uVI9A-c>uT^m!T zP7E~EO`Zq5mOTa5mBg0)JIz0wHZ=3j3O#vZ&Xr1=SLC_3@UbuKI$Mfov&*T-5iM?8 z2hXFP9!nTZl9oMZ?qdk1x2W+xM-Vb#s8>Vlo-%Sgvv}Oij6@PK>bKf&Efi!`t+VLK z|MQ4Te)60L0K|E{g%^KlU6C%ayN-Eu-X&E%D-1ZNY`f`9CS@Er_1l`mJ6TkcZ<*pv zS`fsQ4HSY8b)vB!>_EIusL%Y)Mj)kphnw3FiU-*O6;HqKXU<}rtI6|)cScST#%4yM-h?US18(TR)co1E0K9V00v#zwNv^#5I<7ZZDqA0}e z{v(jgZJ&%?ZOQkO!^4M!QWSR6%ztxWS~Lc;h~;C|qSX>jJEDu^hWsc`rHnntyuK{y zQKWD5IagU!@yLjsZc!NPvUageW^44F!etd$upAMflY-3Kx873a>#ZtG+GoyrLt!)4 zXMzb_g&M*K=w8q{q5J55*)JVb|H`q(?tmNp(oLQXAi}EFWN8Qqe_v?ezd%IQM#i@H z6bc#uY~oeZLV+Vu8*BTao%381C>NtAYmdbm8bdJ2MUB#=n(tYk!4h7sqJg=9cmT62 zLtCmuAK1izY-YqGpZ8$M4I+8o*qNoh9W++%-ALU_wTsYz0k;4_`WV!GwEX$yt6>J2 z{=$85aI@ zuhtQQVphBO@z8toIh&=Jp$QC_)DENF=87dFfLsEC8da$WTQUkuQjj$$oKXa- zq}oKKzv!k^1NRG8lk+X@ViRDw8nPieI}_=zt8T`pClkDwHbZ>;)PnY z;&iFup>RXFlfM56K`szpP$#OUdCqjr?!x6PvRXWde!&zW^Uwk&0?(Qf5zvi+y7kJn z1T0CcGi#bEP+Ldz$ti$%yt*jG>_xWnPCw9d2mGEOk@|?Ax3i4O@?38zTC?d)#P}GB z)&UPQmfc7B^5uu5Tq#M@JY!W@kR9Gy`1bd`Ujgi>gy(;rj^Dca-TP6hVc-+c;6@6l zM@+@3oh2am*CH<`s3JY{&Cc}T!2ZnIKy{`-rjF{zv$f*P9Xw@};vL2c&>x^oVHCL0I8=lBV>y1wX^*~_w2cAh0&FY*f@naw$SWz5Y{0-dvhg0mo z0ysh)DGN}{UH9byQ?X(mx1f9z9g)*B%|c0+0iI0ZQv)&LgmUK$(Y(eU#HB&x&C0U9M!;xTl<@ zv`F0$#=hJbLKE-lihs5ACF_P8US}(i`7cHxrvyR4?vM@6v&8>93}WyFML*z45FbMs z|00ca)L}u^vl>^sDfvFQ3{o^1ltOz2KBQ8|D>bD+&@`R~hYe4p!dc)ikp*T62svDu zZdo0aolT!r(|Q_}k@EAy#|g`o+LlEFMuyJL@uj~YYC~oQz*~1Hj16-*kn}MeMvl;x zK)$F}sXcac9(6ym<@bdh^bNy&f<7hY!nMXm(Gcd4bhWhL!U=uY=z))CJafO-5UIrZ zzcL)Na=B`Kxd{vkt}N}(#l`bLg(G)XtIz^^RzY%n7ODJTj)6A0ReyeaqJs9-+OPOK z@~z^(ySE-@c$91`^tph84@jtJPLolvNE^woPbs{9eG+d9`g}i#n2I0$A_sPd%o7Fl zju7LrDJZF0{S5yjrB76;Pk{vMD

Q`i5$Qg2tSw)n7|6tv^x*9sGvek`Q&fga<{^Yic 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 workspace | dashboard/provider state helpers, create/list empty-state paths | `provider.connection_missing` | Open Provider Connections | no | navigation only; existing surface auth stays authoritative | +| Connection disabled | `ProviderConnection.is_enabled`, `ProviderConnectionSurfaceSummary::readinessSummary()` | yes | record | Provider Connections list/detail, provider-state helper | `provider.connection_disabled` | Open Provider Connection | no | existing enable/disable mutations are confirmed, audited, capability-gated | +| Consent not granted / required / failed / revoked | `ProviderConnection.consent_status`, `RequiredPermissionsLinks::adminConsentPrimaryUrl()`, `ProviderReasonTranslator` | yes | record + environment | Provider Connections, Required Permissions, blocked verification reports | `provider.admin_consent_required` | Grant admin consent / open required permissions | no | existing consent navigation only; no inline mutation | +| Verification status unknown / pending / healthy / degraded / blocked / error | `ProviderConnection.verification_status`, `ProviderVerificationStatus`, `ProviderConnectionSurfaceSummary` | yes | record | Provider Connections, dashboard readiness cards | `provider.verification_required`, `provider.verification_failed`, `provider.ready` | Run verification / open last check run | no | existing run start uses `StartVerification` + `OperationRun` | +| Last check timestamp | `ProviderConnection.last_health_check_at` | yes | record | Provider Connections list/detail | stale / recently checked nuance | Open last check run or re-run verification | no | proof-only; no mutation | +| Last error reason code | `ProviderConnection.last_error_reason_code`, `ProviderReasonTranslator` | yes | record | Provider Connections diagnostics, verification reports | consent missing, credential missing, permission missing, auth failed, etc. | Open required permissions / provider connection / re-run verification | no | translated to next-step options; existing proof links only | +| Last error message (sanitized) | `ProviderConnection.last_error_message`, sanitizers in resource | yes | record | Provider Connections diagnostics | secondary detail only | none primary; open proof if needed | no | must stay secondary and redacted | +| Provider capability groups | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::deriveCapabilityGroups()` | yes | environment | Required Permissions summary/cards | capability missing / at risk / supported | Open required permissions / re-run verification | no | derived from stored permission comparison | +| Primary capability group | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::primaryCapabilityGroup()` | yes | environment | Required Permissions summary | dominant missing capability | Review permissions / re-run verification | no | derived only | +| Missing application permission count | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::deriveCounts()` | yes | environment | Required Permissions summary/issues, dashboard required-permissions action | `provider.required_permissions_missing` | Open required permissions / admin consent | no | derived only | +| Missing delegated permission count | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::deriveCounts()` | yes | environment | Required Permissions summary/issues, dashboard delegated-permissions action | `provider.delegated_permissions_missing` | Open required permissions / re-run verification | no | derived only | +| Freshness / stale permission evidence | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::deriveFreshness()` | yes | environment | Required Permissions summary/issues | `provider.verification_stale` | Start / re-run verification | no | derived from stored timestamps only | +| Overall permission posture | `ManagedEnvironmentRequiredPermissionsViewModelBuilder::deriveOverallStatus()` | yes | environment | Required Permissions badge | blocked / needs attention / ready | route to dominant provider action | no | derived only | +| Existing dashboard provider blocker | `EnvironmentDashboardSummaryBuilder::providerOperatorGuidance()` | yes | environment | Environment Dashboard | continuity source only | Open required permissions | no | current dashboard selection layer only | +| Last provider verification run | `OperationRun` rows of type `provider.connection.check`, `EditProviderConnection::view_last_check_run` | yes | environment + record | Edit Provider Connection, verification reports | `provider.verification_failed` / proof continuity | Open last check run | no | existing proof-only deep link | +| Verification run start | `StartVerification`, `ProviderOperationStartResultPresenter` | yes | environment + record | existing provider actions | `provider.verification_required` | Run verification | yes | capability-gated, queued/deduped/blocked via existing `OperationRun` contract | +| Required Permissions route and admin-consent URL | `RequiredPermissionsLinks` | yes | environment | dashboard/provider/detail links | permissions blocker remediation | Open required permissions / open admin consent | no | link-only helper; no render-time remote call should be introduced | + +## Observed Gaps To Avoid Inventing Around + +- There is no single repo-real `ProviderReadinessPresenter` yet. +- There is no repo-real standalone Required Permissions page-report file today. +- There is no repo-real dedicated provider-health page class to reuse. + +These are implementation-shape gaps, not reasons to create new provider truth. + +## Guidance-Shaping Rules Derived From The Map + +1. Prefer stored counts, statuses, capability groups, freshness, and last-run proof over raw diagnostic detail. +2. Use `ProviderReasonTranslator` and `VerificationLinkBehavior` for safe next-step phrasing before adding another local mapping table. +3. Treat admin-consent navigation and verification-run start as existing safe actions; do not invent auto-remediation. +4. Keep raw permission rows, copy payloads, and sanitized error messages secondary. +5. Keep the guidance request-scoped and DB-local. diff --git a/specs/353-provider-connections-resolution-guidance-v1/plan.md b/specs/353-provider-connections-resolution-guidance-v1/plan.md new file mode 100644 index 00000000..f4cba3c6 --- /dev/null +++ b/specs/353-provider-connections-resolution-guidance-v1/plan.md @@ -0,0 +1,317 @@ +# Implementation Plan: Spec 353 - Provider Connections Resolution Guidance v1 + +- Branch: `353-provider-connections-resolution-guidance-v1` +- Date: 2026-06-04 +- Spec: `specs/353-provider-connections-resolution-guidance-v1/spec.md` +- Input: Spec 353 + repo inspection of Provider Connections, Environment Required Permissions, provider verification/permission helpers, and Environment Dashboard provider blocker guidance. + +## Summary + +Add one derived provider-readiness guidance layer to the existing Provider Connections and Required Permissions surfaces, and make the Environment Dashboard provider CTA land on a target page that explains the same blocker clearly. + +The implementation stays narrow: + +- reuse existing provider connection, permission, capability-group, verification, and last-operation truth +- keep provider actions navigation-first and repo-backed +- preserve onboarding, verification execution, permission calculation, and audit ownership +- avoid live provider calls during render + +## Technical Context + +- Language/Version: PHP 8.4.15, Laravel 12.52.x +- UI stack: Filament 5.2.x, Livewire 4.x +- Database: PostgreSQL, no schema change planned +- Testing: Pest unit + feature/Livewire + one strategic browser smoke +- Validation lanes: fast-feedback + confidence + browser +- Local runtime posture: Sail-first +- Deployment/runtime impact: no expected env, migration, queue-family, scheduler, storage, or panel/provider change +- Global search: unchanged; `ProviderConnectionResource` remains not globally searchable + +## Current Repo Truth That Constrains The Slice + +- `ProviderConnectionResource` already exposes provider readiness signals as columns/infolist entries: + - consent status + - verification status + - provider capability + - last health check + - last error reason/message +- `ViewProviderConnection` already keeps one primary `Grant admin consent` header action and groups the rest under `More`. +- `EditProviderConnection` already surfaces `View last check run` and the existing provider-operation actions, but it is still an action-centered maintenance surface rather than a first-screen readiness-guidance surface. +- `EnvironmentRequiredPermissions` already renders a summary, capability-group overview, issue cards, copy payloads, and a technical-details section around a native permission matrix. +- `ManagedEnvironmentRequiredPermissionsViewModelBuilder` already derives: + - overall readiness (`blocked` / `needs_attention` / `ready`) + - counts + - feature impacts + - capability groups + - freshness +- `EnvironmentDashboardSummaryBuilder` already elevates `required_permissions` / `delegated_permissions` into `operatorGuidance`. +- There is no current `EnvironmentProviderHealth` page class to reuse; provider-health truth is distributed across existing provider/verification helpers. + +## Domain / Model Implications + +- No schema or migration change is planned. +- No new persisted readiness entity, status column, enum family, or provider registry is allowed in this slice. +- The narrowest acceptable implementation shape is one derived provider-guidance adapter over existing `ProviderConnectionResolver`, `ManagedEnvironmentRequiredPermissionsViewModelBuilder`, and `OperationRun` proof truth. +- Existing ownership boundaries remain unchanged: + - provider connection truth stays provider/resource owned + - required-permissions truth stays builder/view-model owned + - verification proof stays `OperationRun` owned + +## UI / Filament / Livewire Implications + +- Filament v5 continues to run on Livewire v4.x; no version or API drift is permitted. +- No panel/provider registration change is allowed; `apps/platform/bootstrap/providers.php` remains untouched. +- `ProviderConnectionResource` stays not globally searchable. +- Existing destructive or high-risk actions must keep their current confirmation, authorization, notification, and audit posture. +- No new asset registration is planned, so there is no expected `filament:assets` deployment change for this spec. + +## RBAC / Policy Implications + +- Workspace membership and environment entitlement remain the only scope authorities. +- Existing provider capabilities continue to decide whether actions are visible, disabled, or executable. +- Guidance selection itself must remain safe for unauthorized users by operating only on already-authorized page state. + +## Audit / Logging / Evidence Implications + +- Existing provider verification start/result handling and `OperationRun` proof links are reused unchanged. +- No new audit stream, notification family, or evidence artifact is planned. +- The implementation must keep provider-readiness render paths read-only and side-effect free. + +## Data / Migration Implications + +- No database migration, backfill, or persisted projection is planned. +- All derived readiness output must be request-local and DB-backed from already stored truth. +- Compatibility shims are not justified because no data shape replacement is proposed in this prep slice. + +## Rollout Considerations + +- No feature flag is expected because the slice is a bounded presentation improvement over existing repo truth. +- Staging validation should still prove three operator states explicitly: + - missing permissions + - verification follow-up + - calm ready state +- Production risk is limited to UI guidance hierarchy and wrong-link regressions, so tests and browser smoke remain the main rollout controls. + +## UI / Surface Guardrail Plan + +- **Guardrail scope**: + - Provider Connections list and view, plus edit-page action/proof continuity + - Environment Required Permissions + - dashboard target continuity only +- **Affected surfaces**: + - `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` + - `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php` + - `apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php` + - `apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php` +- **Native vs custom**: + - preserve native Filament list/detail/page ownership + - avoid new custom page families + - allow one bounded derived guidance presenter/adapter if necessary +- **Shared-family relevance**: + - status messaging + - next-action guidance + - operation proof links + - dashboard-to-detail continuity +- **Required tests / smoke**: + - focused unit tests for derived guidance selection + - feature tests for Provider Connections and Required Permissions + - one bounded browser smoke for priority and target continuity +- **UI/Productization coverage**: + - update `ui-009-provider-connections.md` + - create/update `ui-077-required-permissions.md` + - close the current UI-audit registry for UI-072/UI-077 in `route-inventory.md` + - update `design-coverage-matrix.md` only if route-inventory counts or classification change + - update `strategic-surfaces.md` only if UI-077 is intentionally promoted from its current registry classification + - use `unresolved-pages.md` if browser or screenshot evidence cannot be durably stored under the Spec 353 artifact path + - save screenshots under the Spec 353 artifact path, or document the host-visible artifact blocker honestly + +## Shared Pattern And System Fit + +- **Preferred reuse path**: + - current dashboard `operatorGuidance` structure + - current `ManagedEnvironmentRequiredPermissionsViewModelBuilder` truth + - current `ProviderConnectionResolver` truth + - current `OperationRunLinks` / verification-run start UX +- **Likely implementation shape**: + - one bounded derived adapter under a current provider/guidance support path + - adjacent seams such as `ProviderReasonTranslator` / `VerificationLinkBehavior` may stay contextual helpers, but they do not need to become the primary runtime path +- **Avoid**: + - new provider framework + - new persisted readiness state + - new route/query contract unless absolutely required for continuity + +## OperationRun UX Impact + +Spec 353 does not create a new `OperationRun` type. It reuses the existing provider verification path: + +- `StartVerification` +- `ProviderOperationStartResultPresenter` +- `OperationRunLinks` + +Implementation responsibility is limited to when these existing links/actions become the primary or secondary action for a derived blocker. + +## Likely Runtime Files + +| Area | Repo-real files | +|---|---| +| Provider Connections runtime | `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `Pages/ListProviderConnections.php`, `Pages/ViewProviderConnection.php`, `Pages/EditProviderConnection.php` | +| Required Permissions runtime | `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php`, `apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php` | +| Permission truth | `apps/platform/app/Services/Intune/ManagedEnvironmentRequiredPermissionsViewModelBuilder.php` | +| Provider readiness truth | `apps/platform/app/Support/ResolutionGuidance/Adapters/ProviderReadinessResolutionAdapter.php`, `apps/platform/app/Services/Providers/ProviderConnectionResolver.php`, existing `OperationRun` proof, with `ProviderReasonTranslator.php` / `VerificationLinkBehavior.php` only where directly helpful | +| Dashboard continuity | `apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php` | +| Links/helpers | `apps/platform/app/Support/Links/RequiredPermissionsLinks.php`, existing `ManagedEnvironmentLinks` / `OperationRunLinks` | +| UI audit docs | `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md`, `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` | + +## Likely Test Files + +| Layer | Planned file | +|---|---| +| Unit | `apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php` | +| Feature | `apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php` | +| Feature/Filament | `apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php` | +| Browser | `apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php` | + +## Implementation Approach + +### Phase 0 - Repo Truth Gate + +1. Re-read `spec.md`, `plan.md`, `tasks.md`, `repo-truth-map.md`, `checklists/requirements.md`, and `contracts/provider-readiness-signal-map.md`. +2. Re-verify the current runtime truth in the provider/resource/page/helper files listed above. +3. Keep draft mismatches explicit: + - no `EnvironmentProviderHealth.php` + - no existing `ui-077-required-permissions.md` +4. Confirm no migration, package, env var, queue-family, storage, panel/provider, or global-search change is required. + +### Phase 1 - Tests First + +1. Add unit coverage for deterministic guidance selection: + - no provider connection + - disabled/unusable connection + - missing application permissions + - missing delegated permissions + - verification blocked/error + - verification stale/unknown + - ready/no urgent action +2. Add feature coverage for Provider Connections: + - one dominant case + - one primary action + - secondary proof links only when repo-backed + - no fake remediation buttons +3. Add feature coverage for Required Permissions: + - blocker guidance renders before the raw matrix + - application/delegated/stale cases map to the expected action hierarchy + - copy payloads and technical details remain secondary +4. Add one browser smoke: + - dashboard -> target continuity + - permissions-missing state + - verification follow-up state + - calm ready state + +### Phase 2 - Derived Guidance Contract + +1. Choose the narrowest implementation shape: + - prefer one bounded provider-guidance adapter/presenter + - avoid broadening `ReviewPackOutputResolutionAdapter` into a provider super-framework +2. Build one derived provider-readiness payload with: + - key + - title + - status + - tone + - reason + - impact + - primary action + - secondary actions + - details + - source metadata +3. Consume only stored truth: + - `ProviderConnection` state + - permission counts and capability groups + - freshness + - last `provider.connection.check` run + - reason translation / next-step mapping +4. Keep priority ordering explicit and narrow. + +### Phase 3 - Provider Connections Integration + +1. Add a top guidance presentation to Provider Connections list/view without removing the existing table columns, infolist truth, or safe action groups. +2. Reuse existing repo-backed targets: + - `Grant admin consent` + - `View last check run` + - `Run verification` + - `Open required permissions` +3. Keep destructive/high-impact actions unchanged: + - confirmation + - authorization + - audit + - notifications +4. Do not enable provider actions merely because guidance makes them more visible. + +### Phase 4 - Required Permissions Integration + +1. Replace the current guidance-first-but-generic summary with one explicit blocker case. +2. Reuse the current capability-group and counts truth before inventing any new provider state. +3. Keep copy payloads and the raw matrix secondary. +4. If verification or last-operation proof is stronger than the raw permission count, the page may surface that as the primary blocker only when repo truth clearly supports it. + +### Phase 5 - Dashboard Target Continuity + +1. Keep the Environment Dashboard provider guidance selection logic narrow. +2. Adjust continuity only if required so the linked target surface shows the same blocker class clearly. +3. Avoid adding a fragile dashboard-only query contract when current route state is enough. + +### Phase 6 - Copy, Audit, And Browser Proof + +1. Update or add only the copy required for: + - provider readiness blocked + - required permissions missing + - provider verification required + - provider verification failed + - provider connection ready +2. Update `ui-009-provider-connections.md`. +3. Create/update `ui-077-required-permissions.md`. +4. Close the UI-audit registry around UI-072/UI-077: + - update `route-inventory.md` report/screenshot references + - update `design-coverage-matrix.md` only if classification/counts change + - update `strategic-surfaces.md` only if UI-077 is intentionally promoted from its current registry classification + - use `unresolved-pages.md` if browser evidence cannot be durably stored +5. Save screenshots under `specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/` or record the container-local artifact blocker explicitly during close-out if Pest Browser cannot persist host-visible files. + +## Test Strategy + +- **Unit**: + - deterministic blocker ranking and payload mapping +- **Feature/Livewire**: + - Provider Connections list/detail integration + - Required Permissions page integration + - dashboard target continuity if feature-level proof is cheaper than browser-only proof +- **Browser**: + - one small smoke proving real hierarchy and continuity on the rendered UI +- **Render-path guard**: + - fail if provider guidance rendering pulls live provider or Graph work into the page request + +## Risk Controls + +- **Onboarding overlap**: preserve onboarding links as secondary and do not rewrite onboarding ownership. +- **UI overload**: keep one dominant case and collapse technical detail. +- **Fake remediation**: do not add unsupported buttons or pretend provider fixes can happen inline. +- **Render-time remote calls**: limit inputs to existing DB-backed/provider-state helpers only. +- **Audit coverage drift**: keep existing provider action audit posture unchanged and document any unavoidable copy-only discrepancy. + +## Constitution Check + +- Inventory-first / stored-truth-first: PASS +- Read/write separation: PASS +- No live provider calls during render: PASS target +- Workspace/environment isolation: PASS target +- Shared pattern first: PASS if current dashboard/operator-guidance shape is reused +- Provider boundary neutrality: PASS if shared copy stays provider-neutral and details keep provider-specific labels +- UI/Productization coverage: PASS once `ui-009`, `ui-077`, and the required UI-audit registry close-out around UI-072/UI-077 are handled +- Test governance: PASS with explicit Unit + Feature + Browser split +- Proportionality / anti-bloat: PASS if the guidance layer remains derived-only and no new persisted truth or framework is added + +## Open Questions + +- None blocking prep readiness. The main repo-truth caveat is the missing existing `ui-077-required-permissions.md`, which is handled as a create-during-implementation requirement rather than an unresolved product decision. diff --git a/specs/353-provider-connections-resolution-guidance-v1/repo-truth-map.md b/specs/353-provider-connections-resolution-guidance-v1/repo-truth-map.md new file mode 100644 index 00000000..b929c6f4 --- /dev/null +++ b/specs/353-provider-connections-resolution-guidance-v1/repo-truth-map.md @@ -0,0 +1,100 @@ +# Repo Truth Map: Spec 353 - Provider Connections Resolution Guidance v1 + +Status: draft / prep-ready +Branch: `353-provider-connections-resolution-guidance-v1` +Date: 2026-06-04 +Baseline commit before prep branch: `9a564d6b` (`feat: environment dashboard operator guidance consolidation (spec 352) (#423)`) + +## Branch And Working-Tree Safety + +- Starting branch before prep: `platform-dev` +- Initial `git status --short --branch`: clean +- Initial `git diff --stat`: empty +- Spec Kit branch created via repo script: + - `./.specify/extensions/git/scripts/bash/create-new-feature.sh --json --short-name 'provider-connections-resolution-guidance-v1' --number 353 'Provider Connections Resolution Guidance v1'` +- Current branch after setup: `353-provider-connections-resolution-guidance-v1` +- Current uncommitted change before writing prep artifacts: only `specs/353-provider-connections-resolution-guidance-v1/` + +## Why 353 Was Selected + +- Spec 352 intentionally made provider blockers the dominant Environment Dashboard guidance case. +- The dashboard now links operators into Provider Connections / Required Permissions, but those destination surfaces still read diagnostics-first. +- Provider readiness is already called out as a grouped P1 follow-up in: + - `docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md` + - `docs/ui-ux-enterprise-audit/target-experience-briefs/provider-readiness.md` +- The slice is small and repo-ready because the current repo already has the necessary underlying truth: + - provider connection status fields + - permission counts and capability groups + - verification runs and proof links + - dashboard operator guidance precedence + +## Why Close Alternatives Were Deferred + +- Governance Inbox follow-through is already farther along in the current spec sequence and is not the blocker named by the user for this prep. +- Customer-facing localization is still valuable but does not close the provider-blocker destination gap opened by Spec 352. +- Broader onboarding/provider redesign would be too large for the current narrow follow-up slice. + +## Completed-Spec Guardrail Result + +| Related spec | Current signal | Handling for Spec 353 | +|---|---|---| +| Spec 338 | checked implementation tasks and browser-smoke history | completed baseline; do not reopen scope contracts | +| Spec 339 | checked implementation tasks over provider scope hardening | completed baseline; reuse scope rules only | +| Spec 350 | shared guidance framework and contract artifacts already exist | context only; reuse, do not reopen | +| Spec 351 | repo-real review-output action semantics with residual browser notes | reuse shared guidance lessons only; do not hide residual notes | +| Spec 352 | `repo-truth-map.md` says `Status: implemented` | immediate dependency; follow dashboard target continuity only | + +No `specs/353-*` package or `353-*` branch existed before this prep. + +## Runtime Seam Inventory + +| Surface / seam | Repo-real path(s) | Notes | +|---|---|---| +| Provider Connections list | `apps/platform/app/Filament/Resources/ProviderConnectionResource.php`, `Pages/ListProviderConnections.php` | Table already shows consent, verification, provider capability, last check, and current environment filter behavior | +| Provider Connections view | `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` | Already exposes primary `Grant admin consent` CTA and grouped secondary actions | +| Provider Connections edit | `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` | Already exposes `View last check run` plus existing provider operations | +| Required Permissions page | `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php`, `apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php` | Already has summary, guidance copy, issue cards, copy payloads, and technical-details disclosure | +| Permission posture builder | `apps/platform/app/Services/Intune/ManagedEnvironmentRequiredPermissionsViewModelBuilder.php` | Already derives overall status, counts, capability groups, feature impacts, and freshness | +| Provider readiness summary | `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php` | Already derives consent state, verification state, readiness summary, and primary provider capability | +| Provider blocker translation | `apps/platform/app/Support/Providers/ProviderReasonTranslator.php`, `apps/platform/app/Support/Verification/VerificationLinkBehavior.php` | Already translates reason codes and classifies required-permissions / provider-connections paths as internal diagnostic targets | +| Dashboard provider blocker | `apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php` | Already promotes `required_permissions` / `delegated_permissions` into provider `operatorGuidance` | +| Onboarding/provider state helper | `apps/platform/app/Filament/Resources/ManagedEnvironmentResource.php` | Already has `providerConnectionState()` and related provider-state presentation helpers | + +## Draft-To-Repo Deviations That Must Stay Explicit + +| User draft assumption | Repo truth | Spec 353 handling | +|---|---|---| +| `EnvironmentProviderHealth.php` exists | no such page class exists | do not invent it; use existing provider readiness helpers | +| `ui-077-required-permissions.md` already exists | no file currently exists | create it during implementation instead of claiming an update | +| Provider Connections still needs a primary CTA | view page already has `Grant admin consent` | guidance must coexist with the existing safe CTA hierarchy | +| Required Permissions is mostly a raw list | page already has summary, issue cards, and technical details | productize current page instead of rebuilding it | +| Dashboard still needs provider priority work | provider blockers already outrank review-output in Spec 352 | focus on destination continuity, not a new dashboard ranking spec | + +## Likely Implementation Files + +- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` +- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` +- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` +- `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` +- `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php` +- `apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php` +- bounded provider-guidance support class under `apps/platform/app/Support/...` only if needed +- `apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php` only if continuity needs a narrow adjustment +- `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md` +- `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` + +## Files Explicitly Out Of Scope + +- provider API adapters and Graph clients +- onboarding workflow internals beyond existing outbound links +- migrations, tables, enums, or new persisted readiness truth +- customer portal, PDF/HTML renderer, PSA, billing, or AI follow-up files + +## Prep Conclusion + +Spec 353 is repo-safe as a new prep target: + +- the selected candidate is not already prepared as `353-*` +- the dependency chain is explicit +- the needed runtime truth already exists +- the remaining work is a bounded productization/guidance layer, not a provider architecture rewrite diff --git a/specs/353-provider-connections-resolution-guidance-v1/spec.md b/specs/353-provider-connections-resolution-guidance-v1/spec.md new file mode 100644 index 00000000..23a54f2b --- /dev/null +++ b/specs/353-provider-connections-resolution-guidance-v1/spec.md @@ -0,0 +1,516 @@ +# Feature Specification: Spec 353 - Provider Connections Resolution Guidance v1 + +**Feature Branch**: `353-provider-connections-resolution-guidance-v1` +**Created**: 2026-06-04 +**Status**: Implemented (close-out audit pending) +**Type**: Platform productization / provider readiness guidance / operator workflow consolidation +**Runtime posture**: Narrow provider-readiness guidance over existing Provider Connection, Required Permissions, verification, and dashboard truth. No provider architecture rewrite, no new permission model, no onboarding rewrite, and no new persistence. +**Input**: User-provided Spec 353 draft + repo inspection of Provider Connections, Environment Required Permissions, Environment Dashboard provider blocker guidance, and provider verification/permission seams. + +## Dependencies And Historical Context + +This spec is a bounded follow-up over already repo-real scope, guidance, and provider foundations: + +- Spec 338 - Workspace / Environment Resource Scope Contract +- Spec 339 - Provider Connection Scope Hardening +- Spec 350 - Operator Resolution Guidance Framework v1 +- Spec 351 - Review Output Resolve Actions v1 +- Spec 352 - Environment Dashboard Operator Guidance Consolidation +- `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md` +- `docs/ui-ux-enterprise-audit/target-experience-briefs/provider-readiness.md` +- `docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md` + +Repo-truth adjustments against the user draft: + +- There is no `apps/platform/app/Filament/Pages/EnvironmentProviderHealth.php` surface in the current repo. Provider health/readiness truth is currently spread across `ProviderConnectionSurfaceSummary`, `ProviderConnectionHealthCheckJob`, `ManagedEnvironmentResource::providerConnectionState()`, and `EnvironmentDashboardSummaryBuilder`. +- `EnvironmentRequiredPermissions` already exists as a repo-real page with summary, capability groups, issues, copy flows, and technical-details disclosure. Spec 353 must productize this page further instead of rebuilding it. +- `ProviderConnectionResource` already has list, view, and edit surfaces. The view page already exposes one primary `Grant admin consent` CTA and groups the rest under `More`. +- `EnvironmentDashboardSummaryBuilder` already prioritizes provider blockers by elevating `required_permissions` / `delegated_permissions` recommended actions into `operatorGuidance`. Spec 353 must make the target surface equally decision-first. +- `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` did not exist during prep. Close-out must create that report and align the durable UI audit registry links/classification around UI-077. +- `ProviderConnectionResource` is already not globally searchable. Spec 353 must preserve that state; it does not need a global-search change. + +## Spec Candidate Check *(mandatory - SPEC-GATE-001)* + +- **Problem**: Provider readiness blockers already stop evidence refresh, review output readiness, inventory work, and onboarding continuity, but the target surfaces still force operators to translate badges, counts, and verification states into the next safe action themselves. +- **Today's failure**: The Environment Dashboard can now correctly say "provider readiness blocks evidence refresh", but the linked Provider Connections / Required Permissions surfaces still read as diagnostics-first. Operators can see consent, verification, and missing-permission facts without getting one clear blocker statement, one primary next action, and one safe proof path. +- **User-visible improvement**: Provider Connections and Required Permissions become decision-first surfaces that answer "what is wrong, why it matters, and what to do next" in five seconds while keeping raw permission rows and provider diagnostics secondary. +- **Smallest enterprise-capable version**: Reuse stored provider connection, permission, capability-group, verification, and last-operation truth to derive one provider guidance case with one primary action on the existing surfaces. Update dashboard-target continuity, add focused tests, and create/update the necessary UI audit artifacts. +- **Explicit non-goals**: No provider execution rewrite, no new provider framework, no new onboarding wizard, no new permission persistence, no consent auto-remediation, no customer portal, no PDF/HTML renderer, and no new workflow engine. +- **Permanent complexity imported**: One bounded provider-readiness guidance contract or presenter, focused unit/feature/browser tests, one repo-truth map, one signal inventory, and the required UI audit follow-through. No new table, model, enum family, or queue family is intended. +- **Why now**: Spec 352 intentionally made provider blockers outrank review-output guidance on the Environment Dashboard. Without this follow-through, the new dashboard CTA lands on destination pages that still feel diagnostic instead of operational. +- **Why not local**: Copy-only tweaks on one page would leave Provider Connections, Required Permissions, verification proof, and dashboard target continuity speaking different guidance dialects. A small shared derived guidance shape is the narrowest honest fix. +- **Approval class**: Workflow Compression. +- **Red flags triggered**: Strategic operator surfaces, shared interaction-family reuse, and provider-boundary vocabulary. Defense: the slice is explicitly derived-only, reuses repo-real signals, preserves existing capability/audit/OperationRun behavior, and forbids new provider architecture. +- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 11/12** +- **Decision**: approve. + +## Candidate Source And Completed-Spec Guardrail + +- **Candidate source**: + - direct user-provided Spec 353 draft + - grouped follow-up lane: `Provider onboarding/readiness UX cleanup` + - dashboard follow-up explicitly called out by Spec 352 + - provider-readiness target brief and UI-009 page report +- **Completed-spec guardrail result**: + - no `specs/353-*` package existed before this prep + - Specs 338, 339, 350, 351, and 352 already carry checked implementation/prep history and are treated as context only + - no completed spec is being reopened, normalized, or converted back to preparation state +- **Close alternatives deferred**: + - further Governance Inbox closure after Spec 346 + - customer-facing localization follow-through + - commercial/artifact-lifecycle productization + - broader provider/onboarding redesign +- **Smallest viable implementation slice**: existing Provider Connections list/view surfaces, existing edit-page action/proof continuity, the existing Environment Required Permissions page, and dashboard target continuity only: one dominant provider-readiness case, one primary action, secondary proof links, and technical details on demand. + +## Spec Scope Fields *(mandatory)* + +- **Scope**: workspace-owned provider hub plus environment-owned permissions follow-through +- **Primary Routes**: + - `/admin/provider-connections` + - `/admin/provider-connections/{record}` + - `/admin/provider-connections/{record}/edit` + - `/admin/workspaces/{workspace}/environments/{environment}/required-permissions` + - `/admin/workspaces/{workspace}/environments/{environment}` +- **Data Ownership**: + - `ProviderConnection` remains workspace-owned and linked to `ManagedEnvironment` + - permission posture remains derived from existing stored `ManagedEnvironmentPermission` truth through `ManagedEnvironmentRequiredPermissionsViewModelBuilder` + - verification proof remains `OperationRun` + verification-report truth + - any new readiness case remains derived-only; no new persistence is introduced +- **RBAC**: + - existing workspace membership + environment entitlement remain authoritative + - Provider Connection actions continue to use existing capabilities such as `PROVIDER_VIEW`, `PROVIDER_MANAGE`, and `PROVIDER_RUN` + - Required Permissions page keeps deny-as-not-found workspace/environment semantics + - no new authorization plane or hidden query authority is introduced + +For canonical-view or mixed-scope follow-through: + +- **Default filter behavior when environment-context is active**: Provider Connections continues to use explicit `environment_id` filtering only; Required Permissions keeps the route environment authoritative. +- **Explicit entitlement checks preventing cross-tenant leakage**: provider records remain record-owned and workspace-scoped; required-permissions routes remain workspace+environment scoped; dashboard deep links remain current-scope only. + +## UI Surface Impact *(mandatory - UI-COV-001)* + +- [ ] No UI surface impact +- [x] Existing page changed +- [ ] New page/route added +- [ ] Navigation changed +- [ ] Filament panel/provider surface changed +- [ ] New modal/drawer/wizard/action added +- [x] New table/form/state added +- [ ] Customer-facing surface changed +- [ ] Dangerous action changed +- [x] Status/evidence/review presentation changed +- [x] Workspace/environment context presentation changed + +## UI/Productization Coverage *(mandatory when UI Surface Impact is not "No UI surface impact")* + +- **Route/page/surface**: + - Provider Connections list/view + - Provider Connections edit-page action/proof continuity without mandatory duplicate top guidance + - Environment Required Permissions + - Environment Dashboard provider-blocker target continuity +- **Current or new page archetype**: + - Provider Connections: existing strategic provider/integration surface + - Required Permissions: existing diagnostic/list-plus-guidance surface +- **Design depth**: + - Provider Connections is already a Strategic Surface in the current audit registry + - Required Permissions is currently a repo-verified domain surface in `route-inventory.md`; any promotion to Strategic Surface must be reflected in the registry during close-out +- **Repo-truth level**: repo-verified runtime surfaces +- **Existing pattern reused**: + - Spec 350/352 resolution-guidance hierarchy + - existing dashboard-to-detail deep-link patterns + - existing provider verification / permission guidance links +- **New pattern required**: one bounded provider-readiness guidance contract or presenter; no new generic cross-domain framework +- **Screenshot required**: yes, under `specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/` +- **Page audit required**: + - update `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md` + - create or update `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` because it is currently absent in repo truth +- **Customer-safe review required**: no; operator/internal only +- **Dangerous-action review required**: yes, but only to preserve existing confirmation/authorization/audit posture on provider actions while guidance becomes more prominent +- **Coverage files that must be reviewed in close-out**: + - `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md` + - `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` + - `docs/ui-ux-enterprise-audit/route-inventory.md` to link UI-077 and refresh UI-072/UI-077 report or screenshot references + - `docs/ui-ux-enterprise-audit/design-coverage-matrix.md` only if route-inventory counts or classification change + - `docs/ui-ux-enterprise-audit/strategic-surfaces.md` only if UI-077 is intentionally promoted from its current registry classification + - `docs/ui-ux-enterprise-audit/unresolved-pages.md` if browser or screenshot evidence cannot be durably stored under the Spec 353 artifact path +- **No-impact rationale when applicable**: N/A + +## Cross-Cutting / Shared Pattern Reuse *(mandatory)* + +- **Cross-cutting feature?**: yes +- **Interaction class(es)**: status messaging, next-action guidance, dashboard-to-detail continuity, verification proof links, diagnostic disclosure +- **Systems touched**: + - `App\Support\EnvironmentDashboard\EnvironmentDashboardSummaryBuilder` + - `App\Filament\Resources\ProviderConnectionResource` + - `App\Filament\Pages\EnvironmentRequiredPermissions` + - `App\Services\Intune\ManagedEnvironmentRequiredPermissionsViewModelBuilder` + - `App\Services\Providers\ProviderConnectionResolver` + - existing `RequiredPermissionsLinks`, `ManagedEnvironmentLinks`, and `OperationRunLinks` +- **Existing pattern(s) to extend**: + - current `operatorGuidance` on the Environment Dashboard + - existing Spec 350/352 guidance hierarchy + - existing verification start/proof link behavior +- **Shared contract / presenter / builder / renderer to reuse**: existing dashboard/operator-guidance structure, `ManagedEnvironmentRequiredPermissionsViewModelBuilder`, `ProviderConnectionResolver`, and current verification/result links before adding anything broader +- **Why the existing shared path is sufficient or insufficient**: the repo already has the stored provider truth and one shared guidance family, but Provider Connections and Required Permissions did not yet consume that truth as one dominant provider-readiness case. +- **Allowed deviation and why**: one small provider-specific derived adapter is allowed because reusing the review-output adapter directly would blur provider truth and output-readiness truth. +- **Consistency impact**: blocker title, reason, impact, action hierarchy, and deep links must align between dashboard, provider connection, and required-permissions surfaces. +- **Review focus**: block a second provider-readiness dialect, fake remediation buttons, or live provider calls during render. + +## OperationRun UX Impact *(mandatory)* + +- **Touches OperationRun start/completion/link UX?**: yes, existing `provider.connection.check` start and proof-link behavior only +- **Shared OperationRun UX contract/layer reused**: + - existing `StartVerification` + - existing `ProviderOperationStartResultPresenter` + - existing `OperationRunLinks` +- **Delegated start/completion UX behaviors**: re-run verification and open last check run must reuse current queued/block/deduped/result messaging rather than inventing new start UX +- **Local surface-owned behavior that remains**: deciding when those existing actions are primary, secondary, or hidden based on the derived provider-readiness case +- **Queued DB-notification policy**: unchanged +- **Terminal notification path**: unchanged +- **Exception required?**: none + +## Provider Boundary / Platform Core Check *(mandatory)* + +- **Shared provider/platform boundary touched?**: yes +- **Boundary classification**: mixed; provider-owned signals feed a platform-owned readiness guidance layer +- **Seams affected**: consent status, verification status, provider capability groups, reason-code translation, operator vocabulary on shared surfaces +- **Neutral platform terms preserved or introduced**: provider connection, required permissions, verification, readiness, evidence refresh, operation proof +- **Provider-specific semantics retained and why**: provider-specific permission names and admin-consent destination remain available in details and action targets because the current provider-owned seams require them +- **Why this does not deepen provider coupling accidentally**: the spec forbids new Microsoft-shaped core taxonomies, persistence, or route semantics; provider-specific wording stays bounded to existing provider-owned detail. +- **Follow-up path**: deeper onboarding/provider health redesign stays a later follow-up candidate + +## UI / Surface Guardrail Impact *(mandatory)* + +| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note | +|---|---|---|---|---|---|---| +| Provider Connections list | yes | Native Filament resource | provider readiness, action hierarchy, dashboard continuity | table summary, derived state | no | Existing route only | +| Provider Connections view | yes | Native Filament resource/detail | provider readiness, proof links, safe actions | infolist/header actions, derived state | no | Existing route only | +| Provider Connections edit | yes | Native Filament resource/edit | action/proof continuity, grouped safe actions | header actions, existing form context | no | Existing route only; top guidance intentionally not duplicated | +| Environment Required Permissions | yes | Native Filament page + custom Blade summary | permission blocker guidance, copy flows, verification links | page summary, disclosure hierarchy | no | Existing route only | +| Dashboard target continuity | yes | Existing dashboard -> existing destinations | guidance contract reuse | link target continuity only | no | No new dashboard scope beyond continuity | + +## Decision-First Surface Role *(mandatory)* + +| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction | +|---|---|---|---|---|---|---|---| +| Provider Connections view | Primary Decision Surface | Decide whether this connection is ready and what safe next action resolves the blocker | readiness state, blocker reason, impact, one primary action | capability detail, raw diagnostics, last run proof | Primary because it is the authority surface for connection-level readiness | follows provider admin workflow | removes translation from badges/columns/actions | +| Provider Connections edit | Secondary Configuration Context | Adjust connection metadata or review existing action/proof context after the blocker is understood | existing record fields and safe action context | last run proof, grouped provider operations, diagnostics | Secondary because the first readiness decision is already handled on list/view | follows provider admin workflow | avoids duplicating another top-level guidance layer | +| Environment Required Permissions | Primary Decision Surface | Decide whether missing permissions, stale evidence, or verification follow-up is the blocker | one blocker summary, one primary action, missing type split | raw permission matrix, copy payloads, technical details | Primary because dashboard often lands here first | follows permission-remediation workflow | removes need to infer next step from counts alone | +| Provider Connections list | Secondary Context | Decide which connection needs inspection or whether the environment has any usable connection | top-level readiness summary and row signals | detail page, diagnostics, action group | Secondary because it routes to the real connection decision | supports workspace-wide scanning | keeps list scan-first | +| Environment Dashboard target continuity | Secondary Context | Confirm the dashboard CTA landed on the same blocker | matching title/reason/action | deeper proof after landing | Secondary because the dashboard remains the first-start surface | preserves operator continuity | avoids target-page disorientation | + +## Audience-Aware Disclosure *(mandatory)* + +| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention | +|---|---|---|---|---|---|---|---| +| Provider Connections | operator-MSP, workspace owner, support where authorized | readiness state, why blocked, impact, primary action | capability summary, consent/verification states, last error reason, last check | raw error message, detailed capability rows, operation proof | open required permissions, run verification, or open last check run depending on blocker | raw diagnostics remain secondary | guidance card states blocker once; lower sections add proof only | +| Environment Required Permissions | operator-MSP, workspace owner, support where authorized | missing app/delegated or stale verification blocker, why it matters, primary action | capability groups, counts, freshness, filtered highlights | raw permission matrix, copy payloads, technical details | admin consent, provider connections, or re-run verification | technical details stay collapsed by default | overview replaces the current repeated issue interpretation burden | + +## UI/UX Surface Classification *(mandatory)* + +| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| Provider Connections list | Utility / Workspace Decision | Strategic integration list | inspect the blocking connection or create one | row opens view page | allowed | grouped under existing page/header patterns | existing provider actions stay grouped | `/admin/provider-connections` | `/admin/provider-connections/{record}` | workspace context + optional `environment_id` | Provider connection | readiness blocker and scope summary | none | +| Provider Connections view | Detail / Configuration Authority | Provider readiness detail | resolve the dominant blocker | existing detail page | N/A | secondary proof/actions in header group | existing destructive/high-impact actions stay confirmed and grouped | `/admin/provider-connections` | existing view route | workspace + record ownership | Provider connection | one derived readiness case | none | +| Provider Connections edit | Configuration Surface | Provider connection maintenance | adjust or review connection configuration after readiness diagnosis | existing edit page | N/A | existing grouped proof/actions remain | existing destructive/high-impact actions stay confirmed and grouped | `/admin/provider-connections` | existing edit route | workspace + record ownership | Provider connection | existing action/proof context only; top guidance may be deferred | intentional non-duplication of first-screen guidance | +| Environment Required Permissions | List / Guidance / Diagnostic | Read-first remediation page | grant consent, open provider connection, or re-run verification | same page | forbidden | secondary links in guidance/issues/details | none added | `/admin/workspaces/{workspace}/environments/{environment}/required-permissions` | same page | workspace + environment route | Required permissions | one blocker and one next action | inline workflow exemption remains valid | + +## Summary + +Spec 352 made provider blockers the dominant first-screen case on the Environment Dashboard. Spec 353 makes the destination surfaces trustworthy by turning existing Provider Connections and Required Permissions truth into one explicit provider-readiness guidance layer. + +The feature remains narrow: + +- no new provider architecture +- no new permission model +- no onboarding rewrite +- no new mutation flow +- no live provider calls during render + +The product outcome is: + +- one dominant provider-readiness case +- one primary next action +- secondary proof links only when repo-backed +- technical detail on demand + +## Problem Statement + +Provider readiness is an upstream blocker for evidence refresh, review-output readiness, inventory visibility, and onboarding continuity. The repo already exposes consent status, verification status, missing-permission counts, capability-group impacts, and last-operation proof, but the affected destination surfaces still require operators to interpret those signals for themselves. + +After Spec 352, the Environment Dashboard can correctly prioritize provider blockers and send the operator to a target page. That target page must now preserve the same blocker story and present one safe next action immediately, otherwise the dashboard improvement terminates in a diagnostics-first dead end. + +## Primary Users And Operators + +- MSP operators managing multiple customer environments from the admin panel +- workspace owners or admins responsible for provider consent and verification follow-through +- internal support users with existing workspace/environment entitlement + +This slice does not target customer-portal or public-facing audiences. + +## Goals + +### G1 - Add provider-readiness guidance on Provider Connections + +Provider Connections list/detail must show a clear readiness case when the connection or its owning environment is blocked or needs follow-up. The edit surface may preserve action/proof continuity without duplicating first-screen guidance. + +### G2 - Add provider-readiness guidance on Required Permissions + +Required Permissions must explain which blocker matters, why it affects TenantPilot, and what to do next before the raw permission matrix. + +### G3 - Reuse existing repo-backed signals + +Use stored provider connection, missing-permission, capability-group, verification, and last-operation truth only. + +### G4 - Reuse the current guidance family only where it fits + +Provider readiness may reuse Spec 350-style `ResolutionCase` / `ResolutionAction` semantics or a bounded provider presenter, but it must not force a repo-wide provider framework. + +### G5 - Keep provider actions safe + +Only render repo-backed actions such as open required permissions, open provider connection, run verification, open last check run, or open onboarding/context destinations already supported by the repo. + +### G6 - Preserve domain ownership + +Do not rewrite onboarding ownership, permission calculation ownership, or provider execution ownership. + +## Non-Goals + +- rebuilding `ProviderConnectionResource` +- rewriting `ManagedEnvironmentRequiredPermissionsViewModelBuilder` +- changing provider APIs or Graph integration +- adding a new provider or provider registry layer +- adding a new OAuth or consent execution path +- adding auto-fix, auto-consent, or autonomous remediation +- adding a new dashboard framework +- changing OperationRun semantics +- adding new tables, enums, or persisted readiness states unless repo truth proves unavoidable +- turning Provider Connections into a Microsoft admin mirror + +## Current Repo Truth Summary + +- Provider Connections already exposes consent, verification, provider capability, last check, and diagnostics on list and detail surfaces. +- The view page already has one prominent `Grant admin consent` action; the edit page already has `View last check run` and existing provider operations. +- Required Permissions already derives: + - `overall` + - `counts` + - `feature_impacts` + - `capability_groups` + - `primary_capability_group` + - `freshness` +- Required Permissions already renders: + - summary counts + - guidance copy + - issue cards + - copy payload modals + - technical-details disclosure +- The Environment Dashboard already promotes `required_permissions` / `delegated_permissions` provider blockers into `operatorGuidance`. +- `ProviderReasonTranslator` and `VerificationLinkBehavior` remain adjacent repo seams for provider explanation/link behavior, but they are not required to be the primary runtime path for Spec 353 if a narrower adapter over stored truth is sufficient. + +## Provider Guidance Contract + +The implementation may realize this as a Spec 350-style derived case or as a bounded provider presenter, but the product contract is: + +```php +[ + 'key' => 'provider_readiness.required_permissions_missing', + 'title' => 'Provider readiness blocked', + 'status' => 'Blocked', + 'severity' => 'danger', + 'reason' => 'Required application permissions are missing.', + 'impact' => 'Evidence refresh and review output readiness may be incomplete.', + 'primary_action' => [ + 'label' => 'Open required permissions', + 'url' => '...', + 'enabled' => true, + ], + 'secondary_actions' => [ + ['label' => 'Run verification', 'url' => '...'], + ['label' => 'Open last check run', 'url' => '...'], + ], + 'details' => [ + 'missing_application_permissions' => 15, + 'missing_delegated_permissions' => 0, + 'verification_status' => 'unknown', + 'last_error_reason_code' => 'provider_consent_missing', + ], +] +``` + +Priority order must stay narrow and repo-backed: + +1. No provider connection +2. Connection disabled or unusable +3. Missing application permissions +4. Missing delegated permissions +5. Verification failed / blocked +6. Verification not run / stale / unknown +7. Provider ready + +Safe action set for v1: + +- Open required permissions +- Open provider connection +- Run verification +- Open last check run +- Open environment dashboard +- Open existing onboarding destination only if current repo truth makes it the best supporting path + +Unsupported for v1: + +- auto-consent +- auto-repair +- "make provider ready" mutation buttons +- live provider health polling during render + +## Functional Requirements + +- **FR-353-001**: Provider Connections must expose one dominant provider-readiness case on list/detail when follow-up is required. The edit surface may preserve existing proof/action continuity without duplicating the first-screen guidance layer. +- **FR-353-002**: Required Permissions must expose one dominant readiness case before the raw permission matrix. +- **FR-353-003**: Guidance must reuse stored provider connection, permission, capability-group, freshness, verification, and last-run truth only. +- **FR-353-004**: Guidance must distinguish at least these cases when repo-backed: no connection, disabled connection, missing application permissions, missing delegated permissions, verification blocked/failed, verification stale/unknown, ready. +- **FR-353-005**: Each surface must keep one visually dominant primary action. Secondary links must not compete. +- **FR-353-006**: Dashboard provider-blocker deep links must land on a target surface that shows the same blocker category clearly. +- **FR-353-007**: Raw permission rows, copy payloads, and provider diagnostics must remain secondary or collapsed by default. +- **FR-353-008**: Existing repo-backed actions such as `Grant admin consent`, `Run verification`, `View last check run`, and provider-connection navigation must be reused rather than replaced with unsupported buttons. +- **FR-353-009**: Existing provider/onboarding/verification behavior must remain intact; only the guidance layer changes. +- **FR-353-010**: Scope and authorization must remain workspace/environment safe with no cross-scope leakage. + +## Non-Functional Requirements + +- **NFR-353-001**: Calm enterprise UX. The default view must read as one blocker and one next action, not a wall of permission detail. +- **NFR-353-002**: Provider-neutral core copy on shared surfaces. Provider-specific terms may appear in details only where current seams already require them. +- **NFR-353-003**: Auditability and OperationRun reuse remain unchanged. Existing verification and provider operations keep current audit and run ownership. +- **NFR-353-004**: Capability-first RBAC. Guidance may demote or disable actions, but server-side authorization remains authoritative. +- **NFR-353-005**: Render path must stay DB-local. No live Graph/provider call is allowed during guidance rendering. +- **NFR-353-006**: No new provider framework, no new status persistence, and no new global-search behavior. + +## UX Requirements + +- The first visible state on the affected surfaces must answer: + - what is blocked + - why it matters to TenantPilot + - what the safest next action is +- Exactly one action may be visually primary per rendered provider-readiness case. +- Raw permission rows, copy payloads, diagnostic badges, and sanitized error details must remain secondary or collapsed by default. +- Ready states must read as calm and non-alarming, with secondary proof and navigation still available when useful. +- Dashboard-to-target continuity must preserve the blocker category so the operator does not feel they landed on an unrelated admin page. + +## RBAC / Security Requirements + +- Existing workspace membership and environment entitlement remain authoritative; deny-as-not-found behavior for out-of-scope users must not change. +- Existing provider capabilities such as `PROVIDER_VIEW`, `PROVIDER_MANAGE`, and `PROVIDER_RUN` continue to govern action availability. +- Guidance visibility must not widen authorization, route scope, or provider mutation reach. +- Unsupported remediation must not be rendered as executable UI. + +## Auditability / Observability Requirements + +- Existing `OperationRun` ownership for provider verification and proof links remains authoritative. +- Existing provider action logging and audit semantics must remain unchanged; Spec 353 only changes decision-first presentation. +- Guidance rendering must not introduce live provider calls, background work, or untracked side effects in the request path. + +## Data / Truth-Source Requirements + +- Provider-readiness guidance remains derived-only and request-scoped. +- Canonical inputs are existing stored truth from `ProviderConnection`, `ManagedEnvironmentRequiredPermissionsViewModelBuilder`, `ProviderConnectionResolver`, current link helpers, and existing `OperationRun` proof. +- `ProviderConnectionSurfaceSummary`, `ProviderReasonTranslator`, and `VerificationLinkBehavior` remain adjacent repo seams that may assist explanation or link behavior, but they are not required to be the primary runtime inputs for Spec 353. +- No new table, persisted snapshot, enum family, or provider taxonomy may be introduced unless later repo truth proves it unavoidable. + +## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)* + +- **Livewire version contract**: unchanged; current repo truth stays on Livewire v4.x. +- **Filament panel/provider registration**: unchanged; `apps/platform/bootstrap/providers.php` remains authoritative and is not part of this slice. +- **Global search**: unchanged; `ProviderConnectionResource` stays not globally searchable and no new searchable surface is introduced. +- **Test purpose / classification**: + - Unit for deterministic provider-guidance selection + - Feature/Livewire for Provider Connections and Required Permissions rendering/integration + - Browser for strategic target continuity and first-screen hierarchy +- **Validation lane(s)**: fast-feedback + confidence + browser +- **Why this lane mix is the narrowest sufficient proof**: the risk is decision hierarchy, continuity, and safe action truth on existing strategic surfaces rather than schema or remote execution behavior. +- **Planned proving commands**: + - `cd apps/platform && ./vendor/bin/sail artisan test tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php --compact` + - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php --compact` + - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php --compact` + - `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php --compact` +- **Planned regression filters**: + - `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ProviderConnection --exclude-group=browser` + - `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=RequiredPermissions` + - `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec352 --exclude-group=browser` + - `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ResolutionGuidance --exclude-group=browser` +- **Deployment/runtime impact expected**: none; no migrations, env vars, queues, scheduler entries, storage changes, or `filament:assets` registration are planned. + +## Acceptance Criteria + +- **AC1**: Provider Connections list/detail shows one dominant provider-readiness case when action is required, while edit preserves existing action/proof continuity without widening scope or faking remediation. +- **AC2**: Required Permissions is decision-first and explains the blocker before the raw permission matrix. +- **AC3**: Exactly one provider action is visually primary on the affected surfaces. +- **AC4**: Dashboard provider-blocker links land on a surface that shows a matching blocker clearly. +- **AC5**: No unsupported auto-fix, auto-consent, or fake remediation buttons are rendered. +- **AC6**: Guidance rendering does not call live provider APIs. +- **AC7**: Workspace/environment/provider scope remains correct. +- **AC8**: Existing provider actions, verification runs, required-permission calculation, and onboarding ownership are preserved. +- **AC9**: Focused unit/feature/browser tests cover missing permissions, verification follow-up, ready state, and dashboard continuity. +- **AC10**: UI audit artifacts and screenshots are updated under the Spec 353 package and the current UI audit registry. + +## Success Criteria + +- An operator can land from the Environment Dashboard onto a provider-readiness target and understand the blocker plus next safe action within one screen. +- Provider Connections and Required Permissions no longer require the operator to translate badge/count truth into their own remediation decision. +- No unsupported auto-fix or auto-consent action is introduced. +- Focused validation covers blocker ranking, rendered hierarchy, and dashboard continuity without requiring broader provider rewrites. + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Dashboard to provider target continuity (Priority: P1) + +As an operator, when the dashboard says provider readiness blocks work, the linked page should show the same blocker and the same safe next action. + +**Independent Test**: Seed a provider-blocked environment, open the dashboard, follow the primary provider CTA, and assert that the target surface shows a matching blocker category and one dominant action. + +### User Story 2 - Understand connection-level readiness (Priority: P1) + +As an operator on Provider Connections, I can tell whether a specific connection is blocked by missing consent, missing permissions, stale verification, or provider failure without reading raw diagnostics first. + +**Independent Test**: Feature/browser coverage proves that Provider Connections surfaces show one derived readiness case, one primary action, and secondary proof links only when repo-backed. + +### User Story 3 - Understand required-permissions impact (Priority: P1) + +As an operator on Required Permissions, I can tell whether application permissions, delegated permissions, or stale verification are blocking TenantPilot and what to do next before inspecting the full matrix. + +**Independent Test**: Feature/browser coverage proves that Required Permissions shows one blocker summary before the matrix and preserves raw permission rows as secondary detail. + +### User Story 4 - Calm ready state (Priority: P2) + +As an operator, when provider readiness is currently satisfied, the surfaces show a calm ready state and a non-alarming next step rather than another warning stack. + +**Independent Test**: Unit + feature/browser coverage proves the ready case yields no urgent blocker and keeps technical details secondary. + +## Risks + +- **Risk 1 - Duplicate onboarding ownership**: mitigate by keeping onboarding links secondary and not rewriting onboarding state or wizard logic. +- **Risk 2 - Permission details overwhelm the page**: mitigate by deriving one blocker case and keeping matrix/diagnostics behind secondary disclosure. +- **Risk 3 - Fake remediation**: mitigate by reusing only repo-backed actions and routing unsupported cases to navigation/proof instead of mutation. +- **Risk 4 - Render-time provider calls**: mitigate by limiting guidance inputs to stored connection, permission, capability, freshness, and last-run truth. +- **Risk 5 - Missing UI audit artifact for Required Permissions**: mitigate by explicitly creating `ui-077-required-permissions.md` during implementation instead of silently skipping audit coverage. + +## Follow-Up Candidates + +- accepted-risk / finding-exception resolution guidance follow-through +- broader provider/onboarding productization after this readiness slice is stable +- sellable smoke matrix after provider and governance operator flows are calmer +- customer-facing localization and copy-polish follow-through + +## Assumptions + +- The current stored provider, permission, and verification signals are sufficient to derive one dominant readiness case without new persistence. +- Existing admin-consent, required-permissions, verification-run, and last-operation links remain the authoritative safe actions for this slice. +- Creating `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` during implementation is consistent with the repo's current UI audit structure. + +## Open Questions + +No blocking preparation questions remain. + +Implementation should still confirm two narrow runtime choices during tests-first work: + +- whether dashboard-target continuity can remain route-native without any new query-state hint +- whether the current repo truth prefers surfacing stale verification ahead of delegated-permission follow-up when both are present on the same environment diff --git a/specs/353-provider-connections-resolution-guidance-v1/tasks.md b/specs/353-provider-connections-resolution-guidance-v1/tasks.md new file mode 100644 index 00000000..36644322 --- /dev/null +++ b/specs/353-provider-connections-resolution-guidance-v1/tasks.md @@ -0,0 +1,177 @@ +# Tasks: Spec 353 - Provider Connections Resolution Guidance v1 + +**Input**: `specs/353-provider-connections-resolution-guidance-v1/spec.md`, `plan.md`, `repo-truth-map.md`, `contracts/provider-readiness-signal-map.md`, and `checklists/requirements.md` + +**Tests**: Required. This spec changes strategic operator-facing readiness guidance on existing Provider Connections and Required Permissions surfaces. + +## Test Governance Checklist + +- [x] Lane assignment is explicit and narrow: Unit for guidance selection, Feature/Livewire for rendered integration, Browser for first-screen hierarchy and dashboard target continuity. +- [x] New or changed tests stay in the smallest honest family, and the browser addition is explicit. +- [x] Shared helpers, factories, seeds, and context defaults stay cheap by default. +- [x] Planned validation commands cover the slice without pulling in unrelated lane cost. +- [x] The changed surfaces are explicit strategic/detail surfaces, not a hidden infra-only refactor. +- [x] No new persisted readiness truth, provider framework, or enum family is planned. + +## Phase 1: Preparation And Repo Truth + +**Purpose**: Keep the implementation bounded to the existing runtime seams and recorded draft-to-repo deviations. + +- [x] T001 Re-read `spec.md`, `plan.md`, `tasks.md`, `repo-truth-map.md`, `contracts/provider-readiness-signal-map.md`, and `checklists/requirements.md`. +- [x] T002 Re-verify the current runtime truth in: + - `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php` + - `apps/platform/app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php` + - `apps/platform/app/Filament/Pages/EnvironmentRequiredPermissions.php` + - `apps/platform/resources/views/filament/pages/environment-required-permissions.blade.php` + - `apps/platform/app/Services/Intune/ManagedEnvironmentRequiredPermissionsViewModelBuilder.php` + - `apps/platform/app/Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php` + - `apps/platform/app/Support/EnvironmentDashboard/EnvironmentDashboardSummaryBuilder.php` + - `apps/platform/app/Support/Providers/ProviderReasonTranslator.php` + - `apps/platform/app/Support/Verification/VerificationLinkBehavior.php` +- [x] T003 Re-confirm the draft deviations recorded in `repo-truth-map.md`: + - no `EnvironmentProviderHealth.php` + - no existing `ui-077-required-permissions.md` + - Provider Connections already has primary/safe actions and detail truth + - Required Permissions already has summary/issues/details scaffolding +- [x] T004 Confirm no migration, package, env var, queue family, scheduler, storage, panel/provider, or global-search change is required; keep Livewire v4 and `apps/platform/bootstrap/providers.php` unchanged. +- [x] T005 Keep `repo-truth-map.md` and `contracts/provider-readiness-signal-map.md` current if runtime inspection proves a narrower or broader safe slice. + +## Phase 2: Tests First + +**Purpose**: Lock decision hierarchy, scope, and no-fake-action behavior before runtime changes. + +- [x] T006 Add `apps/platform/tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php`. +- [x] T007 Add unit assertions for `no provider connection`. +- [x] T008 Add unit assertions for `connection disabled or unusable`. +- [x] T009 Add unit assertions for `missing application permissions`. +- [x] T010 Add unit assertions for `missing delegated permissions`. +- [x] T011 Add unit assertions for `verification blocked or failed`. +- [x] T012 Add unit assertions for `verification stale / unknown / not yet trusted`. +- [x] T013 Add unit assertions for `provider ready / no urgent provider action`. +- [x] T014 Add a render-path guard assertion proving the derived guidance selection does not require live provider or Graph calls. +- [x] T015 Add `apps/platform/tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php`. +- [x] T016 Add feature assertions that Provider Connections surfaces show one explicit provider-readiness case with one dominant primary action. +- [x] T017 Add feature assertions that only repo-backed secondary actions are rendered and unsupported auto-fix buttons are absent. +- [x] T018 Add feature assertions that workspace/environment/record scope remains correct for all rendered guidance links. +- [x] T019 Add feature assertions that existing provider detail truth and action groups remain present as secondary context. +- [x] T020 Add `apps/platform/tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php`. +- [x] T021 Add feature assertions that Required Permissions renders the blocker guidance before the raw matrix. +- [x] T022 Add feature assertions that missing application, missing delegated, and stale/unknown cases map to distinct operator-facing guidance. +- [x] T023 Add feature assertions that copy payload flows and technical details remain secondary. +- [x] T024 Add feature assertions that no live provider call is required to render Required Permissions guidance. +- [x] T025 Add a dashboard target continuity assertion in the narrowest honest family (Feature if possible, Browser otherwise). +- [x] T026 Add `apps/platform/tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php`. +- [x] T027 Browser Flow A: permissions-missing state on Required Permissions; assert one dominant blocker and one primary action. +- [x] T028 Browser Flow B: provider connection verification-follow-up state; assert operation-proof or verification action continuity. +- [x] T029 Browser Flow C: ready state; assert calm posture and secondary details only. +- [x] T030 Browser Flow D: Environment Dashboard -> provider target continuity; assert matching blocker language and scope. +- [x] T031 Browser Flow E: technical details remain collapsed by default and layout stays readable on a mobile-ish width if fixture support exists. + +## Phase 3: Derived Guidance Contract + +**Purpose**: Build the narrowest derived readiness payload over existing provider and permission truth. + +- [x] T032 Choose the narrowest implementation shape: + - prefer one bounded provider-readiness adapter/presenter + - avoid broadening `ReviewPackOutputResolutionAdapter` into a provider meta-framework +- [x] T033 Consume existing signals from `ProviderConnectionResolver`, `ManagedEnvironmentRequiredPermissionsViewModelBuilder`, and the last `provider.connection.check` run proof, using `ProviderReasonTranslator` or `VerificationLinkBehavior` only where directly helpful rather than as mandatory primary inputs. +- [x] T034 Derive one provider guidance payload with: + - `key` + - `title` + - `status` + - `severity` + - `reason` + - `impact` + - `primary_action` + - `secondary_actions` + - `technical_details` +- [x] T035 Keep blocker priority explicit: no connection -> disabled/unusable -> missing application -> missing delegated -> verification failed/blocked -> stale/unknown -> ready. +- [x] T036 Keep the derived guidance DB-local and request-scoped only; no new persistence. +- [x] T037 Do not introduce a new provider enum/status family, provider registry, or generic workflow engine in this slice. + +## Phase 4: Provider Connections Integration + +**Purpose**: Make Provider Connections read as an operator guidance destination without removing current truth. + +- [x] T038 Integrate the derived guidance into Provider Connections list in a way that keeps the table scan-first and the environment filter intact. +- [x] T039 Integrate the derived guidance into Provider Connections view, and keep the edit surface aligned as action/proof continuity without forcing duplicate top guidance. +- [x] T040 Reuse existing repo-backed primary/secondary targets where appropriate: + - `Grant admin consent` + - `Run verification` + - `View last check run` + - `Open required permissions` + - `Open provider connection` +- [x] T041 Preserve current destructive/high-impact provider actions exactly as confirmation-, authorization-, and audit-protected secondary actions. +- [x] T042 Do not let guidance visibility widen action authorization or scope. + +## Phase 5: Required Permissions Integration + +**Purpose**: Make Required Permissions decision-first without losing the current diagnostic depth. + +- [x] T043 Add a top guidance case near the summary that explains why the current blocker matters to TenantPilot. +- [x] T044 Reuse the current capability-group and freshness truth before inventing any new provider state. +- [x] T045 Distinguish application permission blockers, delegated permission blockers, and stale/unknown verification follow-up in the top guidance layer. +- [x] T046 Keep copy payloads, feature-impact cards, and the native permission matrix as secondary detail. +- [x] T047 Keep technical details collapsed by default and avoid duplicating the blocker message in lower sections. + +## Phase 6: Dashboard Target Continuity + +**Purpose**: Ensure the dashboard's provider CTA lands on a destination that says the same thing clearly. + +- [x] T048 Reuse the existing dashboard provider blocker mapping from `EnvironmentDashboardSummaryBuilder` and adjust destination continuity only if required. +- [x] T049 Avoid adding a fragile new query-string contract when existing route scope is sufficient. +- [x] T050 Ensure the target page shows the same blocker category and a compatible next action as the dashboard guidance. + +## Phase 7: Copy, Audit, And Artifacts + +**Purpose**: Align user-facing wording and UI audit coverage with the new guidance hierarchy. + +- [x] T051 Update only the required copy in `apps/platform/lang/en/localization.php`. +- [x] T052 Update matching copy in `apps/platform/lang/de/localization.php`. +- [x] T053 Update `docs/ui-ux-enterprise-audit/page-reports/ui-009-provider-connections.md`. +- [x] T054 Create or update `docs/ui-ux-enterprise-audit/page-reports/ui-077-required-permissions.md` and align it with the final bounded route-inventory classification. +- [x] T055 Save screenshots under `specs/353-provider-connections-resolution-guidance-v1/artifacts/screenshots/`, or record the container-local Sail/Pest artifact blocker explicitly if host-visible copies cannot be persisted. +- [x] T056 Keep `repo-truth-map.md`, `contracts/provider-readiness-signal-map.md`, `docs/ui-ux-enterprise-audit/route-inventory.md`, and any conditional `design-coverage-matrix.md` / `strategic-surfaces.md` / `unresolved-pages.md` follow-through aligned with the final bounded implementation shape. + +## Phase 8: Validation + +**Purpose**: Prove the guidance remains bounded, scope-safe, and render-local. + +- [x] T057 Run `cd apps/platform && ./vendor/bin/sail artisan test tests/Unit/ResolutionGuidance/Spec353ProviderReadinessResolutionAdapterTest.php --compact`. +- [x] T058 Run `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/ProviderConnections/Spec353ProviderConnectionGuidanceTest.php --compact`. +- [x] T059 Run `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/Spec353RequiredPermissionsGuidanceTest.php --compact`. +- [x] T060 Run `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec353ProviderReadinessGuidanceSmokeTest.php --compact`. +- [x] T061 Re-run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ProviderConnection --exclude-group=browser`, and document any separate browser-harness instability honestly. +- [x] T062 Re-run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=RequiredPermissions`. +- [x] T063 Re-run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec352 --exclude-group=browser`. +- [x] T064 Re-run `cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ResolutionGuidance --exclude-group=browser`. +- [x] T065 Confirm final render paths remain DB-local and do not call `GraphClientInterface` or provider HTTP during page render. +- [x] T066 Run `cd apps/platform && ./vendor/bin/sail pint --dirty`. +- [x] T067 Run `git diff --check`. +- [x] T068 Report unrelated broader-suite or fixture issues honestly if they remain outside this slice. + +## Non-Goals Checklist + +- [x] NT001 Do not rewrite provider verification execution or provider-connection architecture. +- [x] NT002 Do not add a new permission model, provider status persistence, or onboarding wizard flow. +- [x] NT003 Do not add auto-consent, auto-repair, or fake "make provider ready" buttons. +- [x] NT004 Do not widen Provider Connections global search, panel setup, or routing architecture. +- [x] NT005 Do not introduce live provider calls during render. +- [x] NT006 Do not add customer portal, PDF/HTML renderer, PSA, billing, or AI follow-up work. + +## Required Final Report Content + +When implementation later completes, report: + +- changed provider-readiness behavior on Provider Connections and Required Permissions +- dominant-case selection model +- dashboard target continuity behavior +- safe action set and any disabled/fallback cases +- render-path result for no live provider calls +- UI audit artifact updates and screenshot paths +- files changed +- tests run and results +- explicit no migrations/packages/env/queues/scheduler/storage/panel/global-search change statement +- known gaps or deferred findings