TenantAtlas/specs/297-managed-environment-canonical-route-cutover/legacy-surface-audit.md
ahmido 3ec582a182 feat: retire legacy tenant route surfaces (#352)
## Summary
- retire legacy `/admin/t` and active `/admin/tenants` product surfaces in favor of canonical workspace-scoped managed-environment routes
- centralize runtime URL generation through `ManagedEnvironmentLinks` and update intended URL handling to reject legacy tenant paths
- remove dormant tenant panel runtime, rename test helpers to the admin environment context, and add guard coverage for route/helper regressions

## Validation
- targeted Feature guard, workspace, provider connection, required permissions, and Filament test lanes run under Sail
- browser smoke coverage run for provider connection and workspace RBAC environment access flows
- formatting and diff checks completed with Pint and `git diff --check`

## Notes
- Filament remains on v5 with Livewire v4
- provider registration stays in `apps/platform/bootstrap/providers.php`
- retired tenant resource global search is disabled and destructive action confirmation rules remain unchanged

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #352
2026-05-12 23:35:03 +00:00

11 KiB

Legacy Surface Audit: Spec 297

Prepared: 2026-05-12
Status: Implementation and verification complete on branch 297-managed-environment-canonical-route-cutover.

Commands Run During Prep

Command Result
git status --short --branch Clean on platform-dev before Spec Kit branch creation
.specify/scripts/bash/create-new-feature.sh --json --number 297 --short-name managed-environment-canonical-route-cutover ... Created branch and spec directory 297-managed-environment-canonical-route-cutover
.specify/scripts/bash/setup-plan.sh --json Created plan.md from template
cd apps/platform && ./vendor/bin/sail artisan route:list | rg "admin/t|admin/tenants|provider-connections|required-permissions|workspaces/.*/environments|operations" Found active /admin/tenants routes plus canonical workspace/environment and workspace operations routes
cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/tenants Shows 4 TenantResource routes
cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/workspaces Shows canonical /admin/workspaces/{workspace}/environments... and /admin/workspaces/{workspace}/operations... route families
cd apps/platform && ./vendor/bin/sail artisan route:list --path=admin/provider-connections Shows tenantless provider-connection resource routes
cd apps/platform && ./vendor/bin/sail artisan route:list --columns=... Unsupported option in current Artisan route:list; retried without --columns
`cd apps/platform && rg "TenantPanelProvider panel:\s*'tenant'
git status --short --branch ## 297-managed-environment-canonical-route-cutover; only untracked spec package present before runtime edits
git diff --stat Empty before runtime edits
git log -1 --oneline 928d49b5 Merge remote-tracking branch 'origin/platform-dev' into platform-dev
cd apps/platform && ./vendor/bin/sail artisan route:list | rg "admin/t|admin/tenants|provider-connections|required-permissions|workspaces/.*/environments|operations" Confirmed active /admin/tenants TenantResource routes, canonical workspace/environment routes, canonical workspace operations routes, tenantless provider-connection routes, and canonical required-permissions route
`cd apps/platform && rg "TenantPanelProvider panel:\s*'tenant'

Findings

Finding Runtime/Test/Copy Active? Decision Fixed?
apps/platform/app/Providers/Filament/TenantPanelProvider.php exists Runtime No Deleted; bootstrap/providers.php remains Admin/System only Yes
/admin/tenants route family exists via TenantResource Runtime No Retired as active product surface; route scan now returns no matches Yes
/admin/workspaces/{workspace}/environments... route family exists Runtime Yes Reuse as canonical managed-environment route family N/A
/admin/workspaces/{workspace}/operations... route family exists Runtime Yes Reuse as canonical operations route family N/A
/admin/provider-connections... tenantless route family exists Runtime Yes Keep as canonical provider-connection route family N/A
setTenantPanelContext() exists in tests/Pest.php Test No Renamed to setAdminEnvironmentContext() with no alias; remaining hits are guard regex literals only Yes
Runtime TenantResource::getUrl(...) references remain Runtime No Replaced with ManagedEnvironmentLinks or canonical resource query URLs; app/resource scan is clean Yes
Runtime TenantDashboard::getUrl(...) references remain Runtime No Replaced in app/runtime surfaces; dashboard page getUrl() itself delegates to canonical helper Yes
Runtime TenantRequiredPermissions::getUrl(...) references remain Runtime/Test No Replaced with canonical required-permissions route/helper Yes
Tests still assert /admin/t... or /admin/tenants... in multiple historical and current files Test Yes Rebaselined to retired-route assertions, canonical routes, or historical-only allowed references Yes
Old product copy may remain in touched active surfaces Copy Bounded Touched active surfaces neutralized; remaining hits are outside touched files, guard fixtures, provider/technical names, or follow-up copy scope Yes
AdminPanelProvider explicitly registers TenantResource::class Runtime No Removed explicit registration; TenantResource stays technical/dormant with canonical URL override and global search disabled Yes
TenantResource is still used as a table/form/action owner by canonical workspace pages Runtime Yes Kept as technical owner only; URL generation is canonical and resource routes are inactive Yes
ProviderConnectionResource::extractTenantExternalIdFromUrl() accepts old /admin/tenants and /admin/t referers Runtime compatibility No Removed legacy referer parsing; canonical managed_environment_id query/context remains Yes
WorkspaceIntendedUrl accepts /admin/t... and /admin/tenants... as safe admin intended URLs Runtime No Rejects retired tenant routes at store/consume time Yes
WorkspaceRedirectResolver preserves matching /admin/t... and /admin/tenants... intended URLs Runtime No Rejects retired tenant routes and normalizes exact legacy /admin/operations to workspace-scoped operations Yes
TenantRequiredPermissions::reRunVerificationUrl() uses TenantResource::getUrl('view') Runtime No Uses canonical managed-environment detail helper Yes
ManageTenantMemberships back action uses TenantResource::getUrl('view') Runtime No Uses canonical managed-environment detail helper Yes
ProviderConnectionResource environment backlink uses TenantResource::getUrl('view') Runtime No Uses canonical managed-environment detail helper Yes

Allowed Reference Classes

Reference Why allowed Follow-up
Historical specs and audit docs Repository history, not active runtime truth None
Internal model/table/class names such as Tenant DB/model rename is out of scope Separate DB/model rename spec only if product requires it
Microsoft Entra tenant ID / provider-specific tenant copy External provider terminology None
Guard tests that assert old paths are 404 Regression protection Keep focused and explicit
TenantResource class name and internal helper references Technical resource/model naming remains out of scope Keep only if URL output is canonical and resource is not active as /admin/tenants
Copy scan hits in lang/en/localization.php, FindingExceptionsQueue, baseline compare, governance-action internals, and assignment relation internals Outside touched active cutover surfaces, guard fixtures, or technical/historical tenant-domain wording Future localization/spec only if product asks for broad copy neutralization

Implementation Verification Commands

Command Result
cd apps/platform && ./vendor/bin/sail artisan route:list | rg "admin/tenants|admin/t/" No matches; retired routes are inactive
cd apps/platform && ./vendor/bin/sail artisan route:list | rg "workspaces/.*/environments|provider-connections|required-permissions|operations" Shows canonical workspace/environment, provider-connection, required-permissions, and workspace operations route families
cd apps/platform && rg "filament\\.admin\\.resources\\.tenants|/admin/tenants|/admin/t/|TenantResource::getUrl|TenantDashboard::getUrl|TenantRequiredPermissions::getUrl|setTenantPanelContext|panel:\\s*'tenant'|panel:\\s*\\\"tenant\\\"" app resources routes --glob '!vendor' --glob '!node_modules' No matches
cd apps/platform && rg "setTenantPanelContext|panel:\\s*'tenant'|panel:\\s*\\\"tenant\\\"" tests --glob '!vendor' --glob '!node_modules' Only Spec288NoLegacyRouteAndHelperGuardTest regex guard literals remain
cd apps/platform && rg "Tenant dashboard|Tenant detail|Open tenant|Select tenant|Tenant scope|Remove tenant|Restore tenant|Tenant memberships" app resources lang tests --glob '!vendor' --glob '!node_modules' Remaining hits classified as allowed/out-of-scope above
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php tests/Feature/Guards/ManagedEnvironmentCanonicalRouteContractTest.php tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/Spec080WorkspaceManagedTenantAdminMigrationTest.php tests/Feature/Filament/ManagedEnvironmentAccessScopeManagementTest.php tests/Feature/Rbac/ProviderConnectionWorkspaceFirstPolicyTest.php 51 passed, 173 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards 265 passed, 4653 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces 96 passed, 276 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections 78 passed, 588 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions 21 passed, 82 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament 765 passed, 5 skipped, 4975 assertions
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec281ProviderConnectionScopeSmokeTest.php tests/Browser/Spec285WorkspaceRbacEnvironmentAccessSmokeTest.php 2 passed, 29 assertions
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent Pass
git diff --check Pass

Implementation Refresh Requirements

Before runtime edits, refresh this audit with:

git status --short --branch
git diff --stat

cd apps/platform
./vendor/bin/sail artisan route:list | rg "admin/t|admin/tenants|provider-connections|required-permissions|workspaces/.*/environments|operations"
rg "TenantPanelProvider|panel:\s*'tenant'|panel:\s*\"tenant\"|/admin/t/|/admin/tenants|TenantResource::getUrl|TenantDashboard::getUrl|TenantRequiredPermissions::getUrl|setTenantPanelContext|admin\.operations" . --glob '!vendor' --glob '!node_modules'

Update the Fixed? column as implementation progresses.