TenantAtlas/specs/187-portfolio-triage-arrival-context/tasks.md
2026-04-09 23:29:20 +02:00

20 KiB

Tasks: Portfolio Triage Arrival Context

Input: Design documents from /specs/187-portfolio-triage-arrival-context/ Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/portfolio-triage-arrival-context.logical.openapi.yaml, quickstart.md

Tests: Tests are REQUIRED for this feature. Use Pest unit coverage for the arrival-context codec and resolver, Filament feature coverage for workspace overview drilldowns, tenant-registry triage, tenant-dashboard continuity rendering, explicit legacy overview and registry regressions, and existing backup or restore continuity surfaces. Operations: This feature introduces no new OperationRun, queue, scheduler, remote call, or audit-log mutation surface. All work stays request-scoped and read-only. RBAC: Existing tenant-context membership and deny-as-not-found behavior remain authoritative. Tasks must preserve 404 responses for non-members, truthful degraded guidance for in-scope operators who cannot open deeper follow-up surfaces, and no new capability strings outside the existing registry. Operator Surfaces: The affected operator surfaces are workspace overview recovery triage, tenant-registry recovery triage, the tenant dashboard arrival surface, and the existing backup-set or restore-run follow-up pages that already own deeper continuity messaging. Filament UI Action Surfaces: No new destructive action, bulk action, or action group is introduced. The tenant dashboard receives only read-only continuity links, and existing tenant-open affordances remain authoritative on workspace overview and tenant registry. Filament UI UX-001: No create, edit, or view-form layouts change. This slice adds an additive dashboard widget and preserves existing page layouts and action placement. Badges: No new badge family is introduced. Existing backup-posture and recovery-evidence semantics remain unchanged.

Organization: Tasks are grouped by user story so each story can be implemented and verified independently after the shared arrival-context foundation is in place.

Phase 1: Setup (Shared Test Infrastructure)

Purpose: Prepare reusable test data and helpers for portfolio-arrival scenarios shared across all stories.

  • T001 [P] Add stale and degraded backup fixture states in apps/platform/database/factories/BackupSetFactory.php and failed, partial, and completed-with-follow-up restore fixture states in apps/platform/database/factories/RestoreRunFactory.php
  • T002 [P] Create reusable portfolio triage fixtures for workspace, tenant, operator, and generic-session scenarios in apps/platform/tests/Feature/Concerns/BuildsPortfolioTriageFixtures.php

Checkpoint: Shared fixtures are ready for overview, registry, and tenant-dashboard arrival tests.


Phase 2: Foundational (Blocking Arrival-Context Core)

Purpose: Build the single request-scoped arrival-context contract, token codec, and resolver that every story depends on.

CRITICAL: No user story work should start before this phase is complete.

  • T003 [P] Add encode, decode, unsupported-version, malformed-token, and allowlist regression coverage in apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextTokenTest.php
  • T004 [P] Add resolver coverage for tenant binding, workspace binding, concern-family allowlists, next-step derivation, disabled-target degradation, and return-target sanitization in apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php
  • T005 Create the request-scoped arrival-context value object and versioned token codec in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContext.php and apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextToken.php
  • T006 Implement scope validation, concern-to-target mapping, claim-boundary text, and bounded return-target resolution in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php

Checkpoint: One authoritative arrival-context seam exists and is covered by focused token and resolver tests.


Phase 3: User Story 1 - Understand Why The Tenant Opened (Priority: P1) MVP

Goal: Make tenant arrivals from workspace overview and filtered tenant-registry triage immediately explain why the operator opened this tenant.

Independent Test: Open a tenant dashboard from workspace recovery triage and from filtered tenant-registry triage, then verify a top-of-page continuity block names the source surface, concern family, and bounded reason before deeper widgets load.

Tests for User Story 1

  • T007 [P] [US1] Add workspace-overview arrival-token emission coverage for backup-absent and recovery-evidence drilldowns in apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php
  • T008 [P] [US1] Add filtered tenant-registry arrival-token emission coverage for triage-driven tenant opens in apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php
  • T009 [P] [US1] Add tenant-dashboard continuity rendering coverage for source surface, concern family, and bounded arrival reason in apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php

Implementation for User Story 1

  • T010 [US1] Append bounded arrival tokens to tenant-dashboard targets emitted from workspace recovery attention and recovery summary metrics in apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php
  • T011 [US1] Append arrival-context and return-state payloads only for triage-driven tenant opens in apps/platform/app/Filament/Resources/TenantResource.php and apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
  • T012 [US1] Create the tenant-dashboard continuity widget and template in apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php
  • T013 [US1] Register the arrival continuity widget first in the tenant dashboard widget stack in apps/platform/app/Filament/Pages/TenantDashboard.php

Checkpoint: User Story 1 is independently functional and every triage-driven tenant arrival explains why the tenant opened.


Phase 4: User Story 2 - See The Right Next Action (Priority: P2)

Goal: Make the arrival continuity block recommend the correct existing backup or restore follow-up surface for the triggering concern.

