TenantAtlas/specs/076-permissions-enterprise-ui/tasks.md
ahmido 05a604cfb6 Spec 076: Tenant Required Permissions (enterprise remediation UX) (#92)
Implements Spec 076 enterprise remediation UX for tenant required permissions.

Highlights
- Above-the-fold overview (impact + counts) with missing-first experience
- Feature-based grouping, filters/search, copy-to-clipboard for missing app/delegated permissions
- Tenant-scoped deny-as-not-found semantics; DB-only viewing
- Centralized badge semantics (no ad-hoc status mapping)

Testing
- Feature tests for default filters, grouping, copy output, and non-member 404 behavior.

Integration
- Adds deep links from verification checks to the Required permissions page.

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #92
2026-02-05 22:08:51 +00:00

221 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: "Task list for feature implementation"
---
# Tasks: 076-permissions-enterprise-ui
**Input**: Design documents from `specs/076-permissions-enterprise-ui/`
**Prerequisites**: `plan.md` (required), `spec.md` (required), `research.md`, `data-model.md`, `contracts/`, `quickstart.md`
**Tests**: REQUIRED (Pest) for all runtime behavior changes.
**RBAC (required)**:
- Non-member / not entitled to tenant scope → 404 (deny-as-not-found)
- Member but missing capability → 403
- Capabilities MUST come from `App\Support\Auth\Capabilities`
**Badges (required)**:
- Per-permission: `BadgeDomain::TenantPermissionStatus`
- Overview overall: `BadgeDomain::VerificationReportOverall`
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Ensure the repo is ready for implementation and tests.
- [x] T001 Validate local dev quickstart in specs/076-permissions-enterprise-ui/quickstart.md
- [x] T002 Confirm required permission definitions and feature tags exist in config/intune_permissions.php
- [x] T003 [P] Locate and document the clipboard fallback partial to reuse in resources/views/filament/partials/json-viewer.blade.php
- [x] T004 [P] Locate the verification report viewer/rendering surfaces in app/Filament/Support/VerificationReportViewer.php and resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Shared building blocks used by all user stories.
- [x] T005 Create view-model builder skeleton in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T006 [P] Add unit tests for overall status mapping in tests/Unit/TenantRequiredPermissionsOverallStatusTest.php
- [x] T007 [P] Add unit tests for copy payload semantics in tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php
- [x] T008 Add a small DTO/array-shape contract for permission rows in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T009 [P] Add unit tests for per-feature impact aggregation in tests/Unit/TenantRequiredPermissionsFeatureImpactTest.php
- [x] T010 Add a helper for Required Permissions deep links in app/Support/Links/RequiredPermissionsLinks.php
**Checkpoint**: Foundation ready (builder + core mapping tests).
---
## Phase 3: User Story 1 — Operator sees impact at a glance (Priority: P1) 🎯 MVP
**Goal**: A tenant-scoped Required Permissions page that clearly shows overall status, impacted features, and missing-first by default.
**Independent Test**: Visit `/admin/t/{tenant}/required-permissions` for a tenant with mixed coverage; verify overview status + impacted features + missing-first list.
- [x] T011 [US1] Create tenant Filament page class in app/Filament/Pages/TenantRequiredPermissions.php
- [x] T012 [US1] Create Blade view in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T013 [US1] Implement `canAccess()` (403 for members without capability) in app/Filament/Pages/TenantRequiredPermissions.php
- [x] T014 [US1] Wire builder into page mount/render using app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T015 [US1] Implement overall Ready/Needs attention/Blocked mapping using BadgeDomain::VerificationReportOverall in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T016 [US1] Render impacted-features summary cards (from permission feature tags) in resources/views/filament/pages/tenant-required-permissions.blade.php; cards are clickable to apply a Feature filter
- [x] T017 [US1] Render missing-first, missing-only default list in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T018 [US1] Render per-permission rows with centralized badge semantics (BadgeDomain::TenantPermissionStatus) in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T019 [P] [US1] Add feature test for page renders overview, missing-first, and feature cards include a click-to-filter wiring in tests/Feature/RequiredPermissions/RequiredPermissionsOverviewTest.php
### Verify-step clustering (in-scope per FR-076-011/011a)
- [x] T020 [US1] Define clustered check keys + grouping logic in app/Support/Verification/TenantPermissionCheckClusters.php
- [x] T021 [US1] Extend verification report writing to include clustered checks in app/Jobs/ProviderConnectionHealthCheckJob.php
- [x] T022 [US1] Ensure clustered checks include next-step URL to Required Permissions (use app/Support/Links/RequiredPermissionsLinks.php)
- [x] T023 [US1] Update onboarding wizard verify step to pass `verification_report` to view in app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
- [x] T024 [US1] Render clustered checks issues-first in resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php
- [x] T025 [P] [US1] Add feature test that renders clustered checks in onboarding verify report in tests/Feature/Onboarding/OnboardingVerificationClustersTest.php
- [x] T026 [P] [US1] Add unit tests for cluster status rules in tests/Unit/TenantPermissionCheckClustersTest.php
---
## Phase 4: User Story 2 — Global Admin can act quickly (Priority: P1)
**Goal**: Copy missing application vs delegated permissions separately, with clear guidance about admin consent.
**Independent Test**: From the Required Permissions page, click each copy action and verify output is newline-separated and respects Feature filter only.
- [x] T027 [US2] Add guidance block (“Who can fix this?” / “After granting consent”), including a primary next step link to an admin consent guide (prefer tenant Admin Consent URL; fall back to external guide) in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T028 [US2] Add “Re-run verification” entry point in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T029 [US2] Add “Copy missing application permissions” button + modal in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T030 [US2] Add “Copy missing delegated permissions” button + modal in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T031 [US2] Reuse clipboard fallback logic from resources/views/filament/partials/json-viewer.blade.php in the new copy modal
- [x] T032 [US2] Implement empty-copy UX (disabled action or explicit message) in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T033 [P] [US2] Add unit tests for copy respects Feature filter but ignores Search in tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php
- [x] T034 [P] [US2] Add feature test for presence of copy actions + guidance (including admin consent guide link) in tests/Feature/RequiredPermissions/RequiredPermissionsCopyActionsTest.php
---
## Phase 5: User Story 4 — Unauthorized users see nothing (Priority: P1)
**Goal**: Enforce deny-as-not-found for non-members and forbidden for members lacking `tenant.view`.
**Independent Test**: Request the page as a non-member (404), then as a member without capability (403).
- [x] T035 [US4] Ensure page does not register navigation by default and is not exposed via tenant-agnostic surfaces (e.g., global search / non-tenant nav) in app/Filament/Pages/TenantRequiredPermissions.php
- [x] T036 [P] [US4] Add feature test: non-member tenant access is 404 in tests/Feature/RequiredPermissions/RequiredPermissionsRbacTest.php
- [x] T037 [P] [US4] Add feature test: member without tenant.view gets 403 in tests/Feature/RequiredPermissions/RequiredPermissionsRbacTest.php
- [x] T038 [US4] Ensure capability checks reference registry constants (no raw strings) in app/Filament/Pages/TenantRequiredPermissions.php
- [x] T039 [US4] Ensure any deep links used by verification report do not leak cross-tenant data in app/Support/Links/RequiredPermissionsLinks.php
- [x] T040 [P] [US4] Add regression test for link generation staying tenant-scoped in tests/Unit/RequiredPermissionsLinksTest.php
---
## Phase 6: User Story 3 — Deep dive and triage remains possible (Priority: P2)
**Goal**: Filter/search the full matrix by Status/Type/Feature and search by permission key/description.
**Independent Test**: Apply filters and search; verify results update predictably and missing-first remains stable.
- [x] T041 [US3] Add Status filter (Missing/Present/All) state handling in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T042 [US3] Add Type filter (Application/Delegated/All) state handling in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T043 [US3] Add Feature multi-select filter support in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [x] T044 [US3] Add substring search (by permission key/description) applied at render time (not affecting copy) in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T045 [US3] Add UI controls for filters/search in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T046 [P] [US3] Add unit tests for filter/search behavior in tests/Unit/TenantRequiredPermissionsFilteringTest.php
- [x] T047 [P] [US3] Add feature test for filters narrowing results in tests/Feature/RequiredPermissions/RequiredPermissionsFiltersTest.php
- [x] T048 [US3] Ensure copy payload ignores Search but respects Feature filter (assert in builder) in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
---
## Phase 7: Polish & Cross-Cutting Concerns
- [x] T049 Run Pint formatting for touched files via vendor/bin/sail bin pint (see specs/076-permissions-enterprise-ui/quickstart.md)
- [x] T050 Run targeted Pest tests via vendor/bin/sail artisan test --compact (see specs/076-permissions-enterprise-ui/quickstart.md)
- [x] T051 [P] Ensure table empty states are meaningful (zero required / zero missing) in resources/views/filament/pages/tenant-required-permissions.blade.php
- [x] T052 [P] Ensure the Verify-step check list does not exceed 7 items and remains issues-first in resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php
- [x] T053 [P] Add regression feature test: Required Permissions page render remains DB-only (no Graph client calls) in tests/Feature/RequiredPermissions/RequiredPermissionsDbOnlyRenderTest.php
---
## Phase 8: Enterprise Correctness — Observed Refresh in Verification Run
**Goal**: Prevent false “missing permissions” findings by refreshing Observed permissions inventory during the queued verification run (Operation Run), while keeping all viewer surfaces DB-only.
- [x] T054 Update live-check failure semantics in app/Services/Intune/TenantPermissionService.php (do not overwrite stored inventory; return live-check metadata)
- [x] T055 Refresh observed permissions in app/Jobs/ProviderConnectionHealthCheckJob.php during successful provider checks (`liveCheck=true`, `persist=true`) and pass inventory freshness context into clustered checks
- [x] T055a Use ProviderConnection graph options for permission refresh (avoid falling back to Tenant/global Graph config)
- [x] T056 Degrade permission clusters to warnings when inventory refresh fails in app/Support/Verification/TenantPermissionCheckClusters.php
- [x] T057 Tighten verification report evidence safety via allowlisting in app/Support/Verification/VerificationReportSanitizer.php
- [x] T058 Add/adjust Pest tests covering: permission refresh invoked on healthy run, throttling/network refresh failure becomes warning (not missing), and no Graph calls are introduced into viewer renders
- [x] T059 Treat successful-but-unmappable Graph permission inventory as non-fresh (warn) and add regression coverage (reason_code: permission_mapping_failed)
- [x] T060 Degrade to warnings when live refresh returns empty inventory; surface app_id + observed count in verification report evidence
---
## Phase 9: Onboarding Wizard — Inline “Edit selected connection” (Option 1)
**Goal**: Edit the selected Provider Connection inline inside the onboarding wizard (SlideOver/Modal), without tenant-context navigation, while enforcing capability-first RBAC and requiring an explicit verification re-run after edits.
- [x] T061 Replace tenant-scoped edit link with an inline SlideOver edit action in app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
- [x] T062 Enforce RBAC: action disabled without capability, server-side 403 for missing capability, 404 for non-member/other-tenant scope
- [x] T063 After save: invalidate verification/bootstrap state and set a “connection updated” flag so Verify step shows “Re-run verification” guidance
- [x] T064 Add audit event `provider_connection.updated` with redacted metadata (no secrets)
- [x] T065 Add Pest feature tests covering RBAC, wizard continuity, no tenant-context dependency/links, secret safety, and audit entry
- [x] T066 Run Pint + targeted Pest tests for the new behavior
---
## Phase 10: Onboarding Wizard — Verify “Technical details” SlideOver
**Goal**: In the Verify step, provide a "Technical details" SlideOver with compact Operation Run summary and a "Refresh results" action, without showing an empty "Report unavailable" card in the SlideOver.
- [x] T067 Add Verify-step "Technical details" SlideOver showing run summary (run id/status/outcome, started/updated/completed, operation type + Entra tenant scope) and optional "Open full page" link
- [x] T068 Add/adjust Pest feature test to ensure the Verify step renders the "Technical details" affordance when a verification run exists
---
## Dependencies & Execution Order
### User Story completion order
- Setup → Foundational → US1 → (US2, US4 in parallel) → US3 → Polish
### Dependency graph
- US1 depends on Foundational (view-model builder + mappings)
- US2 depends on US1 (copy actions live on the page)
- US4 depends on US1 (route exists to assert 404/403)
- US3 depends on US1 (matrix exists to filter)
## Parallel execution examples
### US1
- In parallel:
- T011 (Page class) and T012 (Blade view)
- T019 (feature test file scaffolding) can start once route is known
### US2
- In parallel:
- T029/T030 (two copy buttons/modals) can be developed independently
- T033 unit tests can be written while UI is built
### US4
- In parallel:
- T036/T037 RBAC tests can be authored alongside US1 once page route exists
### US3
- In parallel:
- T041T043 builder filter support can be built while T045 UI controls are built
- T046 unit tests can be written alongside implementation
## Implementation Strategy
### MVP scope (recommended)
- Complete Phase 1 + Phase 2 + Phase 3 (US1) first.
- Validate independently via tests and by loading the tenant page.
### Incremental delivery
- Add copy + guidance (US2), then RBAC regression coverage (US4), then filters/search (US3).