# Implementation Plan: 076-permissions-enterprise-ui **Branch**: `076-permissions-enterprise-ui` | **Date**: 2026-02-05 **Spec**: specs/076-permissions-enterprise-ui/spec.md **Input**: specs/076-permissions-enterprise-ui/spec.md ## Summary Implement the “Tenant Required Permissions (Enterprise Remediation UX)” plus the Verify-step clustering: - Tenant-scoped Filament Page for required permissions with an overview section + details matrix. - Copy-to-clipboard for missing permissions split by type (application vs delegated), with clarified semantics. - Verification report updates to emit 5–7 clustered checks and onboarding Verify step rendering updates (issues-first), deep-linking to the Required Permissions page. ## Technical Context **Language/Version**: PHP 8.4.15 (Laravel 12) **Primary Dependencies**: Filament v5 + Livewire v4.0+ **Storage**: PostgreSQL (Sail) **Testing**: Pest v4 **Target Platform**: Filament admin panel with tenancy routing (`/admin/t/{tenant}/...`) **Project Type**: Laravel monolith **Performance Goals**: DB-only render; in-memory filtering on config-sized datasets (<~200 rows) **Constraints**: - Required Permissions page is DB-only at render (no Graph/HTTP). - Tenant isolation / RBAC-UX: - non-member tenant access is 404 via existing middleware - member without `Capabilities::TENANT_VIEW` is 403 - Badge semantics (BADGE-001): use centralized `BadgeDomain` mappings only. - Copy semantics: respects Feature filter only; ignores Search; always copies Missing only; Type fixed by clicked button. - Enterprise correctness: verification runs refresh Observed permissions inventory (Graph) and persist it; viewer surfaces remain DB-only. ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Read/write separation: PASS (page is read-only; copy is client-side) - Graph contract path: PASS (no Graph calls on render) - RBAC-UX: PASS (404 for non-members; 403 for missing capability) - Badge semantics: PASS (explicit badge domains are fixed in spec) ## Project Structure ### Documentation (this feature) - specs/076-permissions-enterprise-ui/spec.md - specs/076-permissions-enterprise-ui/plan.md (this file) - specs/076-permissions-enterprise-ui/research.md - specs/076-permissions-enterprise-ui/data-model.md - specs/076-permissions-enterprise-ui/contracts/* - specs/076-permissions-enterprise-ui/quickstart.md - specs/076-permissions-enterprise-ui/tasks.md (generated next via speckit) ### Code (planned) - app/Filament/Pages/TenantRequiredPermissions.php (new) - resources/views/filament/pages/tenant-required-permissions.blade.php (new) - app/Jobs/ProviderConnectionHealthCheckJob.php (extend verification report) - app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php (render check clusters) - resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php (render checks) - tests/Feature/* (Pest) ## Phase 0 — Outline & Research (COMPLETE) Output: specs/076-permissions-enterprise-ui/research.md Key decisions: - Dedicated tenant-scoped Filament Page for Required Permissions. - Use DB-only permission status (`tenant_permissions`) + `config/intune_permissions.php` for required definitions. - Implement copy actions via existing robust clipboard fallback pattern. - Compute clustered verification checks when writing the verification report (job/service), not in Blade. - Refresh Observed permission inventory during the verification run (Operation Run), not in any viewer surface. ## Phase 1 — Design & Contracts (COMPLETE) Outputs: - specs/076-permissions-enterprise-ui/data-model.md - specs/076-permissions-enterprise-ui/contracts/required-permissions.view-model.json - specs/076-permissions-enterprise-ui/contracts/verification-report.checks.md - specs/076-permissions-enterprise-ui/quickstart.md Remaining required step in this phase: - Run `.specify/scripts/bash/update-agent-context.sh copilot`. ## Phase 2 — Implementation Planning (READY) ### 2.1 Tenant Required Permissions Page - Route/tenancy: create tenant page at slug `required-permissions` (under `/admin/t/{tenant}/required-permissions`). - Authorization: - non-member 404 is enforced by existing tenancy middleware - add `canAccess()` check for `Capabilities::TENANT_VIEW` (403) - Data: - required definitions: `config/intune_permissions.php` - tenant status: `tenant_permissions` via `TenantPermissionService` with DB-only semantics - Overview: - overall status mapping: Blocked if any missing application; Needs attention if only delegated missing; Ready if none missing - impacted features summary (from permission → features tags), with clickable cards that apply a Feature filter - primary next step: Admin consent guide link (prefer existing tenant-specific Admin Consent URL; fall back to external guide) - Details matrix: - missing-first sorting - filters: Feature, Type, Status - search across key/description - Badges: - per-row uses `BadgeDomain::TenantPermissionStatus` - overview uses `BadgeDomain::VerificationReportOverall` - Copy actions: - copy missing application - copy missing delegated - selection respects Feature filter only; ignores Search; always Missing-only ### 2.2 Verification Check Clustering - Extend verification report writing to include 5–7 clustered checks derived from required permissions status. - Follow specs/076-permissions-enterprise-ui/contracts/verification-report.checks.md for keys + status rules. - Ensure permission clusters only assert “missing” when Observed inventory refresh succeeded during the run; otherwise degrade to warnings with retry guidance. ### 2.3 Verify Step UI - Update onboarding Verify step to render check clusters from `verification_report` (via `VerificationReportViewer`). - Issues-first ordering: failures, then warnings, then passes. - Provide an explicit “Open Required Permissions” next-step link. ### 2.4 Tests (Pest) - Access: - member without `tenant.view` gets 403 - non-member tenant access remains 404 - Copy semantics: - Feature filter affects payload; Search does not - type-specific copy returns only missing of that type - Verification report: - cluster keys present - cluster status mapping matches missing application vs delegated rules