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

248 lines
18 KiB
Markdown

# 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.
- [X] T001 Create the focused registry triage regression scaffold in `apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php`
- [X] 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.
- [X] T003 Implement request-scoped visible-tenant posture snapshot loading and canonical triage tier mapping in `apps/platform/app/Filament/Resources/TenantResource.php`
- [X] 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
- [X] 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
- [X] 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`
- [X] 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`
- [X] 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`
- [X] 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
- [X] T010 [US2] Add exact posture-filter and worst-first ordering coverage in `apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php`
### Implementation for User Story 2
- [X] 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`
- [X] T012 [US2] Implement canonical worst-first triage ordering and stable tenant-name tie breaks in `apps/platform/app/Filament/Resources/TenantResource.php`
- [X] 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`
- [X] 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
- [X] T015 [P] [US3] Add multi-tenant backup and recovery destination URL and unchanged destination-kind assertions in `apps/platform/tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php`
- [X] 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
- [X] 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`
- [X] 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`
- [X] 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
- [X] T020 [P] [US4] Add hidden-tenant leakage and posture-filter scope coverage in `apps/platform/tests/Feature/Filament/TenantResourceIndexIsWorkspaceScopedTest.php`
- [X] 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
- [X] 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`
- [X] 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`
- [X] 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`
- [X] 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.
- [X] 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`
- [X] T027 Add explicit query-bounded rendering and no per-row resolver fanout coverage in `apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php`
- [X] T028 Run formatting with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` using `specs/186-tenant-registry-recovery-triage/quickstart.md`
- [X] 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`
- [X] 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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.