TenantAtlas/specs/066-rbac-ui-enforcement-helper/tasks.md
2026-01-30 17:49:05 +01:00

15 KiB
Raw Blame History

description
Task list for RBAC UI Enforcement Helper v2

Tasks: RBAC UI Enforcement Helper v2 (Suite-wide, Mixed Visibility, Record-Scoped)

Input: Design documents from /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/
Prerequisites: /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/plan.md (required), /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/spec.md (required), /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/research.md, /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/data-model.md, /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/contracts/, /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/quickstart.md

Tests: REQUIRED (Pest) for runtime behavior changes
RBAC: Tenant plane only (/admin/t/{tenant}); non-member is deny-as-not-found (404); member without capability is disabled + tooltip and cannot execute; destructive actions require confirmation
Organization: Tasks are grouped by user story (US1US4) to enable independent delivery.

Phase 1: Setup (Shared Infrastructure)

Purpose: Prepare local environment + validate baseline

  • T001 Start containers with ./vendor/bin/sail up -d (script: ./vendor/bin/sail)
  • T002 Run baseline guard suite with ./vendor/bin/sail artisan test tests/Feature/Guards --compact (folder: tests/Feature/Guards)
  • T003 Run baseline tenant RBAC suite with ./vendor/bin/sail artisan test tests/Feature/Rbac --compact (folder: tests/Feature/Rbac)

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Shared helper + guardrails required by all story migrations

Checkpoint: UiEnforcement supports mixed visibility, record-scoped tenant resolution, and bulk preflight; guard exists and is allowlist-driven

  • T004 Create UiTooltips with the v2 default disabled tooltip copy in app/Support/Auth/UiTooltips.php
  • T005 Create/verify v1 baseline UiEnforcement helper in app/Support/Auth/UiEnforcement.php (apply hidden/disabled/tooltip + server-side guard using Capabilities::*)
  • T006 [P] Add mixed visibility APIs (preserveVisibility() tenant-scoped only, andVisibleWhen(), andHiddenWhen()) in app/Support/Auth/UiEnforcement.php
  • T007 [P] Add tenant resolver APIs (tenantFromFilament(), tenantFromRecord(), tenantFrom(callable)) in app/Support/Auth/UiEnforcement.php
  • T008 [P] Add bulk preflight APIs (preflightSelection(), preflightByTenantMembership(), preflightByCapability()) with authorization-only all-or-nothing default in app/Support/Auth/UiEnforcement.php
  • T009 [P] Add helper unit tests (mixed visibility restriction + tenant resolvers + preflight decisions) in tests/Unit/Auth/UiEnforcementTest.php
  • T010 [P] Add query-count regression test for bulk preflight (no N+1 membership lookups) in tests/Unit/Auth/UiEnforcementBulkPreflightQueryCountTest.php
  • T011 Add CI-failing allowlist-driven guard for ad-hoc Filament auth patterns in tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php
  • T012 Run the new guard test with ./vendor/bin/sail artisan test tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php --compact (test: tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php)

Phase 3: User Story 1 — Mixed Visibility (Backup/Restore) (Priority: P1) 🎯 MVP

Goal: Backup/Restore actions preserve business visibility while enforcing RBAC UX (hidden/disabled + standard tooltip) via UiEnforcement

Independent Test: A non-member cannot access tenant routes (404); a member without capability sees actions disabled with the standard tooltip and cannot execute; a member with capability can execute (with confirmation for destructive actions)

Tests for User Story 1

  • T013 [P] [US1] Add BackupSet RBAC UX integration tests (include Http::preventStrayRequests()) in tests/Feature/Filament/BackupSetUiEnforcementTest.php
  • T014 [P] [US1] Add RestoreRun RBAC UX integration tests (include Http::preventStrayRequests()) in tests/Feature/Filament/RestoreRunUiEnforcementTest.php

Implementation for User Story 1

  • T015 [US1] Migrate mixed-visibility actions + bulk actions to UiEnforcement in app/Filament/Resources/BackupSetResource.php
  • T016 [US1] Migrate relation manager actions (incl. standardized tooltip copy via UiTooltips) in app/Filament/Resources/BackupSetResource/RelationManagers/BackupItemsRelationManager.php
  • T017 [US1] Migrate mixed-visibility actions + bulk actions to UiEnforcement in app/Filament/Resources/RestoreRunResource.php
  • T018 [US1] Replace Gate/abort_* access checks with UiEnforcement (tenant-scoped: non-member 404, member without cap 403) in app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php
  • T019 [US1] Remove allowlist entries for migrated Backup/Restore files in tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php
  • T020 [US1] Run story tests with ./vendor/bin/sail artisan test tests/Feature/Filament/BackupSetUiEnforcementTest.php tests/Feature/Filament/RestoreRunUiEnforcementTest.php --compact (tests: tests/Feature/Filament/BackupSetUiEnforcementTest.php)