Independent Test: Render arrivals for backup-absent, backup-stale, backup-degraded, recovery-unvalidated, and recovery-weakened concerns and verify the continuity block recommends the matching existing follow-up surface while staying truthful when access is limited.

Tests for User Story 2

  • T014 [P] [US2] Extend tenant-dashboard continuity coverage for backup-vs-restore next-step guidance and disabled-CTA degradation in apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php
  • T015 [P] [US2] Extend downstream continuity regressions for arrival-driven backup_health_reason and recovery_posture_reason behavior in apps/platform/tests/Feature/Filament/BackupSetListContinuityTest.php and apps/platform/tests/Feature/Filament/RestoreRunListContinuityTest.php

Implementation for User Story 2

  • T016 [US2] Derive concern-family-specific next-step targets, downstream reason params, and disabled helper text in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php
  • T017 [US2] Render concern-specific next-step labels, claim boundaries, and disabled follow-up guidance in apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php
  • T018 [US2] Preserve existing backup and restore continuity ownership while accepting arrival-driven follow-up params in apps/platform/app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php, apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php, and apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ViewRestoreRun.php

Checkpoint: User Story 2 is independently functional and the arrival block tells the operator the correct next action for each concern family.


Phase 5: User Story 3 - Return To Portfolio Flow (Priority: P2)

Goal: Let operators leave the tenant surface and resume the same workspace or tenant-registry triage flow they came from.

Independent Test: Open a tenant from workspace overview and from filtered tenant-registry triage, use the return affordance, and verify the originating workspace or filtered registry context is restored.

Tests for User Story 3

  • T019 [P] [US3] Add workspace-overview return-target coverage for tenant-dashboard arrivals in apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php
  • T020 [P] [US3] Add filtered tenant-registry return-state coverage for preserved backup_posture, recovery_evidence, and triage_sort values in apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php
  • T021 [P] [US3] Add tenant-dashboard return-affordance rendering and navigation coverage in apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php

Implementation for User Story 3

  • T022 [US3] Build bounded workspace-overview and tenant-registry return targets in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php
  • T023 [US3] Reuse the existing triage-filter sanitizers when emitting and restoring return-state query params in apps/platform/app/Filament/Resources/TenantResource.php and apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
  • T024 [US3] Render the return-to-portfolio affordance only for valid arrival contexts in apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php

Checkpoint: User Story 3 is independently functional and operators can continue portfolio triage without reconstructing context manually.


Phase 6: User Story 4 - Stay Honest When Truth Or Access Changes (Priority: P3)

Goal: Keep arrival continuity truthful when posture changes, multiple concerns coexist, the token is invalid, or the operator lacks access to the deeper follow-up surface.

Independent Test: Open triage-driven arrivals after posture changes, with multiple concerns, without any arrival token, with malformed tokens, and under RBAC-limited access; verify the page preserves why the operator came while keeping current truth and access limits explicit.

Tests for User Story 4

  • T025 [P] [US4] Extend tenant-dashboard continuity coverage for stale-context honesty, multiple-concern wording, invalid-token suppression, and generic-session calmness in apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php
  • T026 [P] [US4] Add positive and negative RBAC arrival-visibility coverage for enabled follow-up links, degraded guidance, 403 capability denials, and 404 deny-as-not-found semantics in apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php

Implementation for User Story 4

  • T027 [US4] Differentiate arrival reason from current tenant truth, surface multi-concern wording, and fail closed on stale or malformed tokens in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php
  • T028 [US4] Keep the continuity block additive, suppress it for generic or invalid sessions, and render truthful current-truth deltas in apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php, apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php, and apps/platform/app/Filament/Pages/TenantDashboard.php

Checkpoint: User Story 4 is independently functional and continuity remains truthful across stale truth, multiple concerns, generic sessions, and RBAC limits.


Phase 7: Polish & Cross-Cutting Concerns

Purpose: Final alignment, formatting, and focused verification across all stories.

  • T029 [P] Extend legacy source-route preservation regressions in apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php and apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php so existing non-dashboard destinations remain authoritative when current routing chooses them
  • T030 [P] Add query-shape and request-local resolution regression coverage in apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php
  • T031 [P] Review operator-facing continuity copy and Verb + Object link labels in apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php, apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php, apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php, apps/platform/app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php, and apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php
  • T032 [P] Run formatting for touched files with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent using specs/187-portfolio-triage-arrival-context/quickstart.md
  • T033 Run the focused verification pack from specs/187-portfolio-triage-arrival-context/quickstart.md against apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextTokenTest.php, apps/platform/tests/Unit/Support/PortfolioTriage/PortfolioArrivalContextResolverTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php, apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php, apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php, apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextPerformanceTest.php, apps/platform/tests/Feature/Filament/WorkspaceOverviewContentTest.php, apps/platform/tests/Feature/Filament/TenantRegistryRecoveryTriageTest.php, apps/platform/tests/Feature/Filament/BackupSetListContinuityTest.php, apps/platform/tests/Feature/Filament/RestoreRunListContinuityTest.php, and apps/platform/tests/Feature/Rbac/TenantDashboardArrivalContextVisibilityTest.php

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): Starts immediately and prepares shared fixtures.
  • Foundational (Phase 2): Depends on Setup and blocks all user stories until the arrival-context contract, token, and resolver exist.
  • User Story 1 (Phase 3): Starts after Foundational and is the recommended MVP slice.
  • User Story 2 (Phase 4): Starts after User Story 1 because the next-step CTA extends the continuity widget and arrival-token seams established there.
  • User Story 3 (Phase 5): Starts after User Story 1 because the return affordance depends on the same arrival-context seams but can proceed in parallel with User Story 2 once the base widget exists.
  • User Story 4 (Phase 6): Starts after User Stories 2 and 3 because honesty and degradation rules need the final next-step and return-path behaviors in place.
  • Polish (Phase 7): Starts after all desired user stories are complete.

