feat: retire tenant panel runtime dead code #359
@ -22,7 +22,6 @@
|
||||
use App\Support\Inventory\TenantCoverageTruth;
|
||||
use App\Support\Inventory\TenantCoverageTruthResolver;
|
||||
use App\Support\Navigation\NavigationScope;
|
||||
use App\Support\OperateHub\OperateHubShell;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunType;
|
||||
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
|
||||
@ -611,13 +610,7 @@ private static function resolveAdminUrlTenant(array $parameters, ?Model $tenant
|
||||
return $tenant;
|
||||
}
|
||||
|
||||
$filamentTenant = Filament::getTenant();
|
||||
|
||||
if ($filamentTenant instanceof ManagedEnvironment) {
|
||||
return $filamentTenant;
|
||||
}
|
||||
|
||||
return app(OperateHubShell::class)->tenantOwnedPanelContext(request());
|
||||
return static::resolveTenantContextForCurrentPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
it('keeps backup-set scoping split between admin remembered context and tenant-panel context', function (): void {
|
||||
it('keeps backup-set scoping split between canonical admin environment contexts', function (): void {
|
||||
$tenantA = ManagedEnvironment::factory()->create();
|
||||
[$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');
|
||||
$tenantB = ManagedEnvironment::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]);
|
||||
createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');
|
||||
|
||||
$backupSetA = BackupSet::factory()->for($tenantA)->create(['name' => 'Remembered admin backup']);
|
||||
$backupSetB = BackupSet::factory()->for($tenantB)->create(['name' => 'ManagedEnvironment panel backup']);
|
||||
$backupSetB = BackupSet::factory()->for($tenantB)->create(['name' => 'Canonical environment backup']);
|
||||
|
||||
$this->actingAs($user);
|
||||
|
||||
@ -36,11 +36,14 @@
|
||||
->assertCanSeeTableRecords([$backupSetA])
|
||||
->assertCanNotSeeTableRecords([$backupSetB]);
|
||||
|
||||
Filament::setCurrentPanel('tenant');
|
||||
Filament::setTenant($tenantB, true);
|
||||
Filament::setCurrentPanel('admin');
|
||||
Filament::setTenant(null, true);
|
||||
Filament::bootCurrentPanel();
|
||||
|
||||
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantB->workspace_id);
|
||||
session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [
|
||||
(string) $tenantB->workspace_id => (int) $tenantB->getKey(),
|
||||
]);
|
||||
|
||||
Livewire::actingAs($user)->test(ListBackupSets::class)
|
||||
->assertCanSeeTableRecords([$backupSetB])
|
||||
|
||||
@ -84,7 +84,7 @@ function entraGroupSearchTitles($results): array
|
||||
$this->get($url)->assertOk();
|
||||
});
|
||||
|
||||
it('keeps tenant-panel global-search results panel-native', function (): void {
|
||||
it('scopes admin global-search results to the selected environment context', function (): void {
|
||||
$tenantA = ManagedEnvironment::factory()->create();
|
||||
[$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');
|
||||
|
||||
@ -95,30 +95,31 @@ function entraGroupSearchTitles($results): array
|
||||
createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');
|
||||
|
||||
$groupA = EntraGroup::factory()->for($tenantA)->create([
|
||||
'display_name' => 'ManagedEnvironment panel group',
|
||||
'display_name' => 'Selected environment group',
|
||||
]);
|
||||
|
||||
EntraGroup::factory()->for($tenantB)->create([
|
||||
'display_name' => 'ManagedEnvironment panel outsider',
|
||||
'display_name' => 'Selected environment outsider',
|
||||
]);
|
||||
|
||||
$this->actingAs($user);
|
||||
Filament::setCurrentPanel('tenant');
|
||||
Filament::setCurrentPanel('admin');
|
||||
Filament::setTenant($tenantA, true);
|
||||
Filament::bootCurrentPanel();
|
||||
|
||||
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);
|
||||
|
||||
$results = EntraGroupResource::getGlobalSearchResults('ManagedEnvironment panel');
|
||||
$results = EntraGroupResource::getGlobalSearchResults('Selected environment');
|
||||
|
||||
expect(entraGroupSearchTitles($results))->toBe([
|
||||
'ManagedEnvironment panel group',
|
||||
'Selected environment group',
|
||||
]);
|
||||
|
||||
$url = $results->first()?->url;
|
||||
|
||||
expect($url)
|
||||
->toBe(EntraGroupResource::getUrl('view', ['record' => $groupA], panel: 'admin', tenant: $tenantA))
|
||||
->not->toContain('/admin/tenants')
|
||||
->not->toContain('/admin/t/');
|
||||
|
||||
$this->get($url)->assertOk();
|
||||
|
||||
@ -81,6 +81,7 @@ function seedInventoryCoverageParityRun(ManagedEnvironment $tenant, string $stat
|
||||
(string) $tenant->workspace_id,
|
||||
(string) $tenant->getRouteKey(),
|
||||
))
|
||||
->and($path)->not->toContain('/admin/t/')
|
||||
->and($path)->not->toBe('/admin/inventory/inventory-coverage');
|
||||
});
|
||||
|
||||
|
||||
@ -7,12 +7,14 @@
|
||||
use App\Models\EntraGroup;
|
||||
use App\Models\Policy;
|
||||
use App\Models\PolicyVersion;
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Filament\Facades\Filament;
|
||||
|
||||
it('renders canonical group links for resolved assignment targets', function (): void {
|
||||
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
||||
$this->actingAs($user);
|
||||
Filament::setCurrentPanel('tenant');
|
||||
Filament::setCurrentPanel('admin');
|
||||
Filament::setTenant($tenant, true);
|
||||
Filament::bootCurrentPanel();
|
||||
|
||||
$groupId = '33333333-4444-5555-6666-777777777777';
|
||||
@ -37,8 +39,15 @@
|
||||
],
|
||||
]);
|
||||
|
||||
$this->get(PolicyVersionResource::getUrl('view', ['record' => $version], panel: 'admin', tenant: $tenant))
|
||||
$groupUrl = EntraGroupResource::getUrl('view', ['record' => $group], panel: 'admin', tenant: $tenant);
|
||||
|
||||
expect($groupUrl)
|
||||
->not->toContain('/admin/tenants')
|
||||
->not->toContain('/admin/t/');
|
||||
|
||||
$this->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
|
||||
->get(PolicyVersionResource::getUrl('view', ['record' => $version], panel: 'admin', tenant: $tenant))
|
||||
->assertOk()
|
||||
->assertSee(EntraGroupResource::getUrl('view', ['record' => $group], panel: 'admin', tenant: $tenant), false)
|
||||
->assertSee($groupUrl, false)
|
||||
->assertSee('Scoped group');
|
||||
});
|
||||
|
||||
@ -83,7 +83,7 @@ function adminTenantResolverExceptionFiles(): array
|
||||
}
|
||||
});
|
||||
|
||||
it('keeps the shared panel resolver explicit about admin and tenant-panel resolution', function (): void {
|
||||
it('keeps the shared panel resolver explicit about admin and non-admin fallback resolution', function (): void {
|
||||
$resolverContents = file_get_contents(base_path('app/Filament/Concerns/ResolvesPanelTenantContext.php'));
|
||||
$contents = file_get_contents(base_path('app/Filament/Resources/EntraGroupResource.php'));
|
||||
|
||||
|
||||
@ -5,10 +5,19 @@
|
||||
use App\Support\Workspaces\WorkspaceContext;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
it('does not register active /admin/t route family product routes', function (): void {
|
||||
$legacyRouteUris = collect(Route::getRoutes())
|
||||
->map(fn ($route): string => ltrim((string) $route->uri(), '/'))
|
||||
->filter(fn (string $uri): bool => preg_match('#^admin/t(?:/|$)#', $uri) === 1)
|
||||
->values();
|
||||
|
||||
expect($legacyRouteUris)->toBeEmpty();
|
||||
});
|
||||
|
||||
it('does not register active /admin/tenants product routes', function (): void {
|
||||
$legacyRouteUris = collect(Route::getRoutes())
|
||||
->map(fn ($route): string => ltrim((string) $route->uri(), '/'))
|
||||
->filter(fn (string $uri): bool => preg_match('#^admin/(?:t|tenants)(?:/|$)#', $uri) === 1)
|
||||
->filter(fn (string $uri): bool => preg_match('#^admin/tenants(?:/|$)#', $uri) === 1)
|
||||
->values();
|
||||
|
||||
expect($legacyRouteUris)->toBeEmpty();
|
||||
@ -17,7 +26,10 @@
|
||||
it('does not register active tenant resource route names', function (): void {
|
||||
$legacyRouteNames = collect(Route::getRoutes())
|
||||
->map(fn ($route): ?string => $route->getName())
|
||||
->filter(fn (?string $name): bool => is_string($name) && str_starts_with($name, 'filament.admin.resources.tenants.'))
|
||||
->filter(fn (?string $name): bool => is_string($name) && (
|
||||
str_starts_with($name, 'filament.tenant.')
|
||||
|| str_starts_with($name, 'filament.admin.resources.tenants.')
|
||||
))
|
||||
->values();
|
||||
|
||||
expect($legacyRouteNames)->toBeEmpty();
|
||||
@ -28,6 +40,7 @@
|
||||
|
||||
foreach ([
|
||||
'/admin/t/'.$tenant->external_id,
|
||||
'/admin/t/'.$tenant->external_id.'/inventory-items',
|
||||
'/admin/tenants',
|
||||
"/admin/tenants/{$tenant->external_id}",
|
||||
"/admin/tenants/{$tenant->external_id}/edit",
|
||||
|
||||
@ -6,8 +6,14 @@
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
it('does not keep a runtime TenantPanelProvider or tenant panel registration', function (): void {
|
||||
$registeredProviders = require base_path('bootstrap/providers.php');
|
||||
$tenantPanelProviders = collect($registeredProviders)
|
||||
->filter(fn (string $provider): bool => str_contains($provider, 'TenantPanelProvider'))
|
||||
->values();
|
||||
|
||||
expect(file_exists(app_path('Providers/Filament/TenantPanelProvider.php')))->toBeFalse()
|
||||
->and(require base_path('bootstrap/providers.php'))->not->toContain('App\\Providers\\Filament\\TenantPanelProvider')
|
||||
->and(file_exists(app_path('Filament/Providers/TenantPanelProvider.php')))->toBeFalse()
|
||||
->and($tenantPanelProviders)->toBeEmpty()
|
||||
->and(Filament::getPanel('tenant'))->toBeNull();
|
||||
});
|
||||
|
||||
@ -20,5 +26,5 @@
|
||||
expect($legacyRouteUris)->toBeEmpty();
|
||||
|
||||
$this->get('/admin/t/example')->assertNotFound();
|
||||
$this->get('/admin/t/example/inventory-items')->assertNotFound();
|
||||
});
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Filament\Pages\Monitoring\Operations;
|
||||
use App\Models\OperationRun;
|
||||
use App\Models\ManagedEnvironment;
|
||||
use App\Support\OpsUx\OperationRunUrl;
|
||||
use App\Support\OperationRunLinks;
|
||||
use App\Support\OperationRunOutcome;
|
||||
use App\Support\OperationRunStatus;
|
||||
@ -240,6 +241,34 @@
|
||||
|
||||
it('builds canonical dashboard operations URLs with tenant and tab continuity', function (): void {
|
||||
$tenant = ManagedEnvironment::factory()->create();
|
||||
$run = OperationRun::factory()->create([
|
||||
'workspace_id' => (int) $tenant->workspace_id,
|
||||
'managed_environment_id' => (int) $tenant->getKey(),
|
||||
]);
|
||||
|
||||
$urls = [
|
||||
OperationRunLinks::index($tenant, activeTab: 'active'),
|
||||
OperationRunLinks::index(
|
||||
$tenant,
|
||||
activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
),
|
||||
OperationRunLinks::index(
|
||||
activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
allTenants: true,
|
||||
problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
workspace: $tenant->workspace,
|
||||
),
|
||||
OperationRunLinks::tenantlessView($run),
|
||||
OperationRunUrl::index($tenant),
|
||||
OperationRunUrl::view($run, $tenant),
|
||||
];
|
||||
|
||||
foreach ($urls as $url) {
|
||||
expect($url)
|
||||
->not->toContain('/admin/tenants')
|
||||
->not->toContain('/admin/t/');
|
||||
}
|
||||
|
||||
expect(OperationRunLinks::index($tenant, activeTab: 'active'))
|
||||
->toBe(route('admin.operations.index', [
|
||||
@ -269,7 +298,9 @@
|
||||
'tenant_scope' => 'all',
|
||||
'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
|
||||
]));
|
||||
]))
|
||||
->and(OperationRunUrl::index($tenant))->toBe(OperationRunLinks::index($tenant))
|
||||
->and(OperationRunUrl::view($run, $tenant))->toBe(OperationRunLinks::tenantlessView($run));
|
||||
});
|
||||
|
||||
it('keeps explicit environment scope out of operations lists while preserving tab continuity', function (): void {
|
||||
|
||||
@ -4,7 +4,7 @@ # TenantPilot Implementation Ledger
|
||||
> **Last reviewed:** 2026-05-12
|
||||
> **Use for:** Repo-based implementation status and product-surface maturity assessment
|
||||
> **Do not use for:** Roadmap priority, spec priority, or proof that tests were executed in the current branch
|
||||
> **Scoped maintenance:** 2026-05-12 roadmap/ledger alignment after the admin workspace navigation and tenant-owned surface repair candidate intake from the repo-verified navigation/panel audit; 2026-05-06 ledger conflict cleanup plus alignment with `docs/product/roadmap.md` and `docs/product/spec-candidates.md` after the cross-domain indicator candidate intake and the current manual-promotion backlog review.
|
||||
> **Scoped maintenance:** 2026-05-15 Tenant Panel dead-code retirement guardrail update after Spec 304; 2026-05-12 roadmap/ledger alignment after the admin workspace navigation and tenant-owned surface repair candidate intake from the repo-verified navigation/panel audit; 2026-05-06 ledger conflict cleanup plus alignment with `docs/product/roadmap.md` and `docs/product/spec-candidates.md` after the cross-domain indicator candidate intake and the current manual-promotion backlog review.
|
||||
|
||||
## Purpose
|
||||
|
||||
@ -25,6 +25,10 @@ ## Current Product Position
|
||||
|
||||
TenantPilot ist aktuell ein starkes internes Governance- und Operations-Produkt mit belastbaren Foundations fuer Execution Truth, Baselines/Drift, Findings, Evidence, Reviews, Review Packs, Supportability, Telemetry, Safety Controls und eine repo-reale governed AI policy foundation. Darauf sitzen inzwischen mehrere repo-real productization slices: eine customer-safe Review-/Governance-Package-Surface im Admin-Kontext, released-review detail handoff, compliance interpretation overlays, bounded external support-desk handoff, commercial lifecycle state handling mit read-only gating sowie eine kanonische cross-tenant compare preview mit promotion preflight. Die Repo-Wahrheit liegt damit klar ueber einer simplen Lesart von "R1 done / R2 partial" und auch ueber einer rein foundation-only Interpretation fuer Reviews, Support und Portfolio-Preparation. Gleichzeitig ist das Produkt noch nicht voll als kundenseitig konsumierbare Portfolio- und Commercial-Plattform ausgereift: Es fehlen die letzte customer-safe self-serve productization ueber der Review-Surface, actual portfolio promotion execution, ein bounded governance decision pack and approval workflow, wiederholbare Billing-/Subscription-Truth, eine klarere Stored-Reports-Surface und der erste governed AI runtime consumer ueber der bereits repo-realen AI policy foundation.
|
||||
|
||||
## Runtime Guardrails
|
||||
|
||||
- 2026-05-15 / Spec 304: Active Tenant Panel runtime is absent and guarded. `bootstrap/providers.php` registers no Tenant Panel provider, no active `TenantPanelProvider.php` exists under the platform app runtime paths, no `/admin/t` or legacy `/admin/tenants` route family is registered, and focused tests guard canonical workspace/environment link emission. Workspace remains the active Filament admin runtime context while Managed Environment surfaces stay under canonical workspace/environment routes.
|
||||
|
||||
## Status Model
|
||||
|
||||
- `foundation-only`: belastbare technische, policy- oder control-layer foundation ohne hinreichende Produktisierung
|
||||
|
||||
@ -4,7 +4,7 @@ # Spec Candidates
|
||||
> **Last reviewed:** 2026-05-12
|
||||
> **Use for:** The active repo-based queue of spec candidates that may still need new or refreshed specs
|
||||
> **Do not use for:** Proof that a candidate is already specced, implemented, or prioritized above the roadmap without repo verification
|
||||
> **Scoped maintenance:** 2026-05-12 admin workspace navigation and tenant-owned surface repair candidate intake after the repo-verified navigation/panel audit; 2026-05-06 cross-domain progress and indicator semantics candidate intake; 2026-05-04 OperationRun progress maturity plus Tenant Dashboard active-operations summary candidate intake; 2026-05-03 OperationRun activity feedback candidate intake plus the 2026-05-02 repo-based queue re-audit and enterprise-SaaS deep-research alignment against current `specs/` truth, including Specs 263 and current-branch 264.
|
||||
> **Scoped maintenance:** 2026-05-15 Spec 304 Tenant Panel dead-code retirement guardrail update; 2026-05-12 admin workspace navigation and tenant-owned surface repair candidate intake after the repo-verified navigation/panel audit; 2026-05-06 cross-domain progress and indicator semantics candidate intake; 2026-05-04 OperationRun progress maturity plus Tenant Dashboard active-operations summary candidate intake; 2026-05-03 OperationRun activity feedback candidate intake plus the 2026-05-02 repo-based queue re-audit and enterprise-SaaS deep-research alignment against current `specs/` truth, including Specs 263 and current-branch 264.
|
||||
>
|
||||
> Repo-based next-spec queue for TenantPilot.
|
||||
> This file is not a wishlist. It tracks only open gaps that are still worth turning into new or refreshed specs.
|
||||
@ -892,7 +892,7 @@ ### Admin Workspace Navigation & Tenant-owned Surface Repair candidate group
|
||||
2. `tenant-owned-surface-route-audit`
|
||||
3. `admin-directory-groups-cutover`
|
||||
4. `navigation-contract-split`, only if drift remains after the first three candidates
|
||||
5. `tenant-panel-dead-code-retirement`
|
||||
5. `tenant-panel-dead-code-retirement` -> Spec 304
|
||||
|
||||
#### `admin-inventory-navigation-cutover`
|
||||
|
||||
@ -965,6 +965,7 @@ #### `navigation-contract-split`
|
||||
|
||||
#### `tenant-panel-dead-code-retirement`
|
||||
|
||||
- **Status**: promoted to Spec 304 and implemented as a cleanup/guardrail slice on 2026-05-15. Keep this entry as historical sequencing context unless a future repo audit shows the retired Tenant Panel runtime or `/admin/t` route family has regressed.
|
||||
- **Goal**: remove remaining dead tenant-panel and `/admin/t` artifacts only after active surfaces and tests no longer rely on them.
|
||||
- **Scope**:
|
||||
- delete legacy tenant-panel provider and obsolete `/admin/t` compatibility anchors that are no longer needed after the cutover follow-through
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
# Specification Quality Checklist: Tenant Panel Dead-Code Retirement
|
||||
|
||||
**Purpose**: Validate specification completeness and readiness before implementation planning handoff
|
||||
**Created**: 2026-05-15
|
||||
**Feature**: [spec.md](../spec.md)
|
||||
|
||||
## Content Quality
|
||||
|
||||
- [x] No unresolved placeholders remain.
|
||||
- [x] Focused on operator trust, route safety, workspace-first runtime clarity, and maintenance risk.
|
||||
- [x] Written as a cleanup and guardrail spec rather than a new product feature.
|
||||
- [x] All mandatory repository-specific sections are completed.
|
||||
|
||||
## Requirement Completeness
|
||||
|
||||
- [x] No `[NEEDS CLARIFICATION]` markers remain.
|
||||
- [x] Requirements are testable and unambiguous.
|
||||
- [x] Acceptance criteria are measurable through provider, route, navigation, search, link, and RBAC tests.
|
||||
- [x] Scope is clearly bounded.
|
||||
- [x] Dependencies and assumptions are identified.
|
||||
- [x] Historical documentation allowance is explicit.
|
||||
- [x] Compatibility aliases, redirects, and shims are explicitly forbidden.
|
||||
|
||||
## Constitution And Guardrail Fit
|
||||
|
||||
- [x] SPEC-GATE-001 candidate check is completed.
|
||||
- [x] Proportionality review is completed and confirms no new structure or persisted truth.
|
||||
- [x] TEST-GOV-001 lane and fixture impact is documented.
|
||||
- [x] Provider boundary and platform-core vocabulary risks are documented.
|
||||
- [x] Filament v5 and Livewire v4.0+ posture is documented.
|
||||
- [x] Provider registration location is documented as `apps/platform/bootstrap/providers.php`.
|
||||
- [x] Destructive action posture is documented as none added.
|
||||
- [x] Asset strategy is documented as unchanged.
|
||||
|
||||
## Feature Readiness
|
||||
|
||||
- [x] User scenarios cover provider retirement, route retirement, workspace/environment navigation preservation, and link/search safety.
|
||||
- [x] Functional requirements map to concrete implementation and validation tasks.
|
||||
- [x] Plan identifies likely affected repo surfaces and current repo truth.
|
||||
- [x] Tasks are ordered, verifiable, and avoid application implementation during preparation.
|
||||
- [x] Follow-up candidates are listed without being hidden inside scope.
|
||||
|
||||
## Review Outcome
|
||||
|
||||
**Review Outcome**: `acceptable-special-case`
|
||||
**Workflow Outcome**: `keep`
|
||||
|
||||
The spec is a bounded cleanup package. It should proceed to implementation only through the separate implementation loop and must not expand into ManagedEnvironment schema cutover, compatibility routing, or broad terminology cleanup.
|
||||
|
||||
## Notes
|
||||
|
||||
- Preparation found the Tenant Panel provider and legacy route families already absent from active bootstrap and route collection. Implementation should therefore focus on verification, stale-test cleanup, link/search guardrails, and precise navigation contracts.
|
||||
- Specs 301-303 are completed or reviewed context and must not be rewritten.
|
||||
304
specs/304-tenant-panel-dead-code-retirement/plan.md
Normal file
304
specs/304-tenant-panel-dead-code-retirement/plan.md
Normal file
@ -0,0 +1,304 @@
|
||||
# Implementation Plan: Tenant Panel Dead-Code Retirement
|
||||
|
||||
**Branch**: `304-tenant-panel-dead-code-retirement` | **Date**: 2026-05-15 | **Spec**: [spec.md](spec.md)
|
||||
**Input**: Feature specification from `/specs/304-tenant-panel-dead-code-retirement/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Retire and guard the remaining Tenant Panel and legacy route assumptions after the workspace-first admin runtime repair sequence. Current repo inspection shows the Tenant Panel provider and `/admin/t` route family are already absent from the active boot path and route collection, so the implementation should focus on verifying absence, removing any confirmed stale active tests or link assumptions, and preserving canonical workspace/environment navigation and RBAC behavior.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: PHP 8.4.15
|
||||
**Primary Dependencies**: Laravel 12.52.0, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1
|
||||
**Storage**: PostgreSQL; no schema changes
|
||||
**Testing**: Pest feature/guard tests through Laravel Sail
|
||||
**Validation Lanes**: confidence, formatting/diff-check, optional browser smoke only if rendered navigation changes
|
||||
**Target Platform**: Laravel Sail locally; Dokploy container deployment for staging/production
|
||||
**Project Type**: Web application under `apps/platform`
|
||||
**Performance Goals**: No new query families, polling, route discovery cost, or runtime indirection.
|
||||
**Constraints**: No migrations, no assets, no provider behavior changes, no Graph adapter changes, no compatibility routes, no redirects, no new product surfaces.
|
||||
**Scale/Scope**: Existing provider bootstrap, route registration, link builders, and focused tests.
|
||||
|
||||
## UI / Surface Guardrail Plan
|
||||
|
||||
- **Guardrail scope**: workflow-only route/navigation guardrail change.
|
||||
- **Native vs custom classification summary**: native Filament provider/panel and navigation behavior; no custom UI.
|
||||
- **Shared-family relevance**: navigation, global search destinations, and action/deep links.
|
||||
- **State layers in scope**: route collection, shell route context, remembered environment context, resource URL generation.
|
||||
- **Audience modes in scope**: operator-MSP and support-platform where existing admin access already applies.
|
||||
- **Decision/diagnostic/raw hierarchy plan**: N/A. No new operator decision surface.
|
||||
- **Raw/support gating plan**: unchanged.
|
||||
- **One-primary-action / duplicate-truth control**: unchanged; this cleanup adds no actions.
|
||||
- **Handling modes by drift class or surface**: review-mandatory for active test or link assumptions that still encode retired route behavior.
|
||||
- **Repository-signal treatment**: route/provider/link residues are hard-stop candidates if they revive retired runtime behavior; historical docs are report-only.
|
||||
- **Special surface test profiles**: global-context-shell and standard-native-filament.
|
||||
- **Required tests or manual smoke**: provider/route guard tests, legacy URL 404 tests, navigation separation tests, Inventory and Entra Groups regression tests, global-search/link URL tests. Browser smoke is recommended only if implementation changes rendered navigation or route registration.
|
||||
- **Exception path and spread control**: none. If a real active dependency cannot be removed safely, document it as a deferred blocker rather than adding compatibility behavior.
|
||||
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage or feature-test substitute.
|
||||
|
||||
## Shared Pattern & System Fit
|
||||
|
||||
- **Cross-cutting feature marker**: yes.
|
||||
- **Systems touched**:
|
||||
- `apps/platform/bootstrap/providers.php`
|
||||
- `apps/platform/routes/web.php`
|
||||
- `apps/platform/app/Providers/Filament/AdminPanelProvider.php`
|
||||
- `apps/platform/app/Support/ManagedEnvironmentLinks.php`
|
||||
- `apps/platform/app/Support/OperationRunLinks.php`
|
||||
- `apps/platform/app/Support/OpsUx/OperationRunUrl.php`
|
||||
- `apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php`
|
||||
- `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php`
|
||||
- `apps/platform/app/Support/OperateHub/OperateHubShell.php`
|
||||
- `apps/platform/app/Support/Navigation/NavigationScope.php`
|
||||
- focused tests under `apps/platform/tests/Feature/Guards`, `apps/platform/tests/Feature/Filament`, `apps/platform/tests/Feature/Workspaces`, `apps/platform/tests/Feature/Monitoring`, `apps/platform/tests/Feature/Operations`, `apps/platform/tests/Feature/ProviderConnections`, and `apps/platform/tests/Feature/RequiredPermissions`
|
||||
- **Shared abstractions reused**: existing canonical route helpers, `ManagedEnvironmentLinks`, `OperationRunLinks`, `WorkspaceScopedTenantRoutes`, `OperateHubShell`, `NavigationScope`, and current Filament resource URL behavior.
|
||||
- **New abstraction introduced? why?**: none.
|
||||
- **Why the existing abstraction was sufficient or insufficient**: Existing helpers already produce canonical workspace/environment URLs. The cleanup needs guardrails and stale-test removal, not a new route layer.
|
||||
- **Bounded deviation / spread control**: no deviations. Compatibility redirects and aliases are forbidden.
|
||||
|
||||
## OperationRun UX Impact
|
||||
|
||||
- **Touches OperationRun start/completion/link UX?**: link safety only.
|
||||
- **Central contract reused**: `OperationRunLinks` and `App\Support\OpsUx\OperationRunUrl`.
|
||||
- **Delegated UX behaviors**: existing operation URL resolution remains shared.
|
||||
- **Surface-owned behavior kept local**: none.
|
||||
- **Queued DB-notification policy**: N/A.
|
||||
- **Terminal notification path**: N/A.
|
||||
- **Exception path**: none.
|
||||
|
||||
## Provider Boundary & Portability Fit
|
||||
|
||||
- **Shared provider/platform boundary touched?**: yes, bounded to retired tenant-route runtime language.
|
||||
- **Provider-owned seams**: Existing Microsoft/tenant vocabulary where current models, provider payloads, or historical docs still require it.
|
||||
- **Platform-core seams**: provider bootstrap, panel IDs, route names, canonical workspace/environment URLs, RBAC and navigation tests.
|
||||
- **Neutral platform terms / contracts preserved**: Workspace, Managed Environment, Environment, workspace-first admin runtime, canonical environment route.
|
||||
- **Retained provider-specific semantics and why**: Existing `Tenant` vocabulary remains only where this cleanup does not own the broader model/schema terminology cutover.
|
||||
- **Bounded extraction or follow-up path**: none unless implementation discovers real model/schema-level tenant-core blockers; those must become a follow-up, not hidden scope.
|
||||
|
||||
## Technical Approach
|
||||
|
||||
1. Confirm current runtime truth:
|
||||
- provider bootstrap does not register Tenant Panel provider
|
||||
- no active Tenant Panel provider class exists in runtime app paths
|
||||
- route collection has no `admin/t` or legacy `admin/tenants` product routes
|
||||
- Filament does not resolve a `tenant` panel
|
||||
2. Inspect active tests that still mention `/admin/t`, `/admin/tenants`, `TenantPanelProvider`, or old tenant-panel route names.
|
||||
- Keep tests that explicitly assert removal.
|
||||
- Update or remove tests that expect compatibility redirects, tenant-panel reachability, or blanket admin-hidden semantics.
|
||||
3. Inspect active link builders and resource search destinations.
|
||||
- Verify `ManagedEnvironmentLinks`, `OperationRunLinks`, `OperationRunUrl`, global search, and focused resource URL helpers do not emit `/admin/t`.
|
||||
- Add or update high-signal assertions only where coverage is missing.
|
||||
4. Preserve navigation contracts from Specs 301 and 303.
|
||||
- Workspace home stays clean.
|
||||
- Environment context shows eligible environment-bound surfaces.
|
||||
- Inventory and Entra Groups keep canonical workspace/environment routes.
|
||||
5. Delete active dead runtime files only if a file exists and repo references prove it is unused.
|
||||
6. Update product docs minimally only if implementation changes current repo truth or candidate sequencing.
|
||||
7. Run focused tests and `git diff --check`; run browser smoke if rendered navigation or route registration changed.
|
||||
|
||||
## Current Repo Findings From Preparation
|
||||
|
||||
- `apps/platform/bootstrap/providers.php` registers only app/auth/admin/system providers for Filament runtime.
|
||||
- No active `TenantPanelProvider.php` file was found under `apps/platform/app`.
|
||||
- Laravel route inspection returned no matching routes for `admin/t` and no matching routes for `admin/tenants`.
|
||||
- Existing guard tests already cover provider absence and active route absence:
|
||||
- `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php`
|
||||
- `apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php`
|
||||
- Existing route/navigation tests already cover portions of the intended contract, including `PanelNavigationSegregationTest`, `InventoryCoverageAdminTenantParityTest`, `EntraGroupAdminScopeTest`, and `EntraGroupGlobalSearchScopeTest`.
|
||||
- Active test files still contain historical or stale `/admin/t` mentions. Implementation must classify them instead of blanket-deleting them.
|
||||
|
||||
## Existing Repository Surfaces Likely Affected
|
||||
|
||||
### Runtime Surfaces To Inspect
|
||||
|
||||
```text
|
||||
apps/platform/bootstrap/providers.php
|
||||
apps/platform/routes/web.php
|
||||
apps/platform/app/Providers/Filament/AdminPanelProvider.php
|
||||
apps/platform/app/Providers/Filament/TenantPanelProvider.php
|
||||
apps/platform/app/Filament/Providers/TenantPanelProvider.php
|
||||
apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php
|
||||
apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php
|
||||
apps/platform/app/Support/Navigation/NavigationScope.php
|
||||
apps/platform/app/Support/OperateHub/OperateHubShell.php
|
||||
apps/platform/app/Support/ManagedEnvironmentLinks.php
|
||||
apps/platform/app/Support/OperationRunLinks.php
|
||||
apps/platform/app/Support/OpsUx/OperationRunUrl.php
|
||||
apps/platform/app/Filament/Resources/InventoryItemResource.php
|
||||
apps/platform/app/Filament/Resources/EntraGroupResource.php
|
||||
apps/platform/app/Filament/Pages/InventoryCoverage.php
|
||||
apps/platform/app/Filament/Pages/EnvironmentDashboard.php
|
||||
```
|
||||
|
||||
### Test Surfaces To Inspect Or Update
|
||||
|
||||
```text
|
||||
apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php
|
||||
apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php
|
||||
apps/platform/tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php
|
||||
apps/platform/tests/Feature/Filament/PanelNavigationSegregationTest.php
|
||||
apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php
|
||||
apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php
|
||||
apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php
|
||||
apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php
|
||||
apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php
|
||||
apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php
|
||||
apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php
|
||||
apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php
|
||||
apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php
|
||||
apps/platform/tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php
|
||||
apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php
|
||||
apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php
|
||||
```
|
||||
|
||||
## Domain / Model Implications
|
||||
|
||||
- No model rename.
|
||||
- No new model.
|
||||
- No table migration.
|
||||
- No `tenant_id` cleanup.
|
||||
- No `managed_environment_id` retargeting.
|
||||
- Existing model names and relationship names may still use `Tenant` where this spec does not own the broader core cutover.
|
||||
|
||||
## UI / Filament Implications
|
||||
|
||||
- Filament v5 targets Livewire v4.0+; this repo currently uses Livewire 4.1.4.
|
||||
- Provider registration remains in `apps/platform/bootstrap/providers.php` for Laravel 12; do not move panel provider registration to `bootstrap/app.php`.
|
||||
- `AdminPanelProvider` and `SystemPanelProvider` remain the active panel providers.
|
||||
- The retired Tenant Panel ID must not reappear.
|
||||
- Globally searchable resources touched by this cleanup must keep valid View/Edit pages or disable global search. Entra Groups, Policy, and Policy Versions already have focused global-search tests and View pages in the current route family.
|
||||
- No destructive actions are added. Existing destructive actions, if encountered incidentally, must still execute through `->action(...)`, `->requiresConfirmation()`, and server-side authorization.
|
||||
- No assets are added or changed; deploy-time `cd apps/platform && php artisan filament:assets` posture is unchanged.
|
||||
|
||||
## RBAC / Policy Implications
|
||||
|
||||
- UI visibility remains non-authoritative.
|
||||
- Workspace membership remains the primary admin runtime isolation boundary.
|
||||
- Managed Environment access remains required for environment-owned data.
|
||||
- Cross-workspace and cross-environment direct URL manipulation remains deny-as-not-found.
|
||||
- Members without capability keep existing 403/denial semantics after membership is established.
|
||||
- Global search must not bypass environment scoping or resource policies.
|
||||
|
||||
## Data / Migration Implications
|
||||
|
||||
- No migrations.
|
||||
- No data backfill.
|
||||
- No seed changes unless a stale test fixture explicitly encodes a retired route and is updated in a test-only path.
|
||||
- No PostgreSQL, JSONB, or index changes.
|
||||
|
||||
## Documentation Implications
|
||||
|
||||
- Historical docs and old specs are allowed to mention Tenant Panel and `/admin/t`.
|
||||
- Update current product docs only if implementation changes current repo truth or candidate sequencing.
|
||||
- Likely optional docs:
|
||||
- `docs/product/spec-candidates.md`
|
||||
- `docs/product/implementation-ledger.md`
|
||||
- Do not duplicate the full spec into product docs.
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
- Strengthen existing provider and route guard tests.
|
||||
- Add missing route-name or route-collection checks for retired tenant-panel semantics.
|
||||
- Update stale feature tests that still expect compatibility redirects or tenant-panel reachability.
|
||||
- Preserve existing workspace-home and environment-context navigation proofs.
|
||||
- Preserve Inventory and Entra Groups focused tests from Specs 301 and 303.
|
||||
- Add high-signal link/search no-`/admin/t` assertions only where missing.
|
||||
- Prefer feature tests over browser smoke unless rendered navigation behavior changed.
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before implementation. Re-check after implementation.*
|
||||
|
||||
- Inventory-first: no inventory truth or snapshot semantics change.
|
||||
- Read/write separation: no new write/change function.
|
||||
- Single Graph contract path: no Graph calls or contract changes.
|
||||
- Deterministic capabilities: no capability resolver changes.
|
||||
- RBAC-UX: UI visibility is not authorization; server-side checks remain authoritative.
|
||||
- Workspace isolation: non-member workspace access remains 404.
|
||||
- Tenant/environment isolation: environment-owned data remains scoped to entitled environment context.
|
||||
- OperationRun: no start/completion semantics change; only URL safety is checked.
|
||||
- Proportionality: no new structure, layer, persisted truth, or semantic machinery.
|
||||
- No premature abstraction: no new route framework, provider framework, or compatibility bridge.
|
||||
- Persisted truth: no new persistence.
|
||||
- State: no new status or reason family.
|
||||
- Shared pattern first: reuse existing route/link helpers and guard tests.
|
||||
- Provider boundary: no provider-specific behavior moves into platform core.
|
||||
- Test governance: focused guard/feature tests, no hidden heavy-family expansion.
|
||||
- Filament native first: native Filament provider/routing/navigation behavior; no custom UI.
|
||||
|
||||
## Test Governance Check
|
||||
|
||||
- **Test purpose / classification by changed surface**: Feature/guardrail.
|
||||
- **Affected validation lanes**: confidence and diff-check.
|
||||
- **Why this lane mix is the narrowest sufficient proof**: The change is provider bootstrap, route collection, URL generation, navigation contract, and test cleanup. Focused feature/guard tests prove these without broad browser or heavy-governance lanes.
|
||||
- **Narrowest proving command(s)**:
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php`
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Filament/AdminTenantSurfaceParityTest.php tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php`
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php`
|
||||
- `git diff --check`
|
||||
- **Fixture / helper / factory / seed / context cost risks**: low; reuse existing factories and helpers.
|
||||
- **Expensive defaults or shared helper growth introduced?**: no.
|
||||
- **Heavy-family additions, promotions, or visibility changes**: none expected.
|
||||
- **Surface-class relief / special coverage rule**: standard-native-filament and global-context-shell feature coverage.
|
||||
- **Closing validation and reviewer handoff**: verify no provider/route/link compatibility residue, no stale blanket hidden tests, and no RBAC/context coverage weakened.
|
||||
- **Budget / baseline / trend follow-up**: none expected.
|
||||
- **Review-stop questions**: Did any compatibility redirect get added? Did any route collection include `admin/t`? Did any global-search or operation URL contain `/admin/t`? Did workspace home stay clean? Did environment surfaces stay visible?
|
||||
- **Escalation path**: follow-up-spec only if structural navigation-test coupling remains.
|
||||
- **Active feature PR close-out entry**: Guardrail and optional Smoke Coverage.
|
||||
- **Why no dedicated follow-up spec is needed now**: This spec is the dedicated cleanup slice. Follow-ups are conditional only if implementation uncovers new blockers.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/304-tenant-panel-dead-code-retirement/
|
||||
+-- checklists/
|
||||
| +-- requirements.md
|
||||
+-- plan.md
|
||||
+-- spec.md
|
||||
+-- tasks.md
|
||||
```
|
||||
|
||||
### Source Code (likely implementation surfaces)
|
||||
|
||||
```text
|
||||
apps/platform/bootstrap/
|
||||
apps/platform/routes/
|
||||
apps/platform/app/Providers/Filament/
|
||||
apps/platform/app/Filament/
|
||||
apps/platform/app/Support/
|
||||
apps/platform/tests/Feature/Guards/
|
||||
apps/platform/tests/Feature/Filament/
|
||||
apps/platform/tests/Feature/Workspaces/
|
||||
apps/platform/tests/Feature/Monitoring/
|
||||
apps/platform/tests/Feature/Operations/
|
||||
apps/platform/tests/Feature/ProviderConnections/
|
||||
apps/platform/tests/Feature/RequiredPermissions/
|
||||
```
|
||||
|
||||
**Structure Decision**: Use the existing Laravel/Filament app structure and existing Pest test directories. Do not create new base folders.
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
No constitution violation and no BLOAT-001 trigger. The spec removes or guards legacy behavior and introduces no new persistence, abstraction, state family, taxonomy, or UI framework.
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
1. Confirm active provider and route truth.
|
||||
2. Classify active tests and link builders that mention retired route families.
|
||||
3. Update guardrails for provider, route collection, route names, and not-found behavior.
|
||||
4. Replace stale test contracts with workspace-home clean and environment-context visible assertions.
|
||||
5. Add or update link/search no-legacy assertions.
|
||||
6. Delete active dead runtime files only if found and proven unused.
|
||||
7. Run focused validation and document browser smoke decision.
|
||||
|
||||
## Rollout Considerations
|
||||
|
||||
- No deployment migration.
|
||||
- No environment variables.
|
||||
- No queue or cron worker changes.
|
||||
- No storage/volume changes.
|
||||
- No reverse proxy/Dokploy changes.
|
||||
- Staging validation should run the focused Pest suite before production promotion.
|
||||
306
specs/304-tenant-panel-dead-code-retirement/spec.md
Normal file
306
specs/304-tenant-panel-dead-code-retirement/spec.md
Normal file
@ -0,0 +1,306 @@
|
||||
# Feature Specification: Tenant Panel Dead-Code Retirement
|
||||
|
||||
**Feature Branch**: `304-tenant-panel-dead-code-retirement`
|
||||
**Created**: 2026-05-15
|
||||
**Status**: Draft
|
||||
**Input**: User description: "Retire remaining active Tenant Panel and legacy `/admin/t` runtime artifacts after Specs 301-303 repaired the workspace-first admin runtime and environment-bound surfaces."
|
||||
|
||||
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
|
||||
|
||||
- **Problem**: The product contract is now workspace-first, but retired Tenant Panel and legacy `/admin/t` assumptions can still survive in provider registration, route definitions, tests, helper URLs, or compatibility-style assertions.
|
||||
- **Today's failure**: Repo truth already shows no active Tenant Panel provider registration and no active `/admin/t` or `/admin/tenants` route collection entries, but active tests and historical seams still mention old route families. Without a bounded cleanup, future work can accidentally protect stale panel behavior or add compatibility routes instead of using canonical workspace/environment routes.
|
||||
- **User-visible improvement**: Operators stay in one coherent workspace-first admin runtime. Environment-owned surfaces remain discoverable only in active environment context, and old Tenant Panel URLs fail clearly instead of redirecting or leaking state.
|
||||
- **Smallest enterprise-capable version**: Verify and retire active Tenant Panel runtime residue, tighten route/provider/link guardrails, update stale tests to distinguish workspace-home cleanliness from environment-bound visibility, and preserve Inventory and Entra Groups contracts from Specs 301 and 303.
|
||||
- **Explicit non-goals**: No new routing architecture, no ManagedEnvironment schema cutover, no `tenant_id` migration, no compatibility aliases, no redirects from retired routes, no new product surfaces, no Graph/provider adapter changes, no migrations, no assets, no broad terminology purge, and no customer portal changes.
|
||||
- **Permanent complexity imported**: No new models, tables, enums, statuses, provider abstractions, UI frameworks, or runtime surfaces. The only permanent cost is focused guardrail coverage and clearer route/navigation tests.
|
||||
- **Why now**: `docs/product/spec-candidates.md` sequences `tenant-panel-dead-code-retirement` after Specs 301, 302, and 303. Those specs closed the Inventory, route-audit, and Entra Groups prerequisites needed before deleting or guarding old Tenant Panel assumptions.
|
||||
- **Why not local**: A one-off deletion risks either missing hidden link emitters or weakening workspace/environment access coverage. The cleanup must be repo-based and test-backed so it removes only dead runtime behavior while preserving canonical environment surfaces.
|
||||
- **Approval class**: Cleanup
|
||||
- **Red flags triggered**: None. This spec removes or guards legacy runtime behavior and does not introduce a new truth model, abstraction, taxonomy, or product surface.
|
||||
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 1 | Wiederverwendung: 2 | **Gesamt: 11/12**
|
||||
- **Decision**: approve
|
||||
|
||||
## Spec Scope Fields *(mandatory)*
|
||||
|
||||
- **Scope**: canonical-view
|
||||
- **Primary Routes**:
|
||||
- Retired negative-control routes: `/admin/t/{environment}`, `/admin/t/{environment}/...`, `/admin/tenants`, and `/admin/tenants/{environment}` legacy entry shapes.
|
||||
- Canonical workspace route: `/admin/workspaces/{workspace}/overview`.
|
||||
- Canonical environment route: `/admin/workspaces/{workspace}/environments/{environment}`.
|
||||
- Canonical environment-owned resource routes under `/admin/workspaces/{workspace}/environments/{environment}/...`.
|
||||
- **Data Ownership**: No data ownership changes. Existing workspace-owned and managed-environment-owned tables remain unchanged. This spec does not introduce or migrate persistence.
|
||||
- **RBAC**: Workspace membership and Managed Environment access remain server-side requirements. Navigation visibility is not authorization. Non-entitled workspace/environment access remains deny-as-not-found.
|
||||
|
||||
For canonical-view specs, the spec MUST define:
|
||||
|
||||
- **Default filter behavior when tenant-context is active**: Environment-bound resources continue to resolve through the active canonical workspace/environment context or explicit environment route parameters. Workspace-home surfaces remain tenantless by URL and must not show environment-owned navigation.
|
||||
- **Explicit entitlement checks preventing cross-tenant leakage**: Direct legacy URLs, manipulated canonical environment URLs, stale remembered context, cross-workspace records, and cross-environment records must continue to deny as not found or safely return no results according to existing resource contracts.
|
||||
|
||||
## Current Repo Truth To Preserve
|
||||
|
||||
- `apps/platform/bootstrap/providers.php` currently registers `AppServiceProvider`, `AuthServiceProvider`, `AdminPanelProvider`, and `SystemPanelProvider`; it does not register a Tenant Panel provider.
|
||||
- Repo inspection found no active `TenantPanelProvider.php` under `apps/platform/app`.
|
||||
- Laravel route inspection found no routes matching `admin/t` and no routes matching `admin/tenants`.
|
||||
- Existing guard tests already include `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php` and `apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php`.
|
||||
- Existing canonical environment routes already include Inventory Items, Inventory Coverage, Entra Groups, Policy, Policy Versions, Backup Sets/Schedules, Restore Runs, Findings, Evidence, Environment Reviews, Stored Reports, and Operations through workspace/environment routes.
|
||||
- Implementation must treat this repo truth as a starting point. If an artifact is already absent, the work is to strengthen or consolidate guardrails rather than inventing deletion.
|
||||
|
||||
## Cross-Cutting / Shared Pattern Reuse
|
||||
|
||||
- **Cross-cutting feature?**: yes
|
||||
- **Interaction class(es)**: route registration, Filament provider registration, navigation guardrails, global search result destinations, operation/action links, and environment-bound resource link generation.
|
||||
- **Systems touched**:
|
||||
- `apps/platform/bootstrap/providers.php`
|
||||
- `apps/platform/routes/web.php`
|
||||
- `apps/platform/app/Providers/Filament/AdminPanelProvider.php`
|
||||
- `apps/platform/app/Support/ManagedEnvironmentLinks.php`
|
||||
- `apps/platform/app/Support/OperationRunLinks.php`
|
||||
- `apps/platform/app/Support/OpsUx/OperationRunUrl.php`
|
||||
- `apps/platform/app/Filament/Concerns/WorkspaceScopedTenantRoutes.php`
|
||||
- `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php`
|
||||
- `apps/platform/app/Support/Navigation/NavigationScope.php`
|
||||
- focused guard, navigation, search, and link tests under `apps/platform/tests/`
|
||||
- **Existing pattern(s) to extend**: canonical workspace/environment routes, `ManagedEnvironmentLinks`, `OperationRunLinks`, `WorkspaceScopedTenantRoutes`, `OperateHubShell`, `NavigationScope`, and existing guard tests.
|
||||
- **Shared contract / presenter / builder / renderer to reuse**: Existing route/link helpers and Filament resource URL helpers. No new route-helper framework is introduced.
|
||||
- **Why the existing shared path is sufficient or insufficient**: Existing shared paths already emit canonical workspace/environment URLs. This cleanup only verifies no high-signal path still emits `/admin/t` or resurrects retired tenant-panel route names.
|
||||
- **Allowed deviation and why**: none. Compatibility aliases, redirects, shims, and fallback helpers are forbidden in this spec.
|
||||
- **Consistency impact**: Workspace home remains clean; environment-owned surfaces remain visible only in environment context; global search and operation links must not emit legacy route language.
|
||||
- **Review focus**: Reviewers must verify no provider registration, route definition, link builder, global-search destination, or active test contract depends on the retired Tenant Panel runtime.
|
||||
|
||||
## OperationRun UX Impact
|
||||
|
||||
- **Touches OperationRun start/completion/link UX?**: link safety only. This spec does not start, queue, deduplicate, resume, block, complete, or redesign `OperationRun` behavior.
|
||||
- **Shared OperationRun UX contract/layer reused**: Existing `OperationRunLinks` and `App\Support\OpsUx\OperationRunUrl`.
|
||||
- **Delegated start/completion UX behaviors**: N/A for new behavior.
|
||||
- **Local surface-owned behavior that remains**: Existing operation start and terminal notification behavior remains out of scope.
|
||||
- **Queued DB-notification policy**: N/A.
|
||||
- **Terminal notification path**: N/A.
|
||||
- **Exception required?**: none.
|
||||
|
||||
## Provider Boundary / Platform Core Check
|
||||
|
||||
- **Shared provider/platform boundary touched?**: yes, bounded to route/runtime cleanup and vocabulary guardrails.
|
||||
- **Boundary classification**: mixed, because old tenant wording remains in some model and provider terminology while runtime routing must be workspace-first.
|
||||
- **Seams affected**: provider registration, Filament panel IDs, route names, link builders, global search URLs, navigation tests, and historical route terminology.
|
||||
- **Neutral platform terms preserved or introduced**: Workspace, Managed Environment, Environment, workspace-first admin runtime, canonical environment route.
|
||||
- **Provider-specific semantics retained and why**: `Tenant` terminology may remain where existing database/model/provider vocabulary still requires it or where historical docs mention it. This spec is not a full terminology purge.
|
||||
- **Why this does not deepen provider coupling accidentally**: No Microsoft provider behavior, Graph adapter, capability registry, or platform-core taxonomy is added.
|
||||
- **Follow-up path**: `navigation-contract-split` only if implementation proves tests still conflate workspace-home cleanliness with environment-bound visibility after this cleanup.
|
||||
|
||||
## UI / Surface Guardrail Impact
|
||||
|
||||
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|
||||
|---|---|---|---|---|---|---|
|
||||
| Retired Tenant Panel URLs return not found | yes, negative route behavior | N/A | route guardrail | route collection | no | No new UI, route aliases, or redirects |
|
||||
| Workspace-home sidebar stays clean | yes, regression control | Native Filament navigation | navigation | shell, route context, remembered environment context | no | Existing clean-sidebar contract is preserved |
|
||||
| Environment-bound sidebar/resources stay visible | yes, regression control | Native Filament navigation/resources | navigation, resource links | shell, route context, resource URL generation | no | Existing Spec 301 and 303 contracts are preserved |
|
||||
| Global search and operation links avoid `/admin/t` | yes, destination safety | Native Filament/global search plus shared links | search/action links | URL generation | no | No new search surface |
|
||||
|
||||
## Proportionality Review
|
||||
|
||||
- **New source of truth?**: no
|
||||
- **New persisted entity/table/artifact?**: no
|
||||
- **New abstraction?**: no
|
||||
- **New enum/state/reason family?**: no
|
||||
- **New cross-domain UI framework/taxonomy?**: no
|
||||
- **Current operator problem**: Retired Tenant Panel assumptions can make the app appear to support two admin runtimes or can keep stale tests green while canonical workspace/environment routes regress.
|
||||
- **Existing structure is insufficient because**: Existing guard tests are present but distributed; stale route assumptions remain in active tests and high-signal links must be verified as a set.
|
||||
- **Narrowest correct implementation**: Delete only active dead runtime artifacts if found, update stale tests, consolidate guardrails, and run focused route/navigation/search/link validation.
|
||||
- **Ownership cost**: Focused guardrail tests and clearer route/navigation assertions.
|
||||
- **Alternative intentionally rejected**: Compatibility redirects or broad route-helper architecture are rejected because this is a pre-production cleanup with no legacy preservation requirement.
|
||||
- **Release truth**: Current-release cleanup and guardrail hardening.
|
||||
|
||||
### Compatibility posture
|
||||
|
||||
This feature assumes a pre-production environment.
|
||||
|
||||
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope. Canonical replacement is preferred over preservation. Legacy `/admin/t` and `/admin/tenants` route families must not be revived.
|
||||
|
||||
## Testing / Lane / Runtime Impact
|
||||
|
||||
- **Test purpose / classification**: Feature and guardrail.
|
||||
- **Validation lane(s)**: confidence; optional browser smoke if route/navigation runtime changes affect rendered navigation.
|
||||
- **Why this classification and these lanes are sufficient**: Feature and guardrail tests can prove provider absence, route collection absence, 404 behavior, navigation separation, canonical resource reachability, global-search URL safety, operation-link URL safety, and no compatibility alias behavior.
|
||||
- **New or expanded test families**: Focused updates to existing guard and Filament feature tests. No new heavy-governance family.
|
||||
- **Fixture / helper cost impact**: Low. Reuse existing `createUserWithTenant`, `ManagedEnvironment` factories, `WorkspaceContext`, route collection assertions, and resource URL helpers.
|
||||
- **Heavy-family visibility / justification**: none.
|
||||
- **Special surface test profile**: global-context-shell and standard-native-filament.
|
||||
- **Standard-native relief or required special coverage**: Native Filament navigation/resources use feature tests; browser smoke is recommended only if rendered navigation or route registration changes cannot be proven by feature tests alone.
|
||||
- **Reviewer handoff**: Confirm no `/admin/t`, no `/admin/tenants`, no tenant panel provider, no stale blanket-hidden admin contract, no link emission to retired routes, and no weakened RBAC/context coverage.
|
||||
- **Budget / baseline / trend impact**: Low; focused tests only.
|
||||
- **Escalation needed**: none unless implementation finds structural navigation-test coupling.
|
||||
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage if browser smoke runs; otherwise document feature-test substitute.
|
||||
- **Planned validation commands**:
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php`
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Filament/AdminTenantSurfaceParityTest.php tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php`
|
||||
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php`
|
||||
- `git diff --check`
|
||||
|
||||
## User Scenarios & Testing
|
||||
|
||||
### User Story 1 - Retired Tenant Panel runtime cannot boot (Priority: P1)
|
||||
|
||||
As a platform maintainer, I need the retired Tenant Panel provider and panel ID to stay out of the boot path so new features cannot accidentally bind to a second admin runtime.
|
||||
|
||||
**Why this priority**: Provider registration is the highest-signal runtime boundary. If a Tenant Panel provider can boot, route and navigation cleanup is incomplete.
|
||||
|
||||
**Independent Test**: Assert bootstrap providers do not register a Tenant Panel provider, no active provider class exists in app runtime paths, and `Filament::getPanel('tenant')` is absent.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** the application boots, **When** registered providers are inspected, **Then** no Tenant Panel provider is registered.
|
||||
2. **Given** runtime app paths are inspected, **When** Tenant Panel provider classes are searched, **Then** no active provider class remains unless a documented blocker explicitly allowlists it as non-runtime.
|
||||
3. **Given** Filament panels are resolved, **When** the `tenant` panel ID is requested, **Then** no panel is returned.
|
||||
|
||||
---
|
||||
|
||||
### User Story 2 - Legacy route families are unavailable (Priority: P1)
|
||||
|
||||
As a platform maintainer, I need legacy `/admin/t` and `/admin/tenants` entry routes to fail instead of redirecting, aliasing, or preserving old panel semantics.
|
||||
|
||||
**Why this priority**: Route availability is the visible compatibility boundary. This spec must retire old URLs, not preserve them.
|
||||
|
||||
**Independent Test**: Assert the route collection contains no `admin/t` or legacy `admin/tenants` product routes, route names do not carry retired tenant-panel semantics, and direct requests return 404.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** the route collection is loaded, **When** route URIs are inspected, **Then** no active URI starts with `admin/t`.
|
||||
2. **Given** the route collection is loaded, **When** legacy entry URIs are inspected, **Then** no active `/admin/tenants/{environment}` legacy entry route remains.
|
||||
3. **Given** an authenticated workspace/environment user, **When** they request `/admin/t/{environment}` or `/admin/t/{environment}/inventory-items`, **Then** the response is not found.
|
||||
4. **Given** an authenticated workspace/environment user, **When** they request `/admin/tenants/{environment}`, **Then** the response is not found and is not redirected to a canonical route.
|
||||
|
||||
---
|
||||
|
||||
### User Story 3 - Workspace and environment navigation contracts remain precise (Priority: P2)
|
||||
|
||||
As an operator, I need workspace home to stay clean while eligible environment-bound surfaces remain visible inside the selected environment.
|
||||
|
||||
**Why this priority**: Specs 301 and 303 repaired the distinction between workspace-home navigation and environment-bound admin visibility. This cleanup must not regress those contracts.
|
||||
|
||||
**Independent Test**: Render workspace-home and canonical environment routes and assert the expected absence/presence of Inventory, Entra Groups, policy, backup, restore, findings, evidence, review, report, and operations surfaces.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a workspace-home route with remembered environment context, **When** navigation renders, **Then** environment-owned resources are absent.
|
||||
2. **Given** a canonical environment route and an entitled user, **When** navigation renders, **Then** Inventory and Entra Groups remain visible according to Specs 301 and 303.
|
||||
3. **Given** environment-bound resource URLs are generated, **When** their paths are inspected, **Then** they use workspace/environment routes and not `/admin/t`.
|
||||
|
||||
---
|
||||
|
||||
### User Story 4 - Links and search never emit retired routes (Priority: P3)
|
||||
|
||||
As an operator following links from search, operations, dashboards, or notifications, I need destinations to use canonical workspace/environment URLs so I do not land on retired route families.
|
||||
|
||||
**Why this priority**: Hidden link emission can keep old runtime assumptions alive after route definitions are gone.
|
||||
|
||||
**Independent Test**: Exercise high-signal link builders and global-search result URLs and assert no generated URL contains `/admin/t` or old tenant-panel route names.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** Entra Groups global search has an active environment context, **When** result URLs are generated, **Then** URLs point to canonical workspace/environment View routes and do not contain `/admin/t`.
|
||||
2. **Given** `ManagedEnvironmentLinks`, `OperationRunLinks`, and `OperationRunUrl` generate destinations, **When** generated URLs are inspected, **Then** they use canonical workspace or workspace/environment routes.
|
||||
3. **Given** legacy references remain only in historical docs or removal tests, **When** active app code and active tests are searched, **Then** no runtime dependency on retired route emission remains.
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- The Tenant Panel provider class is already absent; implementation must strengthen tests rather than recreate a deletion diff.
|
||||
- Legacy `/admin/tenants/{environment}/provider-connections` tests may represent stale compatibility behavior and must be updated only if repo route truth confirms no active route exists.
|
||||
- Historical docs and old specs mention `/admin/t`; these are allowed and must not be purged.
|
||||
- Test names may mention legacy routes when they explicitly assert removal.
|
||||
- Remembered environment context exists while the user is on workspace home.
|
||||
- A generated route uses a record's environment relation but no explicit `tenant` parameter.
|
||||
- A global-search result is generated after the active environment changes.
|
||||
- Cross-workspace or cross-environment URLs are manipulated manually.
|
||||
|
||||
## Functional Requirements
|
||||
|
||||
- **FR-001**: No active Tenant Panel provider may remain in application provider bootstrap.
|
||||
- **FR-002**: No active Tenant Panel provider class may remain in runtime app code unless an explicit preparation finding documents a temporary blocker and proves it is not registered.
|
||||
- **FR-003**: The application MUST NOT register routes whose URI starts with `admin/t`.
|
||||
- **FR-004**: Retired `/admin/t/{environment}` and `/admin/t/{environment}/...` URLs MUST return not found or equivalent non-match behavior.
|
||||
- **FR-005**: Legacy `/admin/tenants/{environment}` entry URLs MUST remain unavailable unless proven to be current canonical workspace/environment routes.
|
||||
- **FR-006**: The implementation MUST NOT add compatibility redirects, aliases, fallback middleware, or helper shims for retired route families.
|
||||
- **FR-007**: Workspace MUST remain the active Filament admin tenant context; Managed Environment remains a secondary domain context inside a workspace.
|
||||
- **FR-008**: Inventory Items, Inventory Coverage, Entra Groups, Policy, Policy Versions, Backup Sets/Schedules, Restore Runs, Findings, Evidence Snapshots, Environment Reviews, Stored Reports, and applicable Operations MUST remain reachable through canonical workspace/environment routes.
|
||||
- **FR-009**: Workspace-home navigation MUST remain clean and MUST NOT show environment-owned resources without active environment context.
|
||||
- **FR-010**: Environment-bound navigation MUST remain visible only where the product contract permits it, including the Spec 301 Inventory and Spec 303 Entra Groups contracts.
|
||||
- **FR-011**: Tests MUST NOT preserve a blanket rule that all tenant-owned resources are hidden from admin. They MUST distinguish workspace-home hidden from environment-context visible.
|
||||
- **FR-012**: High-signal link builders and global-search destinations MUST NOT emit `/admin/t` URLs.
|
||||
- **FR-013**: Server-side RBAC, workspace isolation, environment scoping, tenant-owned record scoping, capability checks, and global-search scoping MUST remain intact.
|
||||
- **FR-014**: Historical docs, old specs, migration notes, and removal tests MAY mention Tenant Panel or `/admin/t` if clearly historical or removal-focused.
|
||||
- **FR-015**: No Microsoft/provider-specific behavior may move into platform core during cleanup.
|
||||
- **FR-016**: This spec MUST NOT introduce migrations, persisted entities, runtime features, new destructive actions, new assets, or broad localization/terminology cleanup.
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
- **NFR-001**: Filament v5 compatibility must be preserved with Livewire v4.0+; this repo currently uses Filament 5.2.1 and Livewire 4.1.4.
|
||||
- **NFR-002**: Laravel provider registration stays in `apps/platform/bootstrap/providers.php`; providers must not be moved into `bootstrap/app.php`.
|
||||
- **NFR-003**: Globally searchable resources touched by this cleanup must either keep valid View/Edit destinations or disable global search. Entra Groups, Policy, and Policy Versions currently have focused global-search parity coverage.
|
||||
- **NFR-004**: No destructive Filament actions are added. If cleanup touches an existing destructive action indirectly, confirmation and authorization requirements remain unchanged.
|
||||
- **NFR-005**: No assets are added. Deployment asset strategy remains unchanged; the normal Filament asset deployment step remains `cd apps/platform && php artisan filament:assets` when registered assets are deployed.
|
||||
- **NFR-006**: Test additions must stay focused and avoid broad heavy-governance or browser lanes unless rendered navigation changes require browser smoke.
|
||||
|
||||
## Out Of Scope
|
||||
|
||||
- New workspace/environment routing model.
|
||||
- ManagedEnvironment schema/core cutover.
|
||||
- `tenant_id` to `managed_environment_id` migration.
|
||||
- Dual-read, dual-write, route aliases, redirects, or compatibility bridges.
|
||||
- New product navigation or new Directory/Identity features.
|
||||
- Customer portal, Customer Review Workspace, Governance Inbox, OperationRun progress, billing, entitlement, provider, or Microsoft Graph changes.
|
||||
- Migrations, destructive actions, asset changes, broad localization cleanup, or full repository terminology purge.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- **AC-001**: No Tenant Panel provider is registered in active runtime bootstrap.
|
||||
- **AC-002**: No active Tenant Panel provider/runtime class remains, or a narrow documented blocker proves why it is temporarily non-runtime.
|
||||
- **AC-003**: `/admin/t/{environment}` and `/admin/t/{environment}/...` are unavailable and not registered.
|
||||
- **AC-004**: `/admin/tenants/{environment}` legacy entry behavior is unavailable unless proven canonical and non-legacy.
|
||||
- **AC-005**: No redirects, aliases, or middleware shims from retired routes to canonical workspace/environment routes are introduced.
|
||||
- **AC-006**: Workspace-first admin runtime remains functional.
|
||||
- **AC-007**: Canonical environment routes remain functional.
|
||||
- **AC-008**: Inventory remains hidden on workspace home and visible/reachable in environment context.
|
||||
- **AC-009**: Entra Groups remains hidden on workspace home and visible/reachable in environment context according to Spec 303.
|
||||
- **AC-010**: Global-search result URLs and high-signal link builders do not emit `/admin/t`.
|
||||
- **AC-011**: Tests no longer protect stale blanket hidden assumptions for all tenant-owned resources in admin.
|
||||
- **AC-012**: RBAC, workspace isolation, environment scoping, and cross-environment denial remain covered.
|
||||
- **AC-013**: At least one guardrail test fails if Tenant Panel runtime or `/admin/t` routes return.
|
||||
- **AC-014**: No new product surfaces, mutation workflows, provider behavior, migrations, assets, or compatibility layers are introduced.
|
||||
- **AC-015**: Focused tests and `git diff --check` pass. Browser smoke is either passed or explicitly documented as not run with a feature-test substitute.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- A repo search of active runtime paths finds no registered Tenant Panel provider and no active `/admin/t` route definitions.
|
||||
- Route collection tests prove no `/admin/t` route and no legacy tenant-panel route names are active.
|
||||
- Focused navigation tests prove workspace-home cleanliness and environment-bound visibility independently.
|
||||
- Focused link/search tests prove generated destinations use canonical workspace/environment paths.
|
||||
- Implementation close-out reports whether Tenant Panel provider and legacy routes were already absent or removed during the spec.
|
||||
|
||||
## Risks
|
||||
|
||||
- **Risk**: Removing or rewriting stale tests could weaken RBAC coverage.
|
||||
**Mitigation**: Replace blanket hidden assertions with explicit workspace-home, environment-context, no-context, cross-workspace, and cross-environment assertions.
|
||||
- **Risk**: Old route URLs are still emitted by notifications, operation links, or references.
|
||||
**Mitigation**: Inspect high-signal link builders and add targeted no-`/admin/t` assertions.
|
||||
- **Risk**: Historical docs cleanup expands the scope.
|
||||
**Mitigation**: Allow historical mentions and update only current product truth docs if needed.
|
||||
- **Risk**: Cleanup drifts into ManagedEnvironment core cutover.
|
||||
**Mitigation**: No schema work, no model rename, no dual relation cleanup, and no provider-neutral core refactor.
|
||||
|
||||
## Assumptions
|
||||
|
||||
- Specs 301, 302, and 303 are completed or reviewed context packages and must not be rewritten by this preparation work.
|
||||
- The current route truth from Laravel route inspection is authoritative unless implementation discovers a runtime-only route path not visible in the route collection.
|
||||
- The product remains pre-production, so legacy compatibility is not required unless a future spec explicitly changes that posture.
|
||||
- Historical `/admin/t` mentions in old specs and docs are allowed.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- None blocking. If implementation discovers a real active dependency on `/admin/t` or `/admin/tenants`, document the dependency and either remove it within scope or defer it as a narrow blocker instead of adding compatibility behavior.
|
||||
|
||||
## Follow-Up Spec Candidates
|
||||
|
||||
- `navigation-contract-split`: Promote only if tests still conflate workspace-home cleanliness with environment-bound surface visibility after this cleanup.
|
||||
- `governance-artifact-navigation-proof-pass`: Promote only if governance artifacts still need one canonical proof lane for environment navigation after current tests remain distributed.
|
||||
- `alert-delivery-route-rbac-audit`: Promote only if alert delivery becomes part of the tenant-owned/environment-owned navigation repair sequence.
|
||||
- `managed-environment-core-cutover-follow-up`: Promote only if cleanup exposes model/schema-level tenant-core blockers. Do not hide that work inside this spec.
|
||||
161
specs/304-tenant-panel-dead-code-retirement/tasks.md
Normal file
161
specs/304-tenant-panel-dead-code-retirement/tasks.md
Normal file
@ -0,0 +1,161 @@
|
||||
# Tasks: Tenant Panel Dead-Code Retirement
|
||||
|
||||
**Input**: Design documents from `/specs/304-tenant-panel-dead-code-retirement/`
|
||||
**Prerequisites**: `spec.md`, `plan.md`, `checklists/requirements.md`
|
||||
|
||||
**Tests**: Tests are required. This is a runtime cleanup and guardrail change for provider registration, route collection, canonical links, and Filament navigation contracts.
|
||||
|
||||
## Test Governance Checklist
|
||||
|
||||
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
|
||||
- [x] New or changed tests stay in the smallest honest family, and any browser smoke is explicit and justified.
|
||||
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default.
|
||||
- [x] Planned validation commands cover the change without pulling unrelated lane cost.
|
||||
- [x] The declared surface test profile is `global-context-shell` plus `standard-native-filament`.
|
||||
- [x] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.
|
||||
|
||||
## Phase 1: Preparation and Runtime Truth Lock
|
||||
|
||||
**Purpose**: Confirm repo truth before deleting or rewriting anything.
|
||||
|
||||
- [x] T001 Review `specs/304-tenant-panel-dead-code-retirement/spec.md`, `specs/304-tenant-panel-dead-code-retirement/plan.md`, `specs/304-tenant-panel-dead-code-retirement/tasks.md`, and `specs/304-tenant-panel-dead-code-retirement/checklists/requirements.md`.
|
||||
- [x] T002 Review completed context in `specs/301-admin-inventory-navigation-cutover/`, `specs/302-tenant-owned-surface-route-audit/`, and `specs/303-admin-directory-groups-cutover/` without modifying those completed specs.
|
||||
- [x] T003 Inspect `apps/platform/bootstrap/providers.php` and confirm the active providers are admin/system only for Filament runtime.
|
||||
- [x] T004 Inspect `apps/platform/app/Providers/Filament/TenantPanelProvider.php` and `apps/platform/app/Filament/Providers/TenantPanelProvider.php`; if either active runtime file exists, record references before removal.
|
||||
- [x] T005 Inspect `apps/platform/routes/web.php` and the runtime route collection for `admin/t`, `admin/tenants`, tenant-panel route names, and compatibility redirects.
|
||||
- [x] T006 Search `apps/platform/app/`, `apps/platform/bootstrap/`, `apps/platform/routes/`, and `apps/platform/tests/` for `/admin/t`, `/admin/tenants`, `TenantPanelProvider`, `panel: 'tenant'`, `panel: "tenant"`, and `filament.admin.resources.tenants` and classify each hit as historical/removal-test, stale active test, runtime dependency, or link-emission risk.
|
||||
- [x] T007 Confirm no implementation task introduces migrations, models, provider adapters, assets, new product surfaces, destructive actions, route aliases, redirects, or compatibility shims.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: User Story 1 - Retired Tenant Panel runtime cannot boot (Priority: P1)
|
||||
|
||||
**Goal**: Tenant Panel provider/runtime registration is absent and guarded.
|
||||
|
||||
**Independent Test**: Provider bootstrap and Filament panel resolution assertions fail if the retired tenant panel returns.
|
||||
|
||||
- [x] T008 [P] [US1] Update `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php` to assert `apps/platform/bootstrap/providers.php` does not register any Tenant Panel provider class.
|
||||
- [x] T009 [P] [US1] Update `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php` to assert no active Tenant Panel provider class exists at `app/Providers/Filament/TenantPanelProvider.php` or `app/Filament/Providers/TenantPanelProvider.php`.
|
||||
- [x] T010 [P] [US1] Update `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php` to assert `Filament::getPanel('tenant')` remains null.
|
||||
- [x] T011 [US1] If an active Tenant Panel provider class exists and no runtime/test dependency remains, delete `apps/platform/app/Providers/Filament/TenantPanelProvider.php` or `apps/platform/app/Filament/Providers/TenantPanelProvider.php`. Repo truth: no active provider file existed, so no deletion was needed.
|
||||
- [x] T012 [US1] If a Tenant Panel provider cannot be deleted safely, document the narrow blocker in `specs/304-tenant-panel-dead-code-retirement/plan.md` and keep the class unregistered. Repo truth: no blocker existed because no active provider file remained.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 2 - Legacy route families are unavailable (Priority: P1)
|
||||
|
||||
**Goal**: `/admin/t` and legacy `/admin/tenants` route families are not registered, not reachable, and not redirected.
|
||||
|
||||
**Independent Test**: Route collection and HTTP request assertions prove retired route families are absent.
|
||||
|
||||
- [x] T013 [P] [US2] Update `apps/platform/tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php` to assert no route URI begins with `admin/t`.
|
||||
- [x] T014 [P] [US2] Update `apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php` to assert no active product route URI begins with `admin/tenants`.
|
||||
- [x] T015 [P] [US2] Update `apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php` to assert route names do not include retired tenant-panel naming conventions such as `filament.tenant.` or `filament.admin.resources.tenants.`.
|
||||
- [x] T016 [US2] Update `apps/platform/tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php` to assert `/admin/t/{environment}`, `/admin/t/{environment}/inventory-items`, `/admin/tenants`, and `/admin/tenants/{environment}` return not found for an authenticated workspace/environment user.
|
||||
- [x] T017 [US2] Inspect `apps/platform/tests/Feature/ProviderConnections/LegacyRedirectTest.php`; replace any stale expectation that `/admin/tenants/{environment}/provider-connections` redirects with an assertion matching current route truth, or document why it is current canonical behavior.
|
||||
- [x] T018 [US2] Inspect `apps/platform/tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php`, `apps/platform/tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php`, and `apps/platform/tests/Feature/078/LegacyRoutesReturnNotFoundTest.php` and keep only removal-focused legacy route assertions.
|
||||
- [x] T019 [US2] Remove active route definitions or redirects from `apps/platform/routes/web.php` only if T005 finds a confirmed legacy route. Repo truth: no active legacy route or redirect was found, so no route deletion was needed.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 3 - Workspace and environment navigation contracts remain precise (Priority: P2)
|
||||
|
||||
**Goal**: Workspace home stays clean while eligible environment-bound surfaces remain visible and reachable.
|
||||
|
||||
**Independent Test**: Workspace-home and canonical environment tests prove absence/presence independently.
|
||||
|
||||
- [x] T020 [P] [US3] Update `apps/platform/tests/Feature/Filament/PanelNavigationSegregationTest.php` so workspace-home clean navigation and environment-bound visibility are separate assertions, not one blanket admin-hidden rule.
|
||||
- [x] T021 [P] [US3] Update `apps/platform/tests/Feature/Filament/AdminTenantSurfaceParityTest.php` to stop enforcing stale "admin can never see tenant-owned resources" semantics and instead assert canonical environment context where applicable.
|
||||
- [x] T022 [P] [US3] Update `apps/platform/tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php` to preserve workspace-owned/admin-shared surfaces without referencing Tenant Panel compatibility.
|
||||
- [x] T023 [P] [US3] Update `apps/platform/tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php` to preserve server-side environment scoping and cross-environment denial without depending on retired panel routes.
|
||||
- [x] T024 [P] [US3] Verify `apps/platform/tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php` still proves Inventory Coverage uses canonical workspace/environment routes and does not emit `/admin/t`.
|
||||
- [x] T025 [P] [US3] Verify `apps/platform/tests/Feature/Filament/EntraGroupAdminScopeTest.php` still proves Entra Groups are hidden on workspace home, visible in environment context, scoped to the active environment, and do not emit `/admin/t`.
|
||||
- [x] T026 [P] [US3] Verify `apps/platform/tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php` and `apps/platform/tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php` still prove policy search destinations remain canonical and route-safe.
|
||||
- [x] T027 [US3] If navigation runtime code must change, keep edits limited to existing shared helpers such as `apps/platform/app/Support/Navigation/NavigationScope.php`, `apps/platform/app/Support/OperateHub/OperateHubShell.php`, or resource `shouldRegisterNavigation()` methods. Runtime edit stayed limited to `InventoryCoverage::resolveAdminUrlTenant()` so it delegates to the existing panel tenant resolver instead of reading raw panel tenant state.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 4 - Links and search never emit retired routes (Priority: P3)
|
||||
|
||||
**Goal**: High-signal link builders and global-search destinations never generate `/admin/t` or tenant-panel URLs.
|
||||
|
||||
**Independent Test**: Generated URLs from known link builders and search destinations use canonical workspace/environment paths.
|
||||
|
||||
- [x] T028 [P] [US4] Add or update assertions in `apps/platform/tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php` that global-search result URLs do not contain `/admin/t` and resolve to canonical View routes.
|
||||
- [x] T029 [P] [US4] Add or update assertions in `apps/platform/tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php` to prove `OperationRunLinks` and `OperationRunUrl` do not emit `/admin/t`.
|
||||
- [x] T030 [P] [US4] Add or update assertions covering `apps/platform/app/Support/ManagedEnvironmentLinks.php` through an existing workspace/environment routing test such as `apps/platform/tests/Feature/Guards/ManagedEnvironmentCanonicalRouteContractTest.php`. Existing assertions already covered canonical ManagedEnvironment links and were rerun.
|
||||
- [x] T031 [US4] Inspect `apps/platform/app/Support/OperationRunLinks.php`, `apps/platform/app/Support/OpsUx/OperationRunUrl.php`, and `apps/platform/app/Support/ManagedEnvironmentLinks.php`; fix only confirmed active legacy emissions.
|
||||
- [x] T032 [US4] Inspect resource URL helpers in `apps/platform/app/Filament/Resources/InventoryItemResource.php`, `apps/platform/app/Filament/Resources/EntraGroupResource.php`, `apps/platform/app/Filament/Resources/PolicyResource.php`, `apps/platform/app/Filament/Resources/PolicyVersionResource.php`, `apps/platform/app/Filament/Resources/BackupSetResource.php`, `apps/platform/app/Filament/Resources/RestoreRunResource.php`, `apps/platform/app/Filament/Resources/FindingResource.php`, `apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php`, `apps/platform/app/Filament/Resources/EnvironmentReviewResource.php`, `apps/platform/app/Filament/Resources/ReviewPackResource.php`, and `apps/platform/app/Filament/Resources/StoredReportResource.php`; fix only confirmed active legacy emissions. Static search and focused URL tests found no active legacy emissions.
|
||||
- [x] T033 [US4] Keep historical `/admin/t` strings in old specs, docs, and explicit removal tests allowlisted rather than performing a broad docs purge.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Minimal Product Docs
|
||||
|
||||
**Purpose**: Update only current product truth if implementation changes it.
|
||||
|
||||
- [x] T034 Inspect `docs/product/spec-candidates.md` and `docs/product/implementation-ledger.md` after runtime cleanup.
|
||||
- [x] T035 If Tenant Panel runtime is fully retired or already proven absent, add a minimal ledger or candidate note stating that active Tenant Panel runtime and `/admin/t` routes are unavailable and guarded.
|
||||
- [x] T036 Do not rewrite historical specs, historical docs, roadmap sections, or old implementation evidence.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Validation and Close-Out
|
||||
|
||||
**Purpose**: Prove the cleanup and record exact findings.
|
||||
|
||||
- [x] T037 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/NoLegacyTenantPanelRuntimeTest.php tests/Feature/Guards/NoActiveTenantResourceRoutesTest.php tests/Feature/Workspaces/WorkspaceIntendedUrlLegacyRejectionTest.php`.
|
||||
- [x] T038 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/PanelNavigationSegregationTest.php tests/Feature/Filament/AdminTenantSurfaceParityTest.php tests/Feature/Filament/AdminSharedSurfacePanelParityTest.php tests/Feature/Filament/TenantOwnedResourceScopeParityTest.php tests/Feature/Filament/InventoryCoverageAdminTenantParityTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/Filament/PolicyResourceAdminSearchParityTest.php tests/Feature/Filament/PolicyVersionAdminSearchParityTest.php`.
|
||||
- [x] T039 Run `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsDashboardDrillthroughTest.php tests/Feature/Operations/LegacyRunRoutesNotFoundTest.php tests/Feature/ProviderConnections/LegacyRedirectTest.php tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php`.
|
||||
- [x] T040 Run `git diff --check` from `/Users/ahmeddarrazi/Documents/projects/wt-plattform`.
|
||||
- [x] T041 Run browser smoke only if rendered navigation or route registration changes; otherwise document the feature-test substitute in close-out.
|
||||
- [x] T042 Update implementation close-out notes with files changed, provider status, route status, `/admin/tenants` status, route retirement test result, Inventory result, Entra Groups result, global-search/link result, browser smoke result or reason not run, `git diff --check` result, and deferred blockers.
|
||||
|
||||
## Implementation Close-Out Notes
|
||||
|
||||
- Files changed: `apps/platform/app/Filament/Pages/InventoryCoverage.php`; focused guard, Filament, operations, and reference-link tests; `docs/product/implementation-ledger.md`; `docs/product/spec-candidates.md`; this spec task file.
|
||||
- Tenant Panel provider status: already absent before implementation. Guard coverage now checks both active app provider paths, provider bootstrap contents, and `Filament::getPanel('tenant')`.
|
||||
- `/admin/t` route status: already absent before implementation. Guard coverage now checks route collection absence and direct 404s for base and child retired URLs.
|
||||
- `/admin/tenants/{environment}` route status: no active legacy route or redirect was found. Guard and provider-connection tests assert not found with no `Location` header.
|
||||
- Route retirement test result: `NoLegacyTenantPanelRuntimeTest`, `NoActiveTenantResourceRoutesTest`, and `WorkspaceIntendedUrlLegacyRejectionTest` passed.
|
||||
- Inventory contract result: `InventoryCoverageAdminTenantParityTest` and the full focused Filament lane passed after `InventoryCoverage` was changed to use the shared resolver path.
|
||||
- Entra Groups contract result: `EntraGroupAdminScopeTest` and `EntraGroupGlobalSearchScopeTest` passed; generated global-search URLs use canonical workspace/environment View routes and do not contain `/admin/t` or `/admin/tenants`.
|
||||
- Global-search/link result: `ManagedEnvironmentCanonicalRouteContractTest`, `OperationsDashboardDrillthroughTest`, and `PolicyVersionResolvedReferenceLinksTest` passed; high-signal link builders do not emit retired routes.
|
||||
- Browser smoke result: not run. This implementation changed route/provider/link guardrails and one backend URL-context resolver but did not change rendered Filament navigation, forms, actions, assets, or route registration. Feature tests rendered and exercised the relevant workspace/environment navigation and resource pages as the substitute.
|
||||
- `git diff --check`: passed.
|
||||
- Deferred blockers: none.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Phase 1 must complete before any runtime or test edits.
|
||||
- Phase 2 and Phase 3 can run in parallel after Phase 1 if different test files are owned.
|
||||
- Phase 4 depends on classifying stale tests in Phase 1 and should not weaken RBAC/context assertions.
|
||||
- Phase 5 can run in parallel with Phase 4 when link-builder tests are in separate files.
|
||||
- Phase 6 only runs after implementation findings are known.
|
||||
- Phase 7 runs after all in-scope edits are complete.
|
||||
|
||||
## Parallel Execution Examples
|
||||
|
||||
- T008, T009, T010, T013, T014, and T015 can run in parallel if each worker owns separate assertions or coordinates within guard test files.
|
||||
- T020, T021, T022, and T023 can run in parallel if each worker owns the named test file.
|
||||
- T028, T029, and T030 can run in parallel because they target different link/search proof paths.
|
||||
- T024, T025, and T026 are verification tasks and can run independently after related test updates.
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
1. Treat current runtime truth as authoritative.
|
||||
2. Preserve or strengthen removal-focused guard tests.
|
||||
3. Replace stale compatibility or blanket-hidden assertions with precise workspace/environment contracts.
|
||||
4. Fix only active runtime/link emissions found by tests or repo inspection.
|
||||
5. Keep historical docs and completed specs intact.
|
||||
6. Validate with focused tests and document browser-smoke decision.
|
||||
|
||||
## Explicit Non-Goals
|
||||
|
||||
- [x] Do not add `/admin/t` or `/admin/tenants` compatibility aliases.
|
||||
- [x] Do not add redirects from retired route families to canonical workspace/environment routes.
|
||||
- [x] Do not introduce a new route-helper architecture.
|
||||
- [x] Do not migrate schema, models, `tenant_id`, or provider connection ownership.
|
||||
- [x] Do not add product surfaces, navigation features, destructive actions, Graph behavior, jobs, assets, or migrations.
|
||||
- [x] Do not purge historical docs or rewrite completed specs.
|
||||
- [x] Do not weaken RBAC, workspace isolation, environment scoping, or global-search scoping.
|
||||
Loading…
Reference in New Issue
Block a user