## Summary - add the implementation-ready spec-prep artifacts for Spec 280: Filament Workspace Tenancy & Environment Routing Cutover - define the bounded scope, rollout constraints, route contract, and validation plan for the workspace-first routing cutover - update the generated Copilot agent context for the active feature branch ## Testing - not run; this branch adds spec-prep artifacts only and does not change application code ## Notes - no application runtime, database, or frontend code changes are included in this PR - target base branch requested: `platform-dev` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #336
9.3 KiB
9.3 KiB
Research: Filament Workspace Tenancy & Environment Routing Cutover
Date: 2026-05-07
Branch: 280-workspace-tenancy-environment-routing
Decision 1: Collapse public operator routing into the existing admin panel
- Decision:
AdminPanelProviderremains the only operator-facing Filament panel, andWorkspacebecomes the only Filament tenant for operator admin routing.TenantPanelProviderstops owning public operator routes. - Rationale: verified repo seams show
AdminPanelProvideralready owns/admin,ChooseWorkspace,ChooseTenant,WorkspaceOverview, and the current workspace-scoped operations hub, whileTenantPanelProviderexists only to keep the temporary/admin/tshell alive. Filament v5 panel configuration on Laravel 12 still expects provider registration inapps/platform/bootstrap/providers.php, so the narrowest truthful cutover is to remove the second operator panel rather than preserve it as a redirect shell. - Alternatives considered:
- Keep
TenantPanelProvideras a redirect-only shell: rejected because it preserves the same split public truth and adds compatibility behavior the spec forbids. - Introduce nested environment Filament tenancy: rejected because
ManagedEnvironmentshould remain nested route context, not a second panel tenancy.
- Keep
Decision 2: Make the workspace-scoped environment chooser the canonical public environment entry surface
- Decision: the canonical environment chooser route lives at
/admin/workspaces/{workspace}/environments, reusing the current workspace-boundManagedTenantsLandingsurface.ChooseTenantremains an implementation seam to absorb or delegate selection logic, but it should not survive as a second canonical public chooser route, and/admin/w/{workspace}/managed-tenantsis retired with no redirect or alias. - Rationale:
ManagedTenantsLandingalready binds aWorkspaceroute parameter and lists accessibleManagedEnvironmentrecords for that workspace.ChooseTenantcurrently mixes workspace recovery, selection, and redirection into the temporary tenant panel. Keeping the workspace-scoped landing as the public chooser keeps the route language aligned with the new workspace-first contract. - Alternatives considered:
- Keep both
ChooseTenantandManagedTenantsLandingpublic: rejected because it preserves two chooser URLs for the same operator decision. - Continue auto-branching from workspace selection directly into one environment dashboard: rejected because the spec treats the workspace dashboard and environment chooser as explicit decision surfaces, not hidden branching behavior.
- Keep both
Decision 3: Keep /admin tied to workspace selection or the workspace dashboard
- Decision: direct
/adminrequests resolve only to workspace selection or the canonical workspace dashboard. Environment entry becomes explicit through the workspace dashboard and environment chooser instead of using/adminas a hidden second environment dashboard route. - Rationale: the spec requires
/adminto remain the operator entrypoint only, not a second canonical environment route. This keeps the workspace dashboard as the primary decision surface and removes the need to infer operator scope from a remembered environment. - Alternatives considered:
- Keep
/adminauto-redirecting into one environment when possible: rejected because it weakens the workspace-first shell and makes route truth dependent on remembered tenant context. - Leave
/adminambiguous between workspace and environment dashboards: rejected because it preserves the current split truth.
- Keep
Decision 4: Reuse the existing workspace and environment dashboards under new route ownership
- Decision:
WorkspaceOverviewplusWorkspaceOverviewBuilderremain the workspace dashboard, andTenantDashboardplusTenantDashboardSummaryBuilderremain the managed-environment dashboard. The slice changes route ownership, breadcrumbs, context-bar signals, and deep links only. - Rationale: current repo truth already has the signal builders and widget families needed for this slice. The missing piece is not new dashboard content, but the temporary panel and route shell around it.
- Alternatives considered:
- Build new dashboard pages for workspace-first routing: rejected because it would duplicate existing signal ownership and absorb UI work the spec explicitly defers.
- Refactor builder ownership now: rejected because provider extraction and copy neutralization are deferred to later specs.
Decision 5: Move operations into a workspace-first route family through shared navigation builders
- Decision:
/admin/workspaces/{workspace}/operationsand/admin/workspaces/{workspace}/operations/{run}become the canonical operations routes, andOperationRunLinks,RelatedNavigationResolver, andMonitoring\Operationsremain the only shared seams for retargeting collection/detail URLs, environment filters, and back-navigation context. The legacy/admin/operationsfamily is retired with no redirect or alias. - Rationale:
Monitoring\Operationsalready modelsmanaged_environment_id,tenant_scope,problemClass,activeTab, and navigation context as workspace-scoped state. The current defect is the public route family and back-link language, not the monitoring page itself. - Alternatives considered:
- Keep
/admin/operationsas the canonical route: rejected because the spec explicitly requires the workspace-first operations family. - Add environment-local operations pages: rejected because the operations hub is already the canonical shared monitoring surface.
- Keep
Decision 6: Update middleware, route categorization, and panel-context resolution together
- Decision:
EnsureWorkspaceSelected,EnsureFilamentTenantSelected,TenantPageCategory,ResolvesPanelTenantContext, andWorkspaceRedirectResolvermust move to the workspace-first environment family in the same implementation slice. - Rationale: those seams currently special-case
/admin/t,/admin/tenants/{environment}, workspace-canonical/admin/operations, and current panel ID. Partial updates would leave stale remembered environment context, wrong 404/403 handling, or mixed breadcrumb language. - Alternatives considered:
- Route redirects only: rejected because redirects would preserve the old route language and leave classifier logic stale.
- Query-parameter-only environment context: rejected because the spec requires canonical workspace-first environment routes, not implicit query-driven context.
Decision 7: Keep global search truthful only where destinations remain valid
- Decision: the touched search-eligible surfaces are
WorkspaceResourceandTenantResource. Each remains globally searchable only if it still has a valid view or edit destination under the workspace-first route contract; otherwise search is disabled in the same slice. - Rationale: Filament v5 global search requires a resource to have a view or edit page in order to produce valid results. Current repo truth shows most other touched resources are already
isGloballySearchable = false, so the search review surface is small and explicit. - Alternatives considered:
- Leave current global search behavior unchanged and fix later: rejected because it can leave broken results or inaccurate hints immediately after the route cutover.
Decision 8: Prove the cutover with focused feature coverage, one browser smoke, and grep/guard checks
- Decision: use focused feature tests for routing and authorization, one browser smoke for the workspace-to-environment-to-operations path, and explicit grep/guard checks for
/admin/tandpanel: 'tenant'regressions. - Rationale: Filament documentation emphasizes testing authorization and Livewire page behavior end to end, and the riskiest regression here is the live entry flow across chooser, dashboard, and operations surfaces. One narrow browser smoke is enough; broader browser or governance suites would be disproportionate.
- Alternatives considered:
- Feature tests only: rejected because they would not prove the live chooser-to-dashboard flow on the surviving panel.
- Broad browser suite: rejected because it would create a new heavy cost center for a routing cutover slice.
Final Research Outcome
- The final operator runtime should have one public panel and one public route language rooted in workspace scope.
- The workspace-scoped environment chooser should become the public environment entry surface, with
ChooseTenantabsorbed into the same flow rather than preserved as a second public chooser URL. - The legacy chooser route
/admin/w/{workspace}/managed-tenantsand the legacy operations family/admin/operationsmust not survive as redirects, aliases, or hidden fallback readers. - The workspace dashboard and managed-environment dashboard should be reused as-is under new route ownership.
- Operations routing should move through the shared builders and preserve explicit environment scope via
managed_environment_idand back-link context. - Middleware, page categorization, and panel-context resolution must change together so deny-as-not-found and remembered-context semantics stay correct.
- Global search must remain truthful for
WorkspaceResourceandTenantResourceor be disabled in the same slice. - The narrowest honest proof is feature coverage, one browser smoke, and grep/guard checks.