TenantAtlas/specs/136-admin-canonical-tenant/quickstart.md
2026-03-12 23:26:32 +01:00

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

  1. Freeze the final rollout manifest and classify surfaces as Type A, Type B, or Type C.
  2. Standardize canonical admin resolver usage through OperateHubShell.
  3. Roll out CanonicalAdminTenantFilterState across persisted tenant-filter surfaces.
  4. Deliver Wave 1 high-risk tenant-sensitive resource fixes.
  5. Deliver Wave 2 governance, restore, and inventory alignment.
  6. Deliver Wave 3 workspace-wide tenant-default, diagnostics, search parity, and guard expansion.
  7. Finish with direct filter-state tests, regression coverage, and manual tenant-switch verification.
  1. Update the rollout manifest and guard file list first.
  2. Normalize support-layer resolver and filter-state usage before touching individual resources.
  3. Fix one high-risk resource family at a time and run focused tests after each slice.
  4. Align widget and page pairs together instead of fixing them independently.
  5. 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() or Tenant::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 through OperateHubShell or app/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 call CanonicalAdminTenantFilterState::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