TenantAtlas/specs/186-tenant-registry-recovery-triage/tasks.md
ahmido 9fbd3e5ec7 Spec 186: implement tenant registry recovery triage (#217)
## Summary
- turn the tenant registry into a workspace-scoped recovery triage surface with backup posture and recovery evidence columns
- preserve workspace overview backup and recovery drilldown intent by routing multi-tenant cases into filtered tenant registry slices
- add the Spec 186 planning artifacts, focused regression coverage, and shared triage presentation helpers

## Testing
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php tests/Feature/Guards/ActionSurfaceContractTest.php tests/Feature/Guards/FilamentTableStandardsGuardTest.php`

## Notes
- no schema change
- no new persisted recovery truth
- branch includes the full Spec 186 spec, plan, research, data model, contract, quickstart, and tasks artifacts

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #217
2026-04-09 19:20:48 +00:00

18 KiB

Tasks: Tenant Registry Recovery Triage

Input: Design documents from /specs/186-tenant-registry-recovery-triage/ 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 Pest coverage in apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php, apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php, apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php, and apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php. Operations: This feature does not create a new OperationRun, change run lifecycle ownership, or introduce queued or scheduled work. The work is limited to workspace registry rendering, filter continuity, and drilldown destinations. RBAC: Existing workspace membership, tenant visibility, and deny-as-not-found semantics remain authoritative. Tasks must preserve visible-tenant-only posture buckets, visible-tenant-only drilldown destinations, and the tenant dashboard as the permission-safe fallback surface. Operator Surfaces: TenantResource remains the canonical registry working surface, WorkspaceOverview remains the backup and recovery drilldown source, and /admin/t/{tenant} remains the canonical safe fallback destination. Filament UI Action Surfaces: No new destructive or redundant inspect actions are added. Full-row click remains the registry inspect model, the existing safe dashboard shortcut remains the only inline fast-next-step action, and workspace summary widgets keep their current destination contract. Filament UI UX-001: No create, edit, or view-page layout changes are introduced. This slice is limited to table truth, filters, ordering, and drilldown continuity. Badges: Backup posture and recovery evidence must reuse existing bounded label and tone semantics from shared badge or readiness surfaces; no page-local status language is introduced.

Organization: Tasks are grouped by user story so each story can be implemented and verified as an independent increment where the underlying surface coupling allows it.

Phase 1: Setup (Focused Regression Harness)

Purpose: Create the focused acceptance harness for the registry triage slice and the workspace drilldowns it changes.

  • T001 Create the focused registry triage regression scaffold in apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php
  • T002 [P] Stage workspace backup and recovery drilldown regression assertions in apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php

Phase 2: Foundational (Blocking Shared Posture Semantics)

Purpose: Establish one request-scoped posture snapshot and one list-surface contract baseline before story work expands the registry.

⚠️ CRITICAL: No user story work should begin until this phase is complete.

  • T003 Implement request-scoped visible-tenant posture snapshot loading and canonical triage tier mapping in apps/platform/app/Filament/Resources/TenantResource.php
  • T004 [P] Add failing list-surface and table-standards guard scenarios for the forthcoming posture columns and filters in apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php and apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php

Checkpoint: The registry has one shared posture source for columns, filters, and ranking, and the Filament table contract is guarded before story-specific UI work lands.


Phase 3: User Story 1 - See Weak Tenants On One Registry Surface (Priority: P1) 🎯

Goal: Make /admin/tenants show bounded backup posture and recovery evidence directly on each visible row.

Independent Test: Seed visible tenants with mixed backup and recovery states, open /admin/tenants, and verify that every row shows separate Backup posture and Recovery evidence signals without turning metadata into recovery truth.

Tests for User Story 1

  • T005 [US1] Add row-level backup posture, recovery evidence, dashboard-registry mapping parity, dual-signal rendering, metadata-separation, and no-overclaim coverage in apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php

Implementation for User Story 1

  • T006 [P] [US1] Reuse or extract one shared bounded backup and recovery mapping seam for registry rendering in apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php and apps/platform/app/Filament/Resources/TenantResource.php
  • T007 [US1] Add default-visible Backup posture and Recovery evidence columns beside tenant identity and lifecycle metadata in apps/platform/app/Filament/Resources/TenantResource.php
  • T008 [US1] Keep full-row inspect pointed at the existing registry detail route and the safe dashboard shortcut as the only primary next steps while surfacing posture truth in apps/platform/app/Filament/Resources/TenantResource.php
  • T009 [US1] Run focused US1 verification from specs/186-tenant-registry-recovery-triage/quickstart.md against apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php

Checkpoint: The tenant registry reads as a truthful at-a-glance recovery triage surface even before filters and workspace drilldowns are changed.


Phase 4: User Story 2 - Filter And Rank The Weakest Tenants First (Priority: P1)

Goal: Turn the registry from a readable directory into a usable triage surface with exact posture filters and deterministic worst-first ordering.

Independent Test: Apply backup and recovery posture filters in a mixed visible tenant set and verify that weak tenants sort ahead of calm rows with stable tenant-name tie breaks.

Tests for User Story 2

  • T010 [US2] Add exact posture-filter and worst-first ordering coverage in apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php

Implementation for User Story 2

  • T011 [US2] Add multi-select backup_posture and recovery_evidence filters over snapshot-derived visible tenant ID sets in apps/platform/app/Filament/Resources/TenantResource.php
  • T012 [US2] Implement canonical worst-first triage ordering and stable tenant-name tie breaks in apps/platform/app/Filament/Resources/TenantResource.php
  • T013 [P] [US2] Add filtered empty-state context for manual posture filtering without changing the default calm-browsing sort in apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
  • T014 [US2] Run focused US2 verification from specs/186-tenant-registry-recovery-triage/quickstart.md against apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php

Checkpoint: Operators can reduce the registry to the exact weak slice they need and start with the highest-priority tenants first.


Phase 5: User Story 3 - Preserve Workspace Meaning During Drilldown (Priority: P1)

Goal: Make workspace backup and recovery attention drilldowns land on a filtered registry that preserves why the operator clicked.

Independent Test: Open backup and recovery attention drilldowns for both multi-tenant and single-tenant cases and verify that multi-tenant cases land on filtered /admin/tenants while single-tenant cases still go directly to /admin/t/{tenant}.

Tests for User Story 3

  • T015 [P] [US3] Add multi-tenant backup and recovery destination URL and unchanged destination-kind assertions in apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php
  • T016 [P] [US3] Add registry drilldown continuity and single-tenant dashboard fallback coverage in apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php

Implementation for User Story 3

  • T017 [P] [US3] Initialize backup_posture, recovery_evidence, and triage_sort query intent on first registry load in apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
  • T018 [P] [US3] Replace multi-tenant backup and recovery choose_tenant destinations with filtered /admin/tenants URLs while preserving single-tenant dashboard routing and the existing widget destination-kind contract in apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php
  • T019 [US3] Run focused US3 verification from specs/186-tenant-registry-recovery-triage/quickstart.md against apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php

Checkpoint: Workspace backup and recovery counts now open a destination that keeps the same explanation visible after navigation.


Phase 6: User Story 4 - Keep Scope And Truth Boundaries Honest (Priority: P3)

Goal: Keep posture rows, filters, and drilldowns bounded to visible tenants and bounded claims even when the member has partial visibility or limited follow-up permissions.

Independent Test: Mix visible and hidden tenants with posture issues, open the registry and workspace drilldowns as a partially entitled member, and verify that only visible tenants appear and only permission-safe destinations are offered.

Tests for User Story 4

  • T020 [P] [US4] Add hidden-tenant leakage and posture-filter scope coverage in apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php
  • T021 [P] [US4] Add deny-as-not-found and permission-safe drillthrough fallback coverage in apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php

Implementation for User Story 4

  • T022 [US4] Restrict posture buckets and filtered tenant ID sets to the already visible workspace tenant query in apps/platform/app/Filament/Resources/TenantResource.php
  • T023 [P] [US4] Keep workspace attention candidate selection and dashboard fallback destinations scoped to visible tenants only in apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php
  • T024 [US4] Enforce bounded wording and safe next-step fallback when deeper backup or restore destinations are unavailable in apps/platform/app/Filament/Resources/TenantResource.php and apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php
  • T025 [US4] Run focused US4 verification from specs/186-tenant-registry-recovery-triage/quickstart.md against apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php and apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php

Checkpoint: The registry and its workspace drilldowns stay truthful, scoped, and permission-safe even for partially entitled members.


Phase 7: Polish & Cross-Cutting Concerns

Purpose: Finish guard coverage, formatting, and the final focused acceptance pack.

  • T026 [P] Run final list-surface and table-standards guard verification for the added registry columns and filters against apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php and apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php
  • T027 Add explicit query-bounded rendering and no per-row resolver fanout coverage in apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php
  • T028 Run formatting with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent using specs/186-tenant-registry-recovery-triage/quickstart.md
  • T029 Run the focused verification pack from specs/186-tenant-registry-recovery-triage/quickstart.md against apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php, apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php, and apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php
  • T030 Run the timed 10-second operator-scan and manual mixed-tenant smoke workflow from specs/186-tenant-registry-recovery-triage/quickstart.md on /admin and /admin/tenants

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): Starts immediately and creates the focused regression harness.
  • Foundational (Phase 2): Depends on Setup and blocks all user-story work until the registry has one shared posture snapshot and the list contract baseline is guarded.
  • User Stories (Phase 3+): Depend on Foundational completion.
  • Polish (Phase 7): Depends on all desired user stories being complete.

User Story Dependencies

  • User Story 1 (P1): Starts after Foundational and delivers the truthful row-level registry surface.
  • User Story 2 (P1): Starts after User Story 1 because exact filters and ranking extend the same registry surface and depend on the posture columns already being in place.
  • User Story 3 (P1): Starts after User Story 2 because workspace drilldowns must land on registry filters that already exist.
  • User Story 4 (P3): Starts after User Story 3 because the scope and fallback hardening must cover the finished registry and drilldown behavior together.

Within Each User Story

  • Story tests should be written before or alongside implementation and should fail before the story is considered complete.
  • Shared posture semantics should land before any row-level label or filter rendering that depends on them.
  • Registry resource changes should land before story-level verification runs.
  • Workspace drilldown destination changes should land before continuity verification runs.

Parallel Opportunities

  • T001 and T002 can run in parallel during Setup.
  • T003 and T004 can run in parallel after the target files are identified.
  • T006 can run in parallel with T007 after T005 defines the acceptance cases.
  • T013 can run in parallel with T011 and T012 once the filter contract is fixed.
  • T015 and T016 can run in parallel for User Story 3.
  • T017 and T018 can run in parallel for User Story 3 after the expected query contract is defined.
  • T020 and T021 can run in parallel for User Story 4.
  • T022 and T023 can run in parallel for User Story 4 once the scope assertions are in place.
  • T026 and T027 can run in parallel before the final focused verification commands are executed.

Parallel Example: User Story 1

# After T005 defines the acceptance cases:
Task: T006 apps/platform/app/Filament/Widgets/Dashboard/RecoveryReadiness.php
Task: T007 apps/platform/app/Filament/Resources/TenantResource.php

Parallel Example: User Story 2

# After T010 locks the filter and ordering expectations:
Task: T011 apps/platform/app/Filament/Resources/TenantResource.php
Task: T013 apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php

Parallel Example: User Story 3

# User Story 3 tests in parallel:
Task: T015 apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php
Task: T016 apps/platform/tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php

# User Story 3 implementation in parallel after tests exist:
Task: T017 apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
Task: T018 apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php

Parallel Example: User Story 4

# User Story 4 tests in parallel:
Task: T020 apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php
Task: T021 apps/platform/tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php

# User Story 4 implementation in parallel after the scope assertions exist:
Task: T022 apps/platform/app/Filament/Resources/TenantResource.php
Task: T023 apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php

Implementation Strategy

MVP First (Registry Triage Surface)

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3: User Story 1.
  4. Complete Phase 4: User Story 2.
  5. STOP and VALIDATE: Confirm /admin/tenants is a truthful and usable triage surface before changing workspace drilldowns.

Incremental Delivery

  1. Deliver Setup + Foundational to lock one posture source and the list contract.
  2. Deliver User Story 1 so the registry shows bounded backup and recovery truth.
  3. Deliver User Story 2 so operators can filter and rank the weak slice.
  4. Deliver User Story 3 so workspace summary clicks preserve their meaning.
  5. Deliver User Story 4 so scope, fallback, and truth boundaries remain enforced.
  6. Finish with guard updates, formatting, focused verification, and the manual smoke pass.

Parallel Team Strategy

  1. One developer can build the focused registry acceptance test while another prepares the workspace drilldown regression cases.
  2. After Foundational work, one developer can extend TenantResource.php while another keeps RecoveryReadiness.php semantics aligned for registry rendering.
  3. Once User Story 2 expectations are fixed, one developer can wire /admin/tenants filter and ordering behavior while another handles ListTenants.php query-intent defaults.
  4. User Story 3 and User Story 4 both split cleanly between registry-page work and workspace-builder work before final verification.

Notes

  • [P] tasks target different files or safe concurrent work after their prerequisite expectations are in place.
  • [US1], [US2], [US3], and [US4] labels map directly to the feature specification user stories.
  • The suggested MVP scope is Phase 1 through Phase 4, ending with a fully usable tenant-registry triage surface with explicit query-bounded coverage before workspace drilldowns are switched over.
  • No task in this plan adds a schema migration, a new persisted truth model, a new panel or provider registration, a new asset pipeline step, or a new destructive action.