TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/tasks.md
ahmido 641bb4afde feat: implement tenant lifecycle operability semantics (#172)
## Summary
- implement Spec 143 tenant lifecycle, operability, and tenant-context semantics across chooser, tenant management, onboarding, and canonical operation viewers
- add centralized tenant lifecycle and operability support types, audit action coverage, and lifecycle-aware badge and action handling
- add feature and unit coverage for tenant chooser eligibility, global search scoping, canonical operation access, onboarding authorization, and lifecycle presentation

## Testing
- vendor/bin/sail artisan test --compact
- vendor/bin/sail bin pint --dirty --format agent

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #172
2026-03-15 09:08:36 +00:00

242 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Tasks: Tenant Lifecycle, Operability, and Context Semantics Foundation
**Input**: Design documents from `/specs/143-tenant-lifecycle-operability-context-semantics/`
**Prerequisites**: plan.md, spec.md, checklists/requirements.md, research.md, data-model.md, quickstart.md, contracts/admin-tenant-context-foundation.openapi.yaml
**Tests**: Runtime behavior changes in this repo require Pest coverage. Each user story below includes the focused tests needed to keep the change independently verifiable.
**Operations**: This foundation changes canonical `OperationRun` viewer semantics but does not add a new run type or new queued work. Tasks must preserve existing `OperationRunService` ownership and canonical Monitoring navigation.
**RBAC**: This feature changes admin-plane authorization semantics. Tasks must preserve 404 vs 403 rules, policy enforcement, canonical capability registry usage, and tenant-safe global-search behavior.
**Badges**: Tenant lifecycle badge behavior must stay centralized through `BadgeCatalog` and `TenantStatusBadge`.
**Audit**: Any lifecycle mutation or newly clarified lifecycle action semantics must emit explicit workspace audit entries through the existing audit layer.
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Prepare shared fixtures and support types used by every story.
- [X] T001 Create tenant lifecycle factory states in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/database/factories/TenantFactory.php
- [X] T002 [P] Create operation-run mismatch fixtures in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/database/factories/OperationRunFactory.php
- [X] T003 [P] Create onboarding draft lifecycle fixtures in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/database/factories/TenantOnboardingSessionFactory.php
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Central abstractions that all stories depend on.
**⚠️ CRITICAL**: No user story work should start before this phase is complete.
- [X] T004 Create canonical tenant lifecycle enum in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantLifecycle.php
- [X] T005 [P] Create page category enum in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantPageCategory.php
- [X] T006 [P] Create tenant operability decision DTO in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Tenants/TenantOperabilityDecision.php
- [X] T007 Implement central operability rules in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Tenants/TenantOperabilityService.php
- [X] T008 Integrate canonical lifecycle helpers into /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Models/Tenant.php
- [X] T009 [P] Wire remembered tenant eligibility helpers into /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Workspaces/WorkspaceContext.php
- [X] T010 [P] Wire active entitled tenant resolution to operability rules in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/OperateHub/OperateHubShell.php
- [X] T011 [P] Extend lifecycle audit action identifiers in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Audit/AuditActionId.php
- [X] T012 [P] Add lifecycle audit logging helper coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Audit/WorkspaceAuditLogger.php
- [X] T013 [P] Add unit coverage for lifecycle and operability decisions in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantOperabilityServiceTest.php
- [X] T014 [P] Add unit coverage for lifecycle enum normalization in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantLifecycleTest.php
- [X] T015 [P] Add unit coverage for page-category resolution in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Unit/Tenants/TenantPageCategoryTest.php
**Checkpoint**: Central lifecycle, operability, and audit helpers are available for all user stories.
---
## Phase 3: User Story 1 - Trust Canonical Record Views (Priority: P1) 🎯 MVP
**Goal**: Canonical workspace-owned record viewers remain valid when remembered tenant context differs from the records tenant.
**Independent Test**: Open a valid `/admin/operations/{run}` route while another tenant is selected and verify the page still renders for entitled users, while non-members still receive 404 and members missing capability still receive 403.
### Tests for User Story 1
- [X] T016 [P] [US1] Update canonical operation viewer behavior tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Operations/TenantlessOperationRunViewerTest.php
- [X] T017 [P] [US1] Update remembered-context mismatch regression coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php
- [X] T018 [P] [US1] Update canonical URL and tenant entitlement tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
- [X] T019 [P] [US1] Update positive and negative authorization coverage for run access in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/RunAuthorizationTenantIsolationTest.php
### Implementation for User Story 1
- [X] T020 [US1] Refactor canonical viewer mount and mismatch handling in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
- [X] T021 [US1] Refactor canonical run URL generation and back-navigation behavior in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/OperationRunLinks.php
- [X] T022 [US1] Apply workspace-scoped filter semantics to operation lists and defaults in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/OperationRunResource.php
- [X] T023 [US1] Preserve policy-based 404 and 403 semantics for canonical runs in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Policies/OperationRunPolicy.php
- [X] T024 [US1] Align operations route semantics with canonical viewer rules in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/routes/web.php
- [X] T025 [US1] Preserve canonical viewer page-category behavior in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Concerns/ResolvesPanelTenantContext.php
**Checkpoint**: Canonical operation run viewing works independently of remembered tenant context and remains authorization-safe.
---
## Phase 4: User Story 2 - Select Only Operable Tenants (Priority: P2)
**Goal**: Standard tenant selection surfaces expose only valid normal operating tenants, while onboarding and archived tenants remain visible in the right management surfaces.
**Independent Test**: Seed tenants in `draft`, `onboarding`, `active`, and `archived` states, then verify that `/admin/choose-tenant`, tenant-selection posts, and tenant global search expose only eligible tenants while onboarding and administrative pages still show the non-active tenants appropriately.
### Tests for User Story 2
- [X] T026 [P] [US2] Update tenant chooser lifecycle eligibility tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Auth/TenantChooserSelectionTest.php
- [X] T027 [P] [US2] Update remembered tenant switcher scope tests in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php
- [X] T028 [P] [US2] Add managed-tenants landing lifecycle visibility coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php
- [X] T029 [P] [US2] Update archived tenant route access expectations in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php
- [X] T030 [P] [US2] Add tenant global-search lifecycle scope coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php
### Implementation for User Story 2
- [X] T031 [US2] Apply central operability filtering to chooser rendering in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/ChooseTenant.php
- [X] T032 [US2] Apply central operability filtering to tenant selection writes in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Controllers/SelectTenantController.php
- [X] T033 [US2] Clear or ignore ineligible remembered tenant context in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Controllers/ClearTenantContextController.php
- [X] T034 [US2] Enforce workspace-level remembered tenant validity in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Workspaces/WorkspaceContext.php
- [X] T035 [US2] Align managed-tenant landing visibility with operability rules in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Workspaces/ManagedTenantsLanding.php
- [X] T036 [US2] Align workspace selection and graceful fallback behavior in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Http/Middleware/EnsureWorkspaceSelected.php
- [X] T037 [US2] Scope tenant global search to eligible tenant records in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource.php
**Checkpoint**: Tenant selectors, remembered context, and global search enforce active-only operating selection without making onboarding or archived tenants disappear from management flows.
---
## Phase 5: User Story 3 - Understand Lifecycle and Actions Clearly (Priority: P3)
**Goal**: Tenant lifecycle labels, badges, actions, and audit behavior are centrally defined and semantically accurate across tenant management and onboarding surfaces.
**Independent Test**: Inspect tenant management and onboarding surfaces and verify that each lifecycle renders explicitly, archive-like actions use `Archive`, onboarding tenants can expose `Resume onboarding` when valid, no valid lifecycle renders as `Unknown`, and lifecycle mutations emit the expected audit records.
### Tests for User Story 3
- [X] T038 [P] [US3] Update tenant lifecycle badge mapping coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Badges/TenantStatusBadgeTest.php
- [X] T039 [P] [US3] Update tenant resource authorization and action visibility coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/TenantResourceAuthorizationTest.php
- [X] T040 [P] [US3] Update archive action enforcement coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php
- [X] T041 [P] [US3] Update onboarding lifecycle visibility and resume semantics coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php
- [X] T042 [P] [US3] Update onboarding authorization semantics for linked tenants in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php
- [X] T043 [P] [US3] Add lifecycle audit log coverage in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Audit/TenantLifecycleAuditLogTest.php
### Implementation for User Story 3
- [X] T044 [US3] Centralize tenant lifecycle badge presentation in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Badges/Domains/TenantStatusBadge.php
- [X] T045 [US3] Wire tenant lifecycle badge normalization through /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Badges/BadgeCatalog.php
- [X] T046 [US3] Align tenant table actions, filters, labels, and audit hooks with lifecycle-safe semantics in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Resources/TenantResource.php
- [X] T047 [US3] Align onboarding wizard resume and view affordances with tenant lifecycle boundaries in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
- [X] T048 [US3] Preserve onboarding workflow versus tenant lifecycle boundaries and audit emission in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Onboarding/OnboardingLifecycleService.php
- [X] T049 [US3] Preserve draft resolution and entitlement semantics for linked tenants in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Services/Onboarding/OnboardingDraftResolver.php
- [X] T050 [US3] Preserve workflow-model lifecycle boundaries in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Models/TenantOnboardingSession.php
**Checkpoint**: Lifecycle presentation, lifecycle-driven actions, and lifecycle audit behavior are centrally defined, semantically accurate, and independently testable.
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Close gaps that affect multiple stories and run final validation.
- [X] T051 [P] Add a guard against new ad hoc lifecycle checks in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Guards/NoAdHocTenantLifecycleChecksSpec143Test.php
- [X] T052 Run the focused Spec 143 validation suite from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/quickstart.md using /Users/ahmeddarrazi/Documents/projects/TenantAtlas/vendor/bin/sail artisan test --compact
- [X] T053 Run formatting for all changed PHP files with /Users/ahmeddarrazi/Documents/projects/TenantAtlas/vendor/bin/sail bin pint --dirty --format agent
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: Starts immediately.
- **Foundational (Phase 2)**: Depends on Setup and blocks all user stories.
- **User Story 1 (Phase 3)**: Depends on Foundational completion.
- **User Story 2 (Phase 4)**: Depends on Foundational completion.
- **User Story 3 (Phase 5)**: Depends on Foundational completion.
- **Polish (Phase 6)**: Depends on the completion of the user stories included in the delivery scope.
### User Story Dependencies
- **US1**: No dependency on other user stories. This is the MVP because it resolves the highest-trust canonical viewer failure.
- **US2**: Depends only on foundational operability and remembered-context helpers, not on US1.
- **US3**: Depends only on foundational lifecycle, operability, and audit abstractions, not on US1 or US2, though it benefits from their shared helpers.
### Recommended Order
1. Complete Phase 1 and Phase 2.
2. Deliver US1 as the MVP trust fix.
3. Deliver US2 to align selector and global-search behavior with operability rules.
4. Deliver US3 to unify lifecycle presentation, action semantics, and audit coverage.
5. Run polish validation and formatting before merge.
## Parallel Opportunities
- `T002` and `T003` can run in parallel after `T001`.
- `T005`, `T006`, `T009`, `T010`, `T011`, `T012`, `T013`, `T014`, and `T015` can run in parallel once `T004` is started.
- All test tasks inside each user story marked `[P]` can run in parallel.
- In US1, `T020`, `T021`, `T022`, `T023`, and `T025` can be split across contributors after the tests are in place.
- In US2, `T031`, `T032`, `T033`, `T034`, `T035`, `T036`, and `T037` can be split by controller, middleware, page, and search surfaces after the foundational service exists.
- In US3, `T044`, `T045`, `T046`, `T047`, `T048`, `T049`, and `T050` can be split between badge, Filament surface, onboarding-service, and audit work.
## Parallel Example: User Story 1
```bash
# Parallelize the focused US1 regression tests:
Task: T016 Update canonical operation viewer behavior tests in tests/Feature/Operations/TenantlessOperationRunViewerTest.php
Task: T017 Update remembered-context mismatch regression coverage in tests/Feature/Spec085/CanonicalMonitoringDoesNotMutateTenantContextTest.php
Task: T018 Update canonical URL and tenant entitlement tests in tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php
Task: T019 Update positive and negative authorization coverage for run access in tests/Feature/RunAuthorizationTenantIsolationTest.php
# Then parallelize the implementation seams:
Task: T020 Refactor canonical viewer mount and mismatch handling in app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
Task: T021 Refactor canonical run URL generation and back-navigation behavior in app/Support/OperationRunLinks.php
Task: T022 Apply workspace-scoped filter semantics to operation lists and defaults in app/Filament/Resources/OperationRunResource.php
Task: T023 Preserve policy-based 404 and 403 semantics for canonical runs in app/Policies/OperationRunPolicy.php
```
## Parallel Example: User Story 2
```bash
# Parallelize selector and search-scope tests:
Task: T026 Update tenant chooser lifecycle eligibility tests in tests/Feature/Auth/TenantChooserSelectionTest.php
Task: T027 Update remembered tenant switcher scope tests in tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php
Task: T028 Add managed-tenants landing lifecycle visibility coverage in tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php
Task: T029 Update archived tenant route access expectations in tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php
Task: T030 Add tenant global-search lifecycle scope coverage in tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php
# Then split controller, page, and search work:
Task: T031 Apply central operability filtering to chooser rendering in app/Filament/Pages/ChooseTenant.php
Task: T032 Apply central operability filtering to tenant selection writes in app/Http/Controllers/SelectTenantController.php
Task: T035 Align managed-tenant landing visibility with operability rules in app/Filament/Pages/Workspaces/ManagedTenantsLanding.php
Task: T037 Scope tenant global search to eligible tenant records in app/Filament/Resources/TenantResource.php
```
## Parallel Example: User Story 3
```bash
# Parallelize lifecycle presentation and audit tests:
Task: T038 Update tenant lifecycle badge mapping coverage in tests/Feature/Badges/TenantStatusBadgeTest.php
Task: T039 Update tenant resource authorization and action visibility coverage in tests/Feature/Rbac/TenantResourceAuthorizationTest.php
Task: T040 Update archive action enforcement coverage in tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php
Task: T043 Add lifecycle audit log coverage in tests/Feature/Audit/TenantLifecycleAuditLogTest.php
# Then split badge, resource, onboarding, and audit implementation:
Task: T044 Centralize tenant lifecycle badge presentation in app/Support/Badges/Domains/TenantStatusBadge.php
Task: T046 Align tenant table actions, filters, labels, and audit hooks with lifecycle-safe semantics in app/Filament/Resources/TenantResource.php
Task: T048 Preserve onboarding workflow versus tenant lifecycle boundaries and audit emission in app/Services/Onboarding/OnboardingLifecycleService.php
```
## Implementation Strategy
### MVP First
- Deliver Phase 1, Phase 2, and Phase 3 first.
- This yields the highest-value trust fix: canonical workspace record viewers no longer fail because of remembered tenant mismatch.
### Incremental Delivery
- After the MVP, deliver Phase 4 to make tenant selection and tenant global search match the new operability model.
- Then deliver Phase 5 to unify lifecycle presentation, action semantics, and audit behavior across tenant management and onboarding.
- Finish with Phase 6 guardrails, focused validation, and formatting.
### Task Count Summary
- **Total tasks**: 53
- **Setup tasks**: 3
- **Foundational tasks**: 12
- **US1 tasks**: 10
- **US2 tasks**: 12
- **US3 tasks**: 13
- **Polish tasks**: 3