TenantAtlas/specs/136-admin-canonical-tenant/quickstart.md
ahmido 45a804970e feat: complete admin canonical tenant rollout (#165)
## Summary
- complete Spec 136 canonical admin tenant rollout across admin-visible and shared Filament surfaces
- add the shared panel-aware tenant resolver helper, persisted filter-state synchronization, and admin navigation segregation for tenant-sensitive resources
- expand regression, guard, and parity coverage for admin-path tenant resolution, stale filters, workspace-wide tenant-default surfaces, and panel split behavior

## Validation
- `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`

## Notes
- Livewire v4.0+ compliance is preserved with Filament v5.
- Provider registration remains unchanged in `bootstrap/providers.php`.
- `PolicyResource` and `PolicyVersionResource` have admin global search disabled explicitly; `EntraGroupResource` keeps admin-aware scoped search with a View page.
- Destructive and governance-sensitive actions retain existing confirmation and authorization behavior while using canonical tenant parity.
- No new assets were introduced, so deployment asset strategy is unchanged and does not add new `filament:assets` work.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #165
2026-03-13 08:09:20 +00:00

94 lines
4.6 KiB
Markdown

# 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.
## Recommended implementation order
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.
```bash
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