## Summary - consolidate workspace and tenant shell resolution behind a canonical resolved shell context - align workspace switching, tenant selection, and tenant clearing with the new recovery and fallback rules - add focused Pest coverage for shell resolution and update root dev orchestration so platform Vite starts correctly from repo-root commands ## Testing - cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/HeaderContextBarTest.php - cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/GlobalContextShellContractTest.php - manual integrated-browser smoke for tenant-bound shell actions and context recovery flows - validated corepack pnpm build:platform, corepack pnpm dev:platform, corepack pnpm dev:website, and corepack pnpm dev ## Notes - Livewire v4 / Filament v5 remain unchanged and provider registration stays in bootstrap/providers.php - no new globally searchable resources or destructive Filament actions were introduced Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #246
9.0 KiB
Quickstart: Global Context Shell Contract
Goal
Implement Spec 199 by making workspace and tenant shell context resolve from one request-scoped contract, then verify that switch, select, clear, restore, and invalid-context flows all produce the same truth the shell displays.
Prerequisites
-
Start the app stack:
cd apps/platform && ./vendor/bin/sail up -d -
Confirm the working branch:
git branch --show-current -
Keep the current scope of work bounded to the existing Laravel and Filament monolith under
apps/platform.
Recommended Implementation Order
-
Canonicalize resolution first
- Align
WorkspaceContextandOperateHubShellso they can produce one resolved shell contract. - Make remembered context restore-only and remove any equal-ranking shell truth outside the resolved contract.
- Align
-
Align explicit mutation flows second
- Update
SwitchWorkspaceController,SelectTenantController,ClearTenantContextController, andWorkspaceRedirectResolverto consume the same contract rules. - Keep safe intended-URL behavior via
WorkspaceIntendedUrl.
- Update
-
Convert shell surfaces third
- Update
context-bar.blade.phpand any panel concern or middleware consumer to render only the resolved contract. - Preserve tenantless workspace behavior on routes that support it.
- Update
-
Close with regression coverage
- Extend current unit and feature seams before adding any new test family.
- Use browser testing only if a client-only shell behavior appears that feature tests cannot observe.
Context Source Inventory Owner
Keep the canonical source inventory in specs/199-global-context-shell-contract/data-model.md under Context Source Inventory. Any new source or fallback seam added during implementation must be recorded there before tasks are considered complete.
Documented Recovery Destinations
- Missing or unrecoverable workspace truth goes to
/admin/choose-workspace. - Generic workspace-safe recovery with no trustworthy prior route goes to
admin.operations.index. - Tenant-scoped evidence cleanup goes to
admin.evidence.overview. - Tenant-bound cleanup with a valid workspace goes to
admin.workspace.managed-tenants.index. - Tenant-bound cleanup with no recoverable workspace goes to
admin.home. - Tenantless-capable workspace routes and canonical workspace record viewers stay on their current route when entitlement remains valid.
Explicit Page-Category Exceptions
/admin/choose-workspaceis the explicitworkspace_chooser_exceptionroute.- Tenant-scoped evidence paths under
/admin/evidence/...except/admin/evidence/overvieware explicittenant_scoped_evidenceroutes for recovery purposes.
Documented Workspace Switch Destinations
- A safe intended
/admin...URL wins when it is still valid. - Workspaces with zero selectable tenants land on
admin.workspace.managed-tenants.index. - Workspaces with multiple selectable tenants land on
/admin/choose-tenant. - Workspaces with exactly one selectable tenant land on the tenant dashboard route under
/admin/t/{external_id}.
Focused Validation Commands
Run the narrowest commands that prove the contract:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperateHub/OperateHubShellResolutionTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Workspaces/WorkspaceContextRememberedTenantTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceContextTopbarAndTenantSelectionTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceContextRecoveryDisplayTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/SelectTenantControllerTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/ChooseTenantPageTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/ChooseWorkspacePageTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/ChooseWorkspaceRedirectsToChooseTenantTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/EnsureWorkspaceSelectedMiddlewareTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/SwitchWorkspaceControllerTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/SwitchWorkspaceRedirectsToTenantRegistrationWhenNoTenantsTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/WorkspaceSwitchUserMenuTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/WorkspaceRedirectResolverTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/GlobalContextShellContractTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces/WorkspacesResourceIsTenantlessTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Spec085/OperationsIndexHeaderTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/AdminGlobalSearchContextSafetyTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantRBAC/TenantSwitcherScopeTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsDbOnlyRenderTest.php
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsActionsEnqueueRunTest.php
If new focused tests are added for Spec 199, run them directly as well. The two Monitoring commands above are the non-functional proof that the shell-anchor workspace surfaces remain DB-only and do not enqueue work while rendering.
Formatting
Before closing the feature work:
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
Manual Smoke Checklist
Use a simple 3-second timer for each first-look shell scan on the in-scope entry paths so the SC-001 review stays measurable.
1. Workspace-scoped tenantless entry
- Enter
/admin/operationswith a valid workspace and no active tenant. - Confirm the shell shows the workspace name and
No tenant selectedor the approved tenantless wording. - Confirm no stale tenant label appears.
2. Explicit tenant selection
- Select a valid active tenant from the shared shell surface.
- Confirm the destination route and shell both show the same tenant.
- Confirm the tenant belongs to the active workspace only.
3. Tenant clear from a workspace-scoped page
- Clear tenant context while on
/admin/operationsor another workspace-scoped page. - Confirm the shell becomes tenantless and the page remains valid.
4. Tenant clear from a tenant-bound page
- Clear tenant context while on a tenant-bound route.
- Confirm the request does not leave the user in a half-valid tenant-bound route.
- Confirm the redirect lands in
admin.workspace.managed-tenants.indexfor the current workspace, oradmin.homewhen no workspace truth remains.
4a. Tenant clear from a tenant-scoped evidence path
- Clear tenant context while on a tenant-scoped evidence path under
/admin/evidence/.... - Confirm the redirect lands on
admin.evidence.overviewand no stale tenant label remains in the shell.
4b. Tenant clear from a canonical workspace record viewer
- Clear tenant context while on
/admin/operations/{run}. - Confirm the request stays on
admin.operations.viewwhen entitlement remains valid and does not widen into a different route unnecessarily.
5. Invalid remembered tenant
- Seed a remembered tenant that is inaccessible, missing, or incompatible.
- Confirm the remembered tenant is cleared automatically and does not reappear in the shell.
6. Workspace switch with stale tenant context
- Switch from one workspace to another where the prior tenant is not valid.
- Confirm the shell clears tenant context or replaces it only after validation in the new workspace.
7. Workspace-independent chooser route
- Enter the workspace chooser flow without an active workspace.
- Confirm the route remains available as an explicit exception and is not treated as a generic missing-workspace failure.
8. Admin versus tenant panel parity
- Resolve the same valid tenant scenario through
/adminand/admin/t/{external_id}. - Confirm the shared shell displays the same active truth and does not expose a competing panel-owned context label.
Done Signal
Spec 199 is implementation-ready when:
- one resolved shell contract governs display and route behavior,
- switch, select, clear, restore, and invalid recovery follow one shared rule set,
- the shared shell renders only the resolved truth,
- targeted unit and feature tests pass,
- timed manual smoke checks confirm tenantless and tenant-scoped behavior are both explicit and understandable.