4.6 KiB
4.6 KiB
Quickstart: Spec 136 Admin Panel Canonical Tenant Resolution Full Rollout
Goal
Finish the canonical tenant rollout for workspace-admin flows, preserve tenant-panel-native behavior, and leave the feature ready for small, test-driven implementation slices.
Expected implementation slices
- Freeze the final rollout manifest and classify surfaces as Type A, Type B, or Type C.
- Standardize canonical admin resolver usage through
OperateHubShell. - Roll out
CanonicalAdminTenantFilterStateacross persisted tenant-filter surfaces. - Deliver Wave 1 high-risk tenant-sensitive resource fixes.
- Deliver Wave 2 governance, restore, and inventory alignment.
- Deliver Wave 3 workspace-wide tenant-default, diagnostics, search parity, and guard expansion.
- Finish with direct filter-state tests, regression coverage, and manual tenant-switch verification.
Recommended implementation order
- Update the rollout manifest and guard file list first.
- Normalize support-layer resolver and filter-state usage before touching individual resources.
- Fix one high-risk resource family at a time and run focused tests after each slice.
- Align widget and page pairs together instead of fixing them independently.
- Finish with global-search parity, guard expansion, and developer guidance.
Focused verification commands
Run all commands from the repository root.
vendor/bin/sail artisan test --compact tests/Feature/Guards/AdminTenantResolverGuardTest.php
vendor/bin/sail artisan test --compact tests/Feature/Filament/TableStatePersistenceTest.php
vendor/bin/sail artisan test --compact --filter='CanonicalAdminTenantFilterState|PolicyResource|BackupSchedule|BackupSet|FindingResource|BaselineCompareLanding|RestoreRunResource|InventoryItemResource|PolicyVersionResource|ProviderConnectionResource|TenantDiagnostics|InventoryCoverage|InventoryKpiHeader|AuditLog|EntraGroup'
vendor/bin/sail bin pint --dirty --format agent
Manual tenant-switch verification per wave
Wave 1
- Select Tenant A in the workspace-admin shell.
- Visit representative Type A surfaces in Wave 1 and confirm header context, table/query results, and sensitive actions align.
- Switch to Tenant B and confirm stale tenant filters are cleared or reseeded before data renders.
Wave 2
- Re-check inventory and governance pages plus their embedded widgets.
- Confirm widget KPIs, page summaries, record links, and detail pages remain aligned after a tenant switch.
- Validate that shared resources preserve tenant-panel behavior under
/admin/t/{tenant}/....
Wave 3
- Re-check workspace-wide datasets with tenant-default behavior.
- Confirm base dataset stays workspace-wide while header tenant, filter defaults, deep links, and persisted filters update to the new canonical admin tenant.
- Verify admin search and direct links remain tenant-safe or explicitly disabled where planned.
Scenario matrix to cover in tests
Type A hard tenant-sensitive surfaces
- header tenant, query tenant, widget tenant, and action tenant all match
- no valid canonical tenant produces the defined safe no-tenant-selected behavior
- wrong-tenant sensitive actions are blocked safely
Type B workspace-wide tenant-default surfaces
- base dataset remains workspace-wide
- tenant-default header, filter state, and deep links align to the canonical admin tenant
- stale persisted tenant filters are cleared or reseeded after a tenant switch
Shared panel-aware resources
- admin panel uses the canonical admin tenant rule
- tenant panel preserves panel-native
Filament::getTenant()behavior - direct URLs and search paths do not bypass list parity
Guardrail
- a new raw
Filament::getTenant()orTenant::current()read in a guarded admin file fails CI - approved tenant-panel-native exception files remain explicitly allowed
Future-surface developer rule
- New
/admin/...tenant-sensitive surfaces must resolve tenant context throughOperateHubShellorapp/Filament/Concerns/ResolvesPanelTenantContext.php. - Shared resources must keep tenant-panel behavior panel-native and must not let remembered admin context override
/admin/t/{tenant}/.... - Any list surface that uses
persistFiltersInSession()and tenant-derived defaults must callCanonicalAdminTenantFilterState::sync()before render. - If global search cannot be kept list/detail-safe in admin context, disable it explicitly instead of relying on implicit scoping.
Out of scope during implementation
- dependency or asset changes
- panel bootstrap or routing redesign
- unrelated CLI, queue, or scheduled-context resolver refactors
- broad stylistic rewrites of tenant-panel resources that are already correct