Phase 4: User Story 2 — Record-Scoped Tenant (TenantResource actions) (Priority: P1)

Goal: Tenant list row actions are enforced per-tenant record (record-scoped tenancy) with non-member deny-as-not-found (404) and standardized member disabled UX

Independent Test: A user sees only tenants they are a member of; direct access to another tenant record denies 404; row actions for permitted tenants are disabled/enabled per capability with standard tooltip

Tests for User Story 2

  • T021 [P] [US2] Extend tenant row action tests to assert disabled + tooltip + no-exec (include Http::preventStrayRequests()) in tests/Feature/Filament/TenantActionsAuthorizationTest.php
  • T022 [P] [US2] Add record-scoped non-member 404 tests for tenant view/edit routes in tests/Feature/Filament/TenantPortfolioContextSwitchTest.php

Implementation for User Story 2

  • T023 [US2] Migrate TenantResource row actions to UiEnforcement using tenantFromRecord() (remove ad-hoc Gate/abort_*) in app/Filament/Resources/TenantResource.php
  • T024 [US2] Migrate record-scoped edit-page destructive actions to UiEnforcement (remove ad-hoc Gate/abort_*) in app/Filament/Resources/TenantResource/Pages/EditTenant.php
  • T025 [US2] Remove allowlist entries for migrated TenantResource files in tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php
  • T026 [US2] Run story tests with ./vendor/bin/sail artisan test tests/Feature/Filament/TenantActionsAuthorizationTest.php tests/Feature/Filament/TenantPortfolioContextSwitchTest.php --compact (tests: tests/Feature/Filament/TenantActionsAuthorizationTest.php)

Phase 5: User Story 3 — Bulk Preflight (All-or-Nothing Authorization) (Priority: P2)

Goal: Bulk actions disable deterministically when selection contains any unauthorized record; no partial execution

Independent Test: Selecting tenants with mixed authorization disables the bulk action; selecting only authorized tenants executes; business-ineligible records may be skipped with clear feedback

Tests for User Story 3

  • T027 [P] [US3] Update bulk sync tests to assert all-or-nothing authorization disable (include Http::preventStrayRequests()) in tests/Feature/Filament/TenantPortfolioContextSwitchTest.php

Implementation for User Story 3

  • T028 [US3] Add authorization-only bulk preflight for syncSelected (disable when any selected tenant lacks Capabilities::TENANT_SYNC) in app/Filament/Resources/TenantResource.php
  • T029 [US3] Ensure bulk action feedback cleanly separates authorization vs eligibility (skip inactive with notification; do not partially execute unauthorized) in app/Filament/Resources/TenantResource.php
  • T030 [US3] Run story tests with ./vendor/bin/sail artisan test tests/Feature/Filament/TenantPortfolioContextSwitchTest.php --compact (test: tests/Feature/Filament/TenantPortfolioContextSwitchTest.php)

Phase 6: User Story 4 — Guard Allowlist Shrink + Tier 2 Migrations (Priority: P2)

Goal: CI fails for new ad-hoc auth patterns in app/Filament/**; allowlist count shrinks measurably by migrating remaining targets

Independent Test: Guard fails if a new forbidden pattern is introduced; allowlist removes entries as files are migrated; each migrated Tier 2 surface has a focused RBAC UX test

Tests for User Story 4

  • T031 [P] [US4] Extend inventory resource RBAC UX tests (include Http::preventStrayRequests()) in tests/Feature/Filament/InventoryItemResourceTest.php and tests/Feature/Filament/InventorySyncRunResourceTest.php
  • T032 [P] [US4] Extend Entra group runs RBAC UX tests (include Http::preventStrayRequests()) in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php
  • T033 [P] [US4] Add provider connections RBAC UX tests for mixed visibility (include Http::preventStrayRequests()) in tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php

Implementation for User Story 4

  • T034 [US4] Migrate inventory resources away from ad-hoc Gate/abort_* to UiEnforcement in app/Filament/Resources/InventoryItemResource.php, app/Filament/Resources/InventoryItemResource/Pages/ListInventoryItems.php, and app/Filament/Resources/InventorySyncRunResource.php
  • T035 [US4] Migrate Entra group list/run start surfaces away from ad-hoc Gate/abort_* to UiEnforcement in app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php and app/Filament/Resources/EntraGroupSyncRunResource/Pages/ListEntraGroupSyncRuns.php
  • T036 [US4] Migrate provider connection mixed-visibility actions away from ad-hoc Gate/abort_* to UiEnforcement in app/Filament/Resources/ProviderConnectionResource.php, app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php, and app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php
  • T037 [US4] Remove allowlist entries for migrated Tier 2 files and note the allowlist count reduction in tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php
  • T038 [US4] Run story tests with ./vendor/bin/sail artisan test tests/Feature/Filament/InventoryItemResourceTest.php tests/Feature/Filament/InventorySyncRunResourceTest.php tests/Feature/Filament/EntraGroupSyncRunResourceTest.php tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php --compact (tests: tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php)
  • T039 [US4] Run guard suite with ./vendor/bin/sail artisan test tests/Feature/Guards --compact (folder: tests/Feature/Guards)

Phase 7: Polish & Cross-Cutting Concerns

Purpose: Reduce regressions and ensure suite-wide consistency

  • T040 [P] Ensure all destructive actions touched in v2 include ->requiresConfirmation() in app/Filament/Resources/BackupSetResource.php, app/Filament/Resources/RestoreRunResource.php, and app/Filament/Resources/TenantResource/Pages/EditTenant.php
  • T041 Run formatting with ./vendor/bin/sail bin pint --dirty (script: ./vendor/bin/pint)
  • T042 Run focused test suites with ./vendor/bin/sail artisan test tests/Unit/Auth tests/Feature/Filament tests/Feature/Guards tests/Feature/Rbac --compact (folders: tests/Feature/Filament)

Dependencies & Execution Order

User Story Dependency Graph

Phase 1 (Setup)
  ↓
Phase 2 (Foundation: UiEnforcement v2 + guard baseline)
  ↓
US1 (Backup/Restore mixed visibility) ─┬─→ US4 (Tier 2 migrations + allowlist shrink)
                                      ├─→ US2 (TenantResource record-scoped actions)
                                      └─→ US3 (Bulk preflight all-or-nothing)

Parallel Opportunities

  • Phase 2 tasks marked [P] can run in parallel (different files).
  • Within US1, BackupSet and RestoreRun migrations can be done in parallel (different resources) if coordinated to avoid conflicting changes in app/Support/Auth/UiEnforcement.php.
  • Within US4, Inventory vs EntraGroup vs ProviderConnection migrations can be parallelized (different files), but coordinate allowlist edits in tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php.

Parallel Example: User Story 1

Task: "Add BackupSet RBAC UX integration tests in tests/Feature/Filament/BackupSetUiEnforcementTest.php"
Task: "Add RestoreRun RBAC UX integration tests in tests/Feature/Filament/RestoreRunUiEnforcementTest.php"
Task: "Migrate BackupSet mixed-visibility actions to UiEnforcement in app/Filament/Resources/BackupSetResource.php"
Task: "Migrate RestoreRun mixed-visibility actions to UiEnforcement in app/Filament/Resources/RestoreRunResource.php"

Parallel Example: User Story 2

Task: "Extend tenant row action tests to assert disabled + tooltip + no-exec in tests/Feature/Filament/TenantActionsAuthorizationTest.php"
Task: "Add record-scoped non-member 404 tests for tenant view/edit routes in tests/Feature/Filament/TenantPortfolioContextSwitchTest.php"
Task: "Migrate TenantResource row actions to UiEnforcement using tenantFromRecord() in app/Filament/Resources/TenantResource.php"
Task: "Migrate record-scoped edit-page destructive actions to UiEnforcement in app/Filament/Resources/TenantResource/Pages/EditTenant.php"

Parallel Example: User Story 3

Task: "Update bulk sync tests to assert all-or-nothing authorization disable in tests/Feature/Filament/TenantPortfolioContextSwitchTest.php"
Task: "Add authorization-only bulk preflight for syncSelected in app/Filament/Resources/TenantResource.php"

Parallel Example: User Story 4

Task: "Extend inventory resource RBAC UX tests in tests/Feature/Filament/InventoryItemResourceTest.php"
Task: "Extend Entra group runs RBAC UX tests in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php"
Task: "Add provider connections RBAC UX tests for mixed visibility in tests/Feature/Filament/ProviderConnectionsUiEnforcementTest.php"
Task: "Migrate Entra group run list surfaces to UiEnforcement in app/Filament/Resources/EntraGroupSyncRunResource.php"
Task: "Migrate provider connection pages/actions to UiEnforcement in app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php"

Implementation Strategy

MVP First (User Story 1)

  1. Complete Phase 1 + Phase 2
  2. Complete US1 (BackupSet + RestoreRun mixed visibility enforcement)
  3. Validate with tests/Feature/Filament/BackupSetUiEnforcementTest.php and tests/Feature/Filament/RestoreRunUiEnforcementTest.php

Incremental Delivery

  1. US1 → migrate highest-risk backup/restore surfaces + tests + allowlist reduction
  2. US2 → record-scoped tenant actions enforced per row + 404 non-member on direct access
  3. US3 → bulk preflight all-or-nothing authorization
  4. US4 → Tier 2 migrations + measurable allowlist shrink + guard stability