TenantAtlas/specs/148-central-tenant-operability-policy/quickstart.md
ahmido 417df4f9aa feat: central tenant operability policy (#177)
## Summary
- centralize tenant operability into a lane-aware, actor-aware policy boundary
- align selector eligibility, administrative discoverability, remembered context, tenant-bound routes, and canonical run viewers
- add focused Pest coverage plus Spec 148 artifacts and final polish task completion

## Validation
- `vendor/bin/sail artisan test --compact tests/Unit/Tenants/TenantOperabilityServiceTest.php tests/Unit/Tenants/TenantOperabilityOutcomeTest.php tests/Feature/Workspaces/ChooseTenantPageTest.php tests/Feature/Workspaces/SelectTenantControllerTest.php tests/Feature/TenantRBAC/ArchivedTenantRouteAccessTest.php tests/Feature/TenantRBAC/TenantRouteDenyAsNotFoundTest.php tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php tests/Feature/Rbac/TenantResourceAuthorizationTest.php tests/Feature/Filament/ManagedTenantsLandingLifecycleTest.php tests/Feature/Filament/TenantGlobalSearchLifecycleScopeTest.php tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php`
- `vendor/bin/sail bin pint --dirty --format agent`
- manual browser smoke checks on `/admin/choose-tenant`, `/admin/tenants`, `/admin/onboarding`, `/admin/onboarding/{draft}`, and `/admin/operations/{run}`

## Filament / platform notes
- Livewire v4 compliance preserved
- panel provider registration unchanged in `bootstrap/providers.php`
- Tenant resource global search remains backed by existing view/edit pages and is now separated from active-only selector eligibility
- destructive actions remain action closures with confirmation and authorization enforcement
- no asset pipeline changes and no new `filament:assets` deployment requirement

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #177
2026-03-17 11:48:55 +00:00

94 lines
4.3 KiB
Markdown

# Quickstart: Central Tenant Operability Policy
## Goal
Validate that one central operability authority now drives selector membership, remembered-context validity, tenant-bound page legitimacy, canonical viewer behavior, and lifecycle-safe action availability.
## Prerequisites
1. Start Sail.
2. Ensure a test workspace exists with tenants covering `draft`, `onboarding`, `active`, and `archived` lifecycle states.
3. Ensure at least one onboarding session is linked to a `draft` or `onboarding` tenant.
4. Ensure at least one `OperationRun` references a tenant that is not standard-selector eligible.
## Implementation Validation Order
### 1. Run focused unit coverage for the policy core
```bash
vendor/bin/sail artisan test --compact tests/Unit/Tenants
```
Expected outcome:
- Operability outcomes are stable across all lifecycle and lane combinations.
- Reason codes distinguish lifecycle denial, lane denial, and capability denial.
### 2. Run focused selector and remembered-context tests
```bash
vendor/bin/sail artisan test --compact --filter=ChooseTenant
vendor/bin/sail artisan test --compact --filter=SelectTenant
vendor/bin/sail artisan test --compact --filter=remembered
```
Expected outcome:
- Only `active` tenants are selectable in the standard selector.
- Stale remembered context is cleared when the tenant becomes missing, out of workspace, or selector-ineligible.
### 3. Run focused tenant-bound and canonical-view tests
```bash
vendor/bin/sail artisan test --compact tests/Feature/Operations
vendor/bin/sail artisan test --compact --filter=TenantlessOperationRunViewer
vendor/bin/sail artisan test --compact --filter=OperateHubShell
vendor/bin/sail artisan test --compact --filter=ViewTenant
```
Expected outcome:
- `/admin/operations/{run}` remains valid under mismatched or empty selected tenant context.
- `/admin/tenants/{tenant}` remains valid for authorized onboarding or archived tenants even when they are not selector-eligible.
- Shell-level context resolution keeps canonical and tenant-bound routes valid without falling back to selector-lane assumptions.
### 4. Run focused lifecycle-action tests
```bash
vendor/bin/sail artisan test --compact --filter=archive
vendor/bin/sail artisan test --compact --filter=restore
vendor/bin/sail artisan test --compact --filter="resume onboarding"
vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php
vendor/bin/sail artisan test --compact --filter="onboarding completion"
vendor/bin/sail artisan test --compact --filter=readiness
```
Expected outcome:
- `Archive`, `Restore`, and `Resume onboarding` resolve from the central operability layer.
- Onboarding-completion plus readiness or verification affordances resolve from the same policy boundary with lifecycle-aware and capability-aware reasons.
- Non-members remain 404.
- In-scope users without capability remain 403.
### 5. Run focused discoverability and global-search tests
```bash
vendor/bin/sail artisan test --compact --filter=TenantResourceGlobalSearch
vendor/bin/sail artisan test --compact --filter=discoverability
```
Expected outcome:
- Administrative discoverability and tenant global search do not collapse back to standard selector eligibility.
- Non-active tenants can remain administratively discoverable when policy allows, even though they are not selectable in the active-lane chooser.
### 6. Manual smoke-check in the browser
1. Open `/admin/choose-tenant` and confirm only active tenants are selectable.
2. Open `/admin/tenants` with no selected tenant and confirm the list remains usable.
3. Open `/admin/onboarding` and `/admin/onboarding/{onboardingDraft}` and confirm onboarding-lane actions remain available only when operability allows them.
4. Open an archived tenant detail route directly and confirm the page renders when authorized.
5. Open `/admin/operations/{run}` for a run linked to an onboarding or archived tenant while a different tenant is selected and confirm the mismatch is informational only.
6. Verify lifecycle action buttons plus onboarding-completion and readiness or verification affordances remain honest and confirmation-backed where applicable.
## Non-Goals For This Slice
- No schema migration.
- No new Graph calls.
- No new assets or Filament panel registration changes.
- No new `OperationRun` type.