19 KiB
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.
- 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, andapp/Support/BackupHealth/BackupHealthDashboardSignal.php - T002 Create the central backup-health resolver skeleton in
app/Support/BackupHealth/TenantBackupHealthResolver.php - T003 [P] Add unit test scaffolding for the new backup-health namespace in
tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php - 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.
- T005 Implement query-bounded latest-basis selection,
BackupQualityResolver-backed degradation reuse, posture precedence, schedule-follow-up derivation, and reason target selection inapp/Support/BackupHealth/TenantBackupHealthResolver.php - 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 intests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php - T007 Add shared backup-health loading helpers and dashboard-signal adapters for dashboard widgets in
app/Filament/Widgets/Dashboard/DashboardKpis.phpandapp/Filament/Widgets/Dashboard/NeedsAttention.php - 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
- T009 [P] [US1] Extend primary backup-health posture coverage in
tests/Feature/Filament/DashboardKpisWidgetTest.php - 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
- 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 - T012 [US1] Keep summary wording aligned to
absent,stale,degraded, andhealthysemantics inapp/Support/BackupHealth/TenantBackupHealthAssessment.phpandapp/Filament/Widgets/Dashboard/DashboardKpis.php - T013 [US1] Run the focused dashboard posture verification pack from
specs/180-tenant-backup-health/quickstart.mdagainsttests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php,tests/Feature/Filament/DashboardKpisWidgetTest.php,tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php, andtests/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
- T014 [P] [US2] Extend reason-driven dashboard action coverage in
tests/Feature/Filament/DashboardKpisWidgetTest.phpandtests/Feature/Filament/NeedsAttentionWidgetTest.php - 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, andtests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php
Implementation for User Story 2
- T016 [US2] Add backup-health attention items with safe action-target rendering in
app/Filament/Widgets/Dashboard/NeedsAttention.php - T017 [US2] Route backup-health KPI and attention destinations by reason in
app/Support/BackupHealth/TenantBackupHealthResolver.phpandapp/Support/BackupHealth/BackupHealthActionTarget.php - 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 - T019 [US2] Make schedule-follow-up continuity scan-fast on the backup-schedules surface in
app/Filament/Resources/BackupScheduleResource.php - T020 [US2] Run the focused drillthrough continuity pack from
specs/180-tenant-backup-health/quickstart.mdagainsttests/Feature/Filament/DashboardKpisWidgetTest.php,tests/Feature/Filament/NeedsAttentionWidgetTest.php,tests/Feature/Filament/BackupSetListContinuityTest.php,tests/Feature/Filament/BackupSetEnterpriseDetailPageTest.php, andtests/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
- T021 [P] [US3] Extend healthy-check inclusion and suppression coverage in
tests/Feature/Filament/NeedsAttentionWidgetTest.php - T022 [P] [US3] Extend healthy-claim gating coverage in
tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.phpandtests/Feature/Filament/TenantDashboardTruthAlignmentTest.php
Implementation for User Story 3
- T023 [US3] Enforce healthy-claim gating and supporting-message rules in
app/Support/BackupHealth/TenantBackupHealthResolver.phpandapp/Support/BackupHealth/TenantBackupHealthAssessment.php - T024 [US3] Render
Backups are recent and healthyonly when the assessment permits it inapp/Filament/Widgets/Dashboard/NeedsAttention.php - T025 [US3] Keep positive dashboard copy bounded to backup posture rather than recoverability in
app/Filament/Widgets/Dashboard/DashboardKpis.phpandapp/Filament/Widgets/Dashboard/NeedsAttention.php - T026 [US3] Run the focused healthy-wording pack from
specs/180-tenant-backup-health/quickstart.mdagainsttests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php,tests/Feature/Filament/NeedsAttentionWidgetTest.php, andtests/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
- T027 [P] [US4] Extend tenant-scope
404coverage plus established-member blocked-destination403coverage intests/Feature/Filament/TenantDashboardTenantScopeTest.php - T028 [P] [US4] Extend mixed-history latest-governs and schedule-secondary coverage in
tests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.phpandtests/Feature/Filament/TenantDashboardTruthAlignmentTest.php - 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
- T030 [US4] Finalize schedule-follow-up secondary semantics and latest-history precedence in
app/Support/BackupHealth/TenantBackupHealthResolver.php - T031 [US4] Degrade unavailable backup drillthroughs safely while preserving summary truth in
app/Filament/Widgets/Dashboard/DashboardKpis.phpandapp/Filament/Widgets/Dashboard/NeedsAttention.php - T032 [US4] Keep backup follow-up routes and record resolution tenant-scoped, capability-registry-backed, and
403-after-membership authorization-safe inapp/Filament/Resources/BackupSetResource.phpandapp/Filament/Resources/BackupScheduleResource.php - T033 [US4] Run the focused nuance and RBAC pack from
specs/180-tenant-backup-health/quickstart.mdagainsttests/Unit/Support/BackupHealth/TenantBackupHealthResolverTest.php,tests/Feature/Filament/NeedsAttentionWidgetTest.php,tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php, andtests/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.
- 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, andapp/Filament/Resources/BackupScheduleResource.php - T035 [P] Run the focused verification pack from
specs/180-tenant-backup-health/quickstart.mdagainsttests/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, andtests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php - T036 Run formatting with
vendor/bin/sail bin pint --dirty --format agentas required byspecs/180-tenant-backup-health/quickstart.md - T037 Run the manual validation pass in
specs/180-tenant-backup-health/quickstart.mdfor 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
T003andT004can run in parallel after the backup-health namespace fromT001is agreed.T006andT008can run in parallel onceT005defines the derivation contract.T009andT010can run in parallel for US1.T014andT015can run in parallel for US2.T018andT019can run in parallel for US2 onceT017fixes the reason-target contract.T021andT022can run in parallel for US3.T027,T028, andT029can run in parallel for US4.T034andT035can run in parallel once feature code is stable.
Parallel Example: User Story 1
# 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
# 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
# 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
# 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.