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

216 lines
16 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.

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