TenantAtlas/specs/122-empty-state-consistency/tasks.md
ahmido 73a3a62451 Spec 122: Empty state consistency pass (#148)
## Summary
- unify empty-state UX across the six in-scope Filament list pages
- move empty-state ownership toward resource `table()` definitions while preserving existing RBAC behavior
- add focused Pest coverage for empty-state rendering, CTA outcomes, populated-state regression behavior, and action-surface compliance
- add the Spec 122 planning artifacts and product discovery documents used for this pass

## Changed surfaces
- `PolicyResource`
- `BackupSetResource`
- `RestoreRunResource`
- `BackupScheduleResource`
- `WorkspaceResource`
- `AlertDeliveryResource`

## Tests
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/EmptyStateConsistencyTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/CreateCtaPlacementTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/PolicySyncStartSurfaceTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/BackupScheduling/BackupScheduleLifecycleAuthorizationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/BackupSetUiEnforcementTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/RestoreRunUiEnforcementTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php`
- `vendor/bin/sail bin pint --dirty --format agent`

## Notes
- Filament v5 / Livewire v4.0+ compliance is preserved.
- Panel provider registration remains unchanged in `bootstrap/providers.php`.
- No new globally searchable resources were added.
- Destructive actions were not introduced by this pass.
- Alert Deliveries is documented as the explicit no-header-action exemption for the empty-state CTA relocation rule.
- Manual light/dark visual QA evidence is still expected in the PR/review artifact set for the remaining checklist items (`T018`, `T025`).

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #148
2026-03-08 02:17:51 +00:00

16 KiB
Raw Blame History

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.

  • 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
  • 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
  • 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.

  • 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
  • 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.

  • 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
  • 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

  • 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
  • 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
  • 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
  • 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
  • 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
  • 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 ⚠️

  • 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
  • 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

  • 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
  • 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 resources existing enforcement pattern, and server-side authorization semantics are unchanged.

Tests for User Story 3 ⚠️

  • 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
  • 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

  • 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
  • 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.

  • 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
  • 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

# 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

# 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

# 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.