User Story Dependencies

  • US1: Depends only on the shared arrival-context foundation.
  • US2: Depends on US1 because concern-specific next-step guidance extends the continuity widget and the emitted arrival tokens.
  • US3: Depends on US1 because return targets are only meaningful once arrival tokens are already emitted and rendered.
  • US4: Depends on US2 and US3 because truthful stale-state and RBAC degradation must account for both next-step and return-target behavior.

Within Each User Story

  • Write or extend the story tests first and confirm they fail before implementation is considered complete.
  • Land resolver or routing changes before widget copy and view adjustments in the same story.
  • Keep each story shippable on its own before moving to the next priority.

Parallel Opportunities

  • T001 and T002 can run in parallel during Setup.
  • T003 and T004 can run in parallel during Foundational work, then T005 and T006 can proceed sequentially.
  • Within US1, T007, T008, and T009 can run in parallel, then T010, T011, and T012 can be split before T013 registers the widget.
  • Within US2, T014 and T015 can run in parallel, then T016, T017, and T018 can be split across contributors.
  • Within US3, T019, T020, and T021 can run in parallel, then T022, T023, and T024 can be split across contributors.
  • Within US4, T025 and T026 can run in parallel, then T027 and T028 can proceed.
  • Within Phase 7, T029 and T030 can run in parallel, then T031, T032, and T033 follow.

Parallel Example: User Story 1

# User Story 1 tests in parallel
T007 apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php
T008 apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php
T009 apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php

# User Story 1 implementation split
T010 apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php
T011 apps/platform/app/Filament/Resources/TenantResource.php and apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
T012 apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php

Parallel Example: User Story 2

# User Story 2 tests in parallel
T014 apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php
T015 apps/platform/tests/Feature/Filament/BackupSetListContinuityTest.php and apps/platform/tests/Feature/Filament/RestoreRunListContinuityTest.php

# User Story 2 implementation split
T016 apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php
T017 apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php
T018 apps/platform/app/Filament/Resources/BackupSetResource/Pages/ListBackupSets.php and apps/platform/app/Filament/Resources/RestoreRunResource/Pages/ListRestoreRuns.php

Parallel Example: User Story 3

# User Story 3 tests in parallel
T019 apps/platform/tests/Feature/Filament/WorkspaceOverviewArrivalContextTest.php
T020 apps/platform/tests/Feature/Filament/TenantRegistryArrivalContextTest.php
T021 apps/platform/tests/Feature/Filament/TenantDashboardArrivalContextTest.php

# User Story 3 implementation split
T022 apps/platform/app/Support/PortfolioTriage/PortfolioArrivalContextResolver.php
T023 apps/platform/app/Filament/Resources/TenantResource.php and apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php
T024 apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php and apps/platform/resources/views/filament/widgets/tenant/triage-arrival-continuity.blade.php

Implementation Strategy

MVP First

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3: User Story 1.
  4. Validate that triage-driven tenant arrivals now explain why the tenant opened before any deeper dashboard scan is required.

Incremental Delivery

  1. Add User Story 2 to align the arrival block with the correct existing follow-up surface.
  2. Add User Story 3 to preserve the operator's return-to-portfolio flow.
  3. Add User Story 4 to harden truthfulness, generic-session calmness, and RBAC-safe degradation.
  4. Finish with formatting and the focused verification pack.

Parallel Team Strategy

  1. One contributor can prepare fixture and token coverage while another scaffolds the overview, registry, and dashboard feature tests.
  2. After US1 lands, one contributor can take next-step mapping while another implements return-target behavior.
  3. Rejoin for US4 and Phase 7 so honesty, legacy route preservation, performance protection, formatting, and verification land together.

Notes

  • [P] tasks touch separate files or can be split without waiting on unfinished work in the same phase.
  • [US1], [US2], [US3], and [US4] labels map directly to the user stories in spec.md.
  • The suggested MVP scope is Phase 1 through Phase 3 only.
  • This task plan stays within Filament v5 on Livewire v4, makes no panel-provider changes, introduces no globally searchable resource changes, adds no destructive action, and requires no new asset strategy beyond the project's existing filament:assets deployment behavior.