TenantAtlas/specs/180-tenant-backup-health/tasks.md
ahmido 6f8eb28ca2 feat: add tenant backup health signals (#212)
## Summary
- add the Spec 180 tenant backup-health resolver and value objects to derive absent, stale, degraded, healthy, and schedule-follow-up posture from existing backup and schedule truth
- surface backup posture and reason-driven drillthroughs in the tenant dashboard and preserve continuity on backup-set and backup-schedule destinations
- add deterministic local/testing browser-fixture seeding plus a local fixture-login helper for the blocked drillthrough `403` scenario, along with the related spec artifacts and focused regression coverage

## Testing
- `vendor/bin/sail artisan test --compact tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php`
- `vendor/bin/sail artisan test --compact 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 tests/Feature/BackupScheduling/BackupScheduleLifecycleTest.php tests/Feature/Auth/BackupHealthBrowserFixtureLoginTest.php tests/Feature/Console/TenantpilotSeedBackupHealthBrowserFixtureCommandTest.php`

## Notes
- Filament v5 / Livewire v4 compliant; no panel-provider change was needed, so `bootstrap/providers.php` remains unchanged
- no new globally searchable resource was introduced, so global-search behavior is unchanged
- no new destructive action was added; existing destructive actions and confirmation behavior remain unchanged
- no new asset registration was added; the existing deploy-time `php artisan filament:assets` step remains sufficient
- the local fixture login helper route is limited to `local` and `testing` environments
- the focused and broader Spec 180 packs are green; the full suite was not rerun after these changes

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #212
2026-04-07 21:35:58 +00:00

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, and app/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 in app/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 in tests/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.php and app/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, and healthy semantics in app/Support/BackupHealth/TenantBackupHealthAssessment.php and app/Filament/Widgets/Dashboard/DashboardKpis.php
  • 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

  • T014 [P] [US2] Extend reason-driven dashboard action coverage in tests/Feature/Filament/DashboardKpisWidgetTest.php and tests/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, and tests/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.php and app/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.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

  • 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.php and tests/Feature/Filament/TenantDashboardTruthAlignmentTest.php

Implementation for User Story 3

  • T023 [US3] Enforce healthy-claim gating and supporting-message rules in app/Support/BackupHealth/TenantBackupHealthResolver.php and app/Support/BackupHealth/TenantBackupHealthAssessment.php
  • T024 [US3] Render Backups are recent and healthy only when the assessment permits it in app/Filament/Widgets/Dashboard/NeedsAttention.php
  • 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
  • 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

  • T027 [P] [US4] Extend tenant-scope 404 coverage plus established-member blocked-destination 403 coverage in tests/Feature/Filament/TenantDashboardTenantScopeTest.php
  • 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
  • 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.php and app/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 in app/Filament/Resources/BackupSetResource.php and app/Filament/Resources/BackupScheduleResource.php
  • 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.

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

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