# Tasks: Tenant Backup Health Signals **Input**: Design documents from `/specs/180-tenant-backup-health/` **Prerequisites**: `plan.md` (required), `spec.md` (required for user stories), `research.md`, `data-model.md`, `contracts/`, `quickstart.md` **Tests**: Tests are REQUIRED for this feature. Use focused Pest coverage in `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php`, `tests/Feature/Filament/DashboardKpisWidgetTest.php`, `tests/Feature/Filament/NeedsAttentionWidgetTest.php`, `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php`, `tests/Feature/Filament/TenantDashboardTenantScopeTest.php`, `tests/Feature/Filament/TenantDashboardDbOnlyTest.php`, `tests/Feature/Filament/BackupSetListContinuityTest.php`, `tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php`, and `tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php`. **Operations**: No new `OperationRun`, queue, or scheduled execution flow is introduced. Work stays limited to read-time tenant dashboard truth and existing backup or schedule follow-up surfaces. **RBAC**: Existing workspace membership, tenant entitlement, capability-registry usage, and `404` vs `403` semantics must remain unchanged across `/admin/t/{tenant}`, `/admin/t/{tenant}/backup-sets`, and `/admin/t/{tenant}/backup-schedules`. Tests must cover both positive and negative access paths plus safe degradation when an action target is unavailable. **Operator Surfaces**: The tenant dashboard must expose backup posture in the primary summary zone, `NeedsAttention` must show reason-specific backup follow-up, and backup-set or schedule destinations must make the clicked reason recognizable without forcing the operator into raw diagnostics first. **Filament UI Action Surfaces**: `DashboardKpis` and `NeedsAttention` remain summary-only surfaces with one primary reason-driven destination; `BackupSetResource` and `BackupScheduleResource` keep their current inspect models, row-click behavior, and destructive placement unchanged. **Filament UI UX-001**: No new create or edit flow is introduced. The work is limited to summary-first truth on the existing dashboard and list or detail surfaces. **Badges**: Reuse existing shared badge or tone primitives if backup-health tone mapping is needed; do not add page-local semantic mappings in widgets or resources. **Organization**: Tasks are grouped by user story so each story can be implemented and validated as an independent increment after the shared backup-health scaffolding is in place. ## Phase 1: Setup (Shared Backup-Health Scaffolding) **Purpose**: Add the narrow derived backup-health types and configuration used by every story. - [X] T001 Create the shared backup-health value objects in `app/Support/BackupHealth/TenantBackupHealthAssessment.php`, `app/Support/BackupHealth/BackupFreshnessEvaluation.php`, `app/Support/BackupHealth/BackupScheduleFollowUpEvaluation.php`, `app/Support/BackupHealth/BackupHealthActionTarget.php`, and `app/Support/BackupHealth/BackupHealthDashboardSignal.php` - [X] T002 Create the central backup-health resolver skeleton in `app/Support/BackupHealth/TenantBackupHealthResolver.php` - [X] T003 [P] Add unit test scaffolding for the new backup-health namespace in `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php` - [X] T004 [P] Add explicit backup-health freshness and schedule grace configuration in `config/tenantpilot.php` --- ## Phase 2: Foundational (Blocking Shared Wiring) **Purpose**: Wire the shared derivation contract before any story-specific dashboard or continuity behavior lands. **⚠️ CRITICAL**: No user story work should begin until this phase is complete. - [X] T005 Implement query-bounded latest-basis selection, `BackupQualityResolver`-backed degradation reuse, posture precedence, schedule-follow-up derivation, and reason target selection in `app/Support/BackupHealth/TenantBackupHealthResolver.php` - [X] T006 [P] Extend core resolver coverage for absent, stale, degraded, healthy, stale-over-degraded precedence, mixed-history latest-governs, `BackupQualityResolver`-backed degradation reuse, and schedule-follow-up behavior in `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php` - [X] T007 Add shared backup-health loading helpers and dashboard-signal adapters for dashboard widgets in `app/Filament/Widgets/Dashboard/DashboardKpis.php` and `app/Filament/Widgets/Dashboard/NeedsAttention.php` - [X] T008 [P] Extend DB-only and query-bounded tenant dashboard guard coverage for backup-health rendering in `tests/Feature/Filament/TenantDashboardDbOnlyTest.php` **Checkpoint**: The repository has one authoritative derived backup-health contract that dashboard and follow-up surfaces can consume without new persistence. --- ## Phase 3: User Story 1 - See Backup Posture Immediately (Priority: P1) 🎯 MVP **Goal**: Show absent, stale, degraded, or healthy backup posture on the tenant dashboard's primary summary surface. **Independent Test**: Seed one tenant each for no usable backup basis, stale latest backup, degraded latest backup, and fresh healthy backup, then verify the tenant dashboard renders the correct primary backup-health posture without opening deeper pages. ### Tests for User Story 1 - [X] T009 [P] [US1] Extend primary backup-health posture coverage in `tests/Feature/Filament/DashboardKpisWidgetTest.php` - [X] T010 [P] [US1] Extend tenant dashboard calmness-versus-caution coverage for backup-health summary states in `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php` ### Implementation for User Story 1 - [X] T011 [US1] Render the primary backup-health stat or card with posture, last relevant backup timing, and bounded summary copy in `app/Filament/Widgets/Dashboard/DashboardKpis.php` - [X] T012 [US1] Keep summary wording aligned to `absent`, `stale`, `degraded`, and `healthy` semantics in `app/Support/BackupHealth/TenantBackupHealthAssessment.php` and `app/Filament/Widgets/Dashboard/DashboardKpis.php` - [X] T013 [US1] Run the focused dashboard posture verification pack from `specs/180-tenant-backup-health/quickstart.md` against `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php`, `tests/Feature/Filament/DashboardKpisWidgetTest.php`, `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php`, and `tests/Feature/Filament/TenantDashboardDbOnlyTest.php` **Checkpoint**: The tenant dashboard now answers the backup-health question within seconds on a primary summary surface. --- ## Phase 4: User Story 2 - Click The Warning And Recover The Same Reason (Priority: P1) **Goal**: Make dashboard backup warnings and attention items open destination surfaces that confirm the same problem family. **Independent Test**: Trigger stale, degraded, no-basis, and schedule-follow-up scenarios, click the dashboard KPI or attention destination, and verify the target surface immediately confirms the same reason. ### Tests for User Story 2 - [X] T014 [P] [US2] Extend reason-driven dashboard action coverage in `tests/Feature/Filament/DashboardKpisWidgetTest.php` and `tests/Feature/Filament/NeedsAttentionWidgetTest.php` - [X] T015 [P] [US2] Create or extend no-basis, stale, degraded, and schedule-follow-up continuity coverage in `tests/Feature/Filament/BackupSetListContinuityTest.php`, `tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php`, and `tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php` ### Implementation for User Story 2 - [X] T016 [US2] Add backup-health attention items with safe action-target rendering in `app/Filament/Widgets/Dashboard/NeedsAttention.php` - [X] T017 [US2] Route backup-health KPI and attention destinations by reason in `app/Support/BackupHealth/TenantBackupHealthResolver.php` and `app/Support/BackupHealth/BackupHealthActionTarget.php` - [X] T018 [US2] Make no-basis list continuity and stale or degraded latest-basis continuity scan-fast on the backup-set surfaces in `app/Filament/Resources/BackupSetResource.php` - [X] T019 [US2] Make schedule-follow-up continuity scan-fast on the backup-schedules surface in `app/Filament/Resources/BackupScheduleResource.php` - [X] T020 [US2] Run the focused drillthrough continuity pack from `specs/180-tenant-backup-health/quickstart.md` against `tests/Feature/Filament/DashboardKpisWidgetTest.php`, `tests/Feature/Filament/NeedsAttentionWidgetTest.php`, `tests/Feature/Filament/BackupSetListContinuityTest.php`, `tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php`, and `tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php` **Checkpoint**: Backup-health warnings on the tenant dashboard now lead to destinations that confirm the same problem class without guesswork. --- ## Phase 5: User Story 3 - Trust Positive Backup Calmness Only When Earned (Priority: P2) **Goal**: Allow positive backup-health wording only when the latest relevant backup basis genuinely supports it. **Independent Test**: Render the tenant dashboard for one clearly healthy case and several almost-healthy cases, then verify that only the fully supported case emits positive backup-health wording. ### Tests for User Story 3 - [X] T021 [P] [US3] Extend healthy-check inclusion and suppression coverage in `tests/Feature/Filament/NeedsAttentionWidgetTest.php` - [X] T022 [P] [US3] Extend healthy-claim gating coverage in `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php` and `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php` ### Implementation for User Story 3 - [X] T023 [US3] Enforce healthy-claim gating and supporting-message rules in `app/Support/BackupHealth/TenantBackupHealthResolver.php` and `app/Support/BackupHealth/TenantBackupHealthAssessment.php` - [X] T024 [US3] Render `Backups are recent and healthy` only when the assessment permits it in `app/Filament/Widgets/Dashboard/NeedsAttention.php` - [X] T025 [US3] Keep positive dashboard copy bounded to backup posture rather than recoverability in `app/Filament/Widgets/Dashboard/DashboardKpis.php` and `app/Filament/Widgets/Dashboard/NeedsAttention.php` - [X] T026 [US3] Run the focused healthy-wording pack from `specs/180-tenant-backup-health/quickstart.md` against `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php`, `tests/Feature/Filament/NeedsAttentionWidgetTest.php`, and `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php` **Checkpoint**: Positive backup calmness now appears only when the current evidence earns it. --- ## Phase 6: User Story 4 - Preserve Truth Under Schedule And Permission Nuance (Priority: P3) **Goal**: Keep tenant backup-health truth strong under mixed history, schedule nuance, and restricted downstream access. **Independent Test**: Seed mixed-history, overdue-schedule, and reduced-destination-access scenarios, then verify the dashboard still surfaces the strongest truthful backup-health state and degrades navigation safely. ### Tests for User Story 4 - [X] T027 [P] [US4] Extend tenant-scope `404` coverage plus established-member blocked-destination `403` coverage in `tests/Feature/Filament/TenantDashboardTenantScopeTest.php` - [X] T028 [P] [US4] Extend mixed-history latest-governs and schedule-secondary coverage in `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php` and `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php` - [X] T029 [P] [US4] Extend disabled-action, member-without-capability, and schedule-follow-up nuance coverage in `tests/Feature/Filament/NeedsAttentionWidgetTest.php` ### Implementation for User Story 4 - [X] T030 [US4] Finalize schedule-follow-up secondary semantics and latest-history precedence in `app/Support/BackupHealth/TenantBackupHealthResolver.php` - [X] T031 [US4] Degrade unavailable backup drillthroughs safely while preserving summary truth in `app/Filament/Widgets/Dashboard/DashboardKpis.php` and `app/Filament/Widgets/Dashboard/NeedsAttention.php` - [X] T032 [US4] Keep backup follow-up routes and record resolution tenant-scoped, capability-registry-backed, and `403`-after-membership authorization-safe in `app/Filament/Resources/BackupSetResource.php` and `app/Filament/Resources/BackupScheduleResource.php` - [X] T033 [US4] Run the focused nuance and RBAC pack from `specs/180-tenant-backup-health/quickstart.md` against `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php`, `tests/Feature/Filament/NeedsAttentionWidgetTest.php`, `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php`, and `tests/Feature/Filament/TenantDashboardTenantScopeTest.php` **Checkpoint**: Backup-health truth remains accurate even when schedules exist, history is mixed, or one downstream destination is unavailable. --- ## Phase 7: Polish & Cross-Cutting Concerns **Purpose**: Final consistency, formatting, and focused verification across all stories. - [X] T034 [P] Review and align operator-facing backup-health copy in `app/Support/BackupHealth/TenantBackupHealthAssessment.php`, `app/Filament/Widgets/Dashboard/DashboardKpis.php`, `app/Filament/Widgets/Dashboard/NeedsAttention.php`, `app/Filament/Resources/BackupSetResource.php`, and `app/Filament/Resources/BackupScheduleResource.php` - [X] T035 [P] Run the focused verification pack from `specs/180-tenant-backup-health/quickstart.md` against `tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php`, `tests/Feature/Filament/DashboardKpisWidgetTest.php`, `tests/Feature/Filament/NeedsAttentionWidgetTest.php`, `tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php`, `tests/Feature/Filament/TenantDashboardTenantScopeTest.php`, `tests/Feature/Filament/TenantDashboardDbOnlyTest.php`, `tests/Feature/Filament/BackupSetListContinuityTest.php`, `tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php`, and `tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php` - [X] T036 Run formatting with `vendor/bin/sail bin pint --dirty --format agent` as required by `specs/180-tenant-backup-health/quickstart.md` - [ ] T037 Run the manual validation pass in `specs/180-tenant-backup-health/quickstart.md` for no-backup, stale, stale-over-degraded, degraded, healthy, schedule-follow-up, and tenant-scope scenarios --- ## Dependencies & Execution Order ### Phase Dependencies - **Setup (Phase 1)**: Starts immediately and establishes the new backup-health namespace and config. - **Foundational (Phase 2)**: Depends on Setup and blocks all story work until one authoritative backup-health derivation contract exists. - **User Story 1 (Phase 3)**: Starts after Foundational and delivers the first operator-visible backup-health truth. - **User Story 2 (Phase 4)**: Starts after Foundational and should follow User Story 1 closely because it adds reason continuity to the summary surfaces. - **User Story 3 (Phase 5)**: Starts after Foundational and can proceed once the primary posture contract from User Story 1 is in place. - **User Story 4 (Phase 6)**: Starts after Foundational and should follow User Stories 2 and 3 because it hardens action degradation and final nuance on top of those surfaces. - **Polish (Phase 7)**: Starts after the desired stories are complete. ### User Story Dependencies - **US1**: Depends only on Setup and Foundational work. - **US2**: Depends on Setup and Foundational work and should reuse the posture contract delivered for US1. - **US3**: Depends on Setup and Foundational work and should reuse the posture contract delivered for US1. - **US4**: Depends on Setup and Foundational work plus the action-target and healthy-claim behavior hardened in US2 and US3. ### Within Each User Story - Test updates should land before the corresponding behavior change is considered complete. - Resolver and value-object changes should land before widget or resource rendering tasks for the same story. - Story-level focused test runs should pass before moving to the next priority slice. ### Parallel Opportunities - `T003` and `T004` can run in parallel after the backup-health namespace from `T001` is agreed. - `T006` and `T008` can run in parallel once `T005` defines the derivation contract. - `T009` and `T010` can run in parallel for US1. - `T014` and `T015` can run in parallel for US2. - `T018` and `T019` can run in parallel for US2 once `T017` fixes the reason-target contract. - `T021` and `T022` can run in parallel for US3. - `T027`, `T028`, and `T029` can run in parallel for US4. - `T034` and `T035` can run in parallel once feature code is stable. --- ## Parallel Example: User Story 1 ```bash # Story 1 tests in parallel: Task: T009 tests/Feature/Filament/DashboardKpisWidgetTest.php Task: T010 tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php # Story 1 implementation split after the resolver contract is stable: Task: T011 app/Filament/Widgets/Dashboard/DashboardKpis.php Task: T012 app/Support/BackupHealth/TenantBackupHealthAssessment.php ``` ## Parallel Example: User Story 2 ```bash # Story 2 tests in parallel: Task: T014 tests/Feature/Filament/DashboardKpisWidgetTest.php Task: T015 tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php # Story 2 follow-up surfaces in parallel after reason-target mapping is fixed: Task: T018 app/Filament/Resources/BackupSetResource.php Task: T019 app/Filament/Resources/BackupScheduleResource.php ``` ## Parallel Example: User Story 3 ```bash # Story 3 tests in parallel: Task: T021 tests/Feature/Filament/NeedsAttentionWidgetTest.php Task: T022 tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php # Story 3 implementation split after gating rules are defined: Task: T023 app/Support/BackupHealth/TenantBackupHealthResolver.php Task: T024 app/Filament/Widgets/Dashboard/NeedsAttention.php ``` ## Parallel Example: User Story 4 ```bash # Story 4 tests in parallel: Task: T027 tests/Feature/Filament/TenantDashboardTenantScopeTest.php Task: T028 tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php Task: T029 tests/Feature/Filament/NeedsAttentionWidgetTest.php # Story 4 hardening split after expectations are locked: Task: T031 app/Filament/Widgets/Dashboard/DashboardKpis.php Task: T032 app/Filament/Resources/BackupSetResource.php ``` --- ## Implementation Strategy ### MVP First - Complete Phase 1 and Phase 2. - Deliver User Story 1 first so the tenant dashboard stops hiding backup posture at the summary layer. - If the slice is intended to ship immediately after MVP, include User Story 2 before release so dashboard warnings also preserve drillthrough trust. ### Incremental Delivery - Add User Story 2 next to make every warning recoverable on the correct destination surface. - Add User Story 3 after that to prevent positive calm wording from overclaiming health. - Add User Story 4 last to harden mixed-history, schedule nuance, and RBAC-safe degradation. ### Verification Finish - Run Pint on touched files. - Run the focused backup-health pack from `quickstart.md`. - Run the manual quickstart validation pass for absent, stale, degraded, healthy, schedule-follow-up, and tenant-scope cases. - Offer the broader suite only after the focused pack passes.