# Tasks: Empty State Consistency Pass **Input**: Design documents from `/specs/122-empty-state-consistency/` **Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/empty-states.openapi.yaml, quickstart.md **Tests**: Tests are REQUIRED for this runtime behavior change. Use Pest feature and Livewire tests via Sail. **Operations**: No new `OperationRun` work is required for this feature; existing policy sync operation behavior must remain unchanged. **RBAC**: No authorization model changes are planned; tasks must preserve existing tenant/workspace membership isolation plus current resource-specific capability behavior for empty-state CTAs. **Filament UI Action Surfaces**: Tasks must keep each changed list surface compliant with the Action Surface Contract and update `AlertDeliveryResource` so `ListEmptyState` is satisfied instead of exempted. **Filament UI UX-001**: Tasks must ensure every changed empty state has a specific title, concise explanation, and exactly one CTA, with the CTA relocating to the header when records exist for create-capable surfaces. Alert Deliveries is the documented no-header-action exemption. **Organization**: Tasks are grouped by user story so each story remains independently testable. ## Phase 1: Setup (Shared Context) **Purpose**: Align implementation with the approved empty-state contract and current codebase patterns before editing runtime code. - [X] T001 [P] Review the approved contract and copy in specs/122-empty-state-consistency/spec.md, specs/122-empty-state-consistency/research.md, and specs/122-empty-state-consistency/contracts/empty-states.openapi.yaml - [X] T002 [P] Inspect canonical resource-level empty-state patterns in app/Filament/Resources/BaselineProfileResource.php, app/Filament/Resources/ReviewPackResource.php, app/Filament/Resources/AlertDestinationResource.php, and app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php - [X] T003 [P] Review current in-scope list implementations and helper ownership in app/Filament/Resources/PolicyResource.php, app/Filament/Resources/BackupSetResource.php, app/Filament/Resources/RestoreRunResource.php, app/Filament/Resources/BackupScheduleResource.php, app/Filament/Resources/Workspaces/WorkspaceResource.php, and app/Filament/Resources/AlertDeliveryResource.php --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Prepare the shared test and contract guard surfaces that all user stories depend on. **⚠️ CRITICAL**: No user story work should begin until this phase is complete. - [X] T004 Extend shared CTA placement and populated-state regression coverage in tests/Feature/Filament/CreateCtaPlacementTest.php so header-vs-empty-state relocation remains a stable baseline for the in-scope create surfaces - [X] T005 Confirm current action-surface guard expectations in tests/Feature/Guards/ActionSurfaceContractTest.php and the existing `AlertDeliveryResource` exemption in app/Filament/Resources/AlertDeliveryResource.php before changing declarations **Checkpoint**: Shared placement and contract guard baselines are understood and user-story implementation can begin. --- ## Phase 3: User Story 1 - First-run clarity on empty lists (Priority: P1) 🎯 MVP **Goal**: Give first-time admins a complete, contextual empty state on every in-scope list page. **Independent Test**: With zero records on each in-scope list page, the page renders an icon, heading, description, and one primary CTA without changing the underlying workflow destination. ### Tests for User Story 1 ⚠️ > **NOTE**: Add or update these tests first and ensure they fail before implementation. - [X] T006 [P] [US1] Create empty-state rendering and CTA outcome coverage for policies, backup sets, restore runs, backup schedules, and workspaces in tests/Feature/Filament/EmptyStateConsistencyTest.php - [X] T007 [P] [US1] Extend alert delivery list coverage for empty-state rendering, CTA destination behavior, and the documented no-header-action exemption in tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php ### Implementation for User Story 1 - [X] T008 [P] [US1] Define the full policies empty state in app/Filament/Resources/PolicyResource.php and reduce helper-only CTA ownership in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php - [X] T009 [P] [US1] Define the full backup sets empty state in app/Filament/Resources/BackupSetResource.php and reduce helper-only CTA ownership in app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php - [X] T010 [P] [US1] Define the full restore runs empty state in app/Filament/Resources/RestoreRunResource.php and reduce helper-only CTA ownership in app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php - [X] T011 [P] [US1] Define the full backup schedules empty state in app/Filament/Resources/BackupScheduleResource.php and reduce helper-only CTA ownership in app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php - [X] T012 [P] [US1] Define the full workspaces empty state in app/Filament/Resources/Workspaces/WorkspaceResource.php and reduce helper-only CTA ownership in app/Filament/Resources/Workspaces/Pages/ListWorkspaces.php - [X] T013 [US1] Define the read-only alert deliveries empty state, replace the current empty-state exemption, and preserve the documented no-header-action exemption in app/Filament/Resources/AlertDeliveryResource.php **Checkpoint**: User Story 1 should now render complete empty states across all six in-scope list pages and remain independently testable. --- ## Phase 4: User Story 2 - Enterprise-grade consistency during evaluation (Priority: P2) **Goal**: Make the six empty states feel like one intentional product system rather than six scaffolds. **Independent Test**: Compare all six in-scope empty states and verify that copy hierarchy, icon presence, single-CTA structure, and header relocation behavior are consistent. ### Tests for User Story 2 ⚠️ - [X] T014 [P] [US2] Extend tests/Feature/Filament/CreateCtaPlacementTest.php to assert the in-scope create surfaces still expose exactly one empty-state CTA, relocate it to the header when populated, and preserve populated-table behavior after the resource-level refactor - [X] T015 [P] [US2] Extend tests/Feature/Guards/ActionSurfaceContractTest.php to assert the changed surfaces still satisfy `ListEmptyState`, including `AlertDeliveryResource`, while honoring the documented Alert Deliveries header-action exemption ### Implementation for User Story 2 - [X] T016 [US2] Normalize heading, description, icon, and CTA labels across app/Filament/Resources/PolicyResource.php, app/Filament/Resources/BackupSetResource.php, app/Filament/Resources/RestoreRunResource.php, app/Filament/Resources/BackupScheduleResource.php, app/Filament/Resources/Workspaces/WorkspaceResource.php, and app/Filament/Resources/AlertDeliveryResource.php against the Spec 122 contract - [X] T017 [US2] Reconcile any remaining split ownership between resource tables and list-page helpers in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php, app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php, app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php, app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php, and app/Filament/Resources/Workspaces/Pages/ListWorkspaces.php - [ ] T018 [US2] Perform a light/dark visual QA pass for the six in-scope list pages using the review flow described in specs/122-empty-state-consistency/quickstart.md and attach the evidence to the PR/review artifact set **Checkpoint**: User Story 2 should now demonstrate a deliberate, consistent empty-state system across all in-scope resources. --- ## Phase 5: User Story 3 - Permission-aware guidance (Priority: P3) **Goal**: Preserve current RBAC behavior so members still get the right disabled/hidden guidance and non-members still get deny-as-not-found behavior. **Independent Test**: With role-appropriate fixtures, empty-state CTAs remain disabled or hidden according to each resource’s existing enforcement pattern, and server-side authorization semantics are unchanged. ### Tests for User Story 3 ⚠️ - [X] T019 [P] [US3] Extend disabled-action coverage for policy sync and backup schedule create behavior in tests/Feature/PolicySyncStartSurfaceTest.php and tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php - [X] T020 [P] [US3] Extend empty-state permission coverage in tests/Feature/Filament/BackupSetUiEnforcementTest.php, tests/Feature/Filament/RestoreRunUiEnforcementTest.php, and tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php ### Implementation for User Story 3 - [X] T021 [US3] Preserve existing capability-aware CTA behavior in app/Filament/Resources/PolicyResource.php, app/Filament/Resources/BackupSetResource.php, app/Filament/Resources/RestoreRunResource.php, app/Filament/Resources/BackupScheduleResource.php, app/Filament/Resources/Workspaces/WorkspaceResource.php, and app/Filament/Resources/AlertDeliveryResource.php while moving empty-state ownership into resource tables - [X] T022 [US3] Preserve disabled CTA helper text or tooltip messaging for member-without-capability cases in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php, app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php, app/Filament/Resources/Workspaces/Pages/ListWorkspaces.php, and any corresponding resource-level empty-state CTA definitions that surface disabled actions **Checkpoint**: User Story 3 should now preserve existing authorization semantics while still guiding members who lack permissions. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Final verification, formatting, and review readiness across all stories. - [X] T023 Run focused Pest coverage with `vendor/bin/sail artisan test --compact` for tests/Feature/Filament/EmptyStateConsistencyTest.php, tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php, tests/Feature/Filament/CreateCtaPlacementTest.php, tests/Feature/PolicySyncStartSurfaceTest.php, tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php, tests/Feature/Filament/BackupSetUiEnforcementTest.php, tests/Feature/Filament/RestoreRunUiEnforcementTest.php, and tests/Feature/Guards/ActionSurfaceContractTest.php to verify CTA outcomes, populated-state regressions, and action-surface compliance - [X] T024 Run `vendor/bin/sail bin pint --dirty --format agent` - [ ] T025 Validate the implementation against specs/122-empty-state-consistency/quickstart.md and confirm PR/review evidence includes light/dark screenshots plus populated-table smoke verification for all affected resources --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: No dependencies; can start immediately. - **Foundational (Phase 2)**: Depends on Setup completion; blocks all user stories. - **User Story 1 (Phase 3)**: Depends on Foundational completion; this is the MVP. - **User Story 2 (Phase 4)**: Depends on User Story 1 because consistency normalization assumes the new empty-state content exists. - **User Story 3 (Phase 5)**: Depends on User Story 1 and can run in parallel with User Story 2 once the new empty-state surfaces exist. - **Polish (Phase 6)**: Depends on completion of the desired user stories. ### User Story Dependencies - **US1**: No dependency on other stories; delivers the main feature value. - **US2**: Depends on US1 surfaces being in place so consistency can be normalized and guarded. - **US3**: Depends on US1 surfaces being in place so permission behavior can be verified on the final empty-state implementation. ### Within Each User Story - Tests should be added or updated first and observed failing before implementation. - Resource `table()` ownership should be established before any helper cleanup. - Alert Deliveries declaration changes should land with its UI change so guard coverage stays consistent. - Story-specific verification should complete before moving to the next priority. ### Parallel Opportunities - T001, T002, and T003 can run in parallel. - T006 and T007 can run in parallel. - T008 through T012 can run in parallel because they touch different resource/page pairs. - T014 and T015 can run in parallel. - T019 and T020 can run in parallel. - After US1 implementation begins, US2 and US3 test authoring can be prepared in parallel by different contributors. --- ## Parallel Example: User Story 1 ```bash # Launch the independent resource retrofits together: Task: "Define the full policies empty state in app/Filament/Resources/PolicyResource.php and reduce helper-only CTA ownership in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php" Task: "Define the full backup sets empty state in app/Filament/Resources/BackupSetResource.php and reduce helper-only CTA ownership in app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php" Task: "Define the full restore runs empty state in app/Filament/Resources/RestoreRunResource.php and reduce helper-only CTA ownership in app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php" Task: "Define the full backup schedules empty state in app/Filament/Resources/BackupScheduleResource.php and reduce helper-only CTA ownership in app/Filament/Resources/BackupScheduleResource/Pages/ListBackupSchedules.php" Task: "Define the full workspaces empty state in app/Filament/Resources/Workspaces/WorkspaceResource.php and reduce helper-only CTA ownership in app/Filament/Resources/Workspaces/Pages/ListWorkspaces.php" ``` --- ## Parallel Example: User Story 2 ```bash # Launch consistency guard updates together: Task: "Extend tests/Feature/Filament/CreateCtaPlacementTest.php to assert the in-scope create surfaces still expose exactly one empty-state CTA, relocate it to the header when populated, and preserve populated-table behavior" Task: "Extend tests/Feature/Guards/ActionSurfaceContractTest.php to assert the changed surfaces still satisfy ListEmptyState, including AlertDeliveryResource" ``` --- ## Parallel Example: User Story 3 ```bash # Launch permission-regression updates together: Task: "Extend disabled-action coverage for policy sync and backup schedule create behavior in tests/Feature/PolicySyncStartSurfaceTest.php and tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php" Task: "Extend empty-state permission coverage in tests/Feature/Filament/BackupSetUiEnforcementTest.php, tests/Feature/Filament/RestoreRunUiEnforcementTest.php, and tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php" ``` --- ## Implementation Strategy ### MVP First (User Story 1 Only) 1. Complete Phase 1: Setup 2. Complete Phase 2: Foundational 3. Complete Phase 3: User Story 1 4. Validate the six empty states render correctly with one CTA each 5. Stop and review before broader consistency and RBAC refinement if needed ### Incremental Delivery 1. Ship the core empty-state retrofit across all six surfaces in US1 2. Normalize consistency and guard coverage in US2 3. Harden permission-aware behavior regressions in US3 4. Finish with focused Sail tests, Pint, and review evidence ### Parallel Team Strategy With multiple contributors: 1. One contributor updates the tenant resource empty states (`Policy`, `BackupSet`, `RestoreRun`) 2. One contributor updates the remaining workspace/monitoring surfaces (`BackupSchedule`, `Workspace`, `AlertDelivery`) 3. One contributor extends guard and placement tests 4. Recombine for authorization regression tests, formatting, and review evidence --- ## Notes - [P] tasks touch different files and can be executed in parallel. - User story labels map each task to the corresponding story in spec.md. - No migrations, new routes, or dependency changes are expected. - Manual visual QA evidence belongs in PR/review artifacts, not in committed files.