## 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
7.1 KiB
Data Model: Spec 136 Admin Panel Canonical Tenant Resolution Full Rollout
Overview
This feature introduces no new database tables or persisted business objects. Its data model is request-time and behavioral: it formalizes how surface classification, panel mode, canonical admin tenant context, session-backed filter state, and sensitive actions combine into one deterministic tenant outcome.
Entity: Surface Inventory Entry
Purpose: Represents one admin-visible or admin-reachable surface in the rollout manifest.
Fields:
surface_nameclass_namesurface_kindenum:resource,page,widget,shared_helper,guarded_fileclassificationenum:type_a,type_b,type_cvisibility_modeenum:admin_visible,shared_code_path,tenant_panel_only_but_reviewedhas_persisted_tenant_filtersbooleanhas_global_searchbooleanhas_sensitive_actionsbooleanguard_requiredboolean
Relationships:
- may reference one resource, page, or widget class
- may depend on one or more support-layer resolver or filter-state helpers
Validation rules:
- Every rollout surface must have exactly one classification.
- Type A and Type B surfaces must be guard-covered unless explicitly documented as an exception.
- Type C surfaces must not acquire hidden tenant enforcement in read or write paths.
Entity: Canonical Admin Tenant Context
Purpose: Represents the single tenant context used by workspace-admin tenant-sensitive flows.
Source fields:
workspace_idpanel_idroute_tenant_idnullablefilament_tenant_idnullableremembered_tenant_idnullableresolved_tenant_idnullableresolution_sourceenum:route,filament,remembered,noneis_entitledboolean
Relationships:
- belongs to one current workspace
- may resolve to one entitled tenant
- drives header context, queries, filter defaults, widgets, links, and sensitive actions for Type A and Type B admin surfaces
Validation rules:
resolved_tenant_idmust be null when no entitled tenant exists.- The same resolved tenant must drive every tenant-sensitive element of the same admin surface.
- When the panel is admin, raw panel-native tenant reads are not valid substitutes for this entity.
Entity: Panel Resolver Contract
Purpose: Encodes which resolver is allowed in a given panel mode.
Fields:
panel_idallowed_sourceenum:operate_hub_shell,filament_tenant,nonefallback_behaviorenum:remembered_allowed,no_fallback,safe_noneapplies_toenum:admin,tenant,shared_surface
Validation rules:
- Admin panel uses
operate_hub_shell. - Tenant panel uses
filament_tenant. - Shared surfaces must branch by current panel rather than blending both rules.
Entity: Persisted Tenant Filter Session State
Purpose: Represents session-backed filter state whose validity depends on the current canonical admin tenant.
Fields:
filters_session_keytenant_sensitive_filtersarrayprevious_resolved_tenant_idnullablecurrent_resolved_tenant_idnullableresolution_actionenum:apply,reseed,clearhas_invalid_valuesboolean
Relationships:
- belongs to one table or page surface
- depends on one
Canonical Admin Tenant Context
Validation rules:
- Tenant-sensitive filter values must be cleared or reseeded when resolved tenant changes.
- If
current_resolved_tenant_idis null, tenant-specific filter state must not remain active. - Workspace-wide Type B surfaces may preserve non-tenant filters while clearing or reseeding tenant-specific ones.
Entity: Sensitive Action Scope Contract
Purpose: Represents the tenant parity requirement between visible surface context and a sensitive action target.
Fields:
surface_nameaction_namevisible_tenant_idnullablequery_tenant_idnullableaction_tenant_idnullableauthorization_outcomeenum:ok,not_found,forbiddenconfirmation_requiredboolean
Relationships:
- belongs to one rollout surface
- depends on one resolved tenant context and one authorization decision
Validation rules:
action_tenant_idmust equalvisible_tenant_idfor Type A surfaces.- Out-of-scope or missing tenant access must remain
not_foundwhen membership is not established. - Existing destructive-like actions must still require confirmation and server-side authorization.
Entity: Search and Record Resolution Contract
Purpose: Represents list, detail, deep-link, and global-search parity for tenant-sensitive resources.
Fields:
surface_nameaccess_pathenum:list,detail,direct_url,deep_link,global_searchpanel_modeenum:admin,tenantresolved_tenant_idnullablerecord_tenant_idnullableparity_outcomeenum:aligned,disabled,not_found,forbidden
Validation rules:
- Detail and direct access must never be broader than list scope.
- Global search must either match list/detail parity or be disabled.
- Admin no-context behavior must be explicit and deterministic per surface class.
Entity: Guard Coverage Entry
Purpose: Documents whether a file is enforced by the admin tenant resolver guard or allowed as an exception.
Fields:
relative_pathsurface_nameguard_statusenum:guarded,exceptionexception_reasonnullablereview_owner
Validation rules:
- Exceptions must be explicit and stable.
- Admin-only files are not valid exceptions for raw
Filament::getTenant()orTenant::current()reads. - Guard output must clearly distinguish true violations from approved tenant-panel-native usage.
State Transitions
Canonical admin tenant state
none
- No entitled route, Filament, or remembered tenant is available.
- Outcome: safe no-tenant-selected behavior by surface type.
remembered
- Only remembered tenant is valid and entitled.
- Outcome: remembered tenant becomes the canonical admin tenant for the full request.
filament
- A Filament tenant is valid and entitled.
- Outcome: Filament tenant becomes the canonical admin tenant for the full request.
route
- A route tenant parameter is present and entitled for a tenant-panel or shared route.
- Outcome: route tenant governs the request where panel-native semantics apply.
Persisted filter synchronization state
unchanged
- Previous and current resolved tenant IDs match.
- Outcome: persisted tenant filter values may remain.
tenant_switched
- Previous and current resolved tenant IDs differ.
- Outcome: tenant-sensitive filter values are cleared or reseeded.
tenant_removed
- Current resolved tenant ID becomes null.
- Outcome: tenant-sensitive filter values are cleared.
Invariants
- One workspace-admin surface uses one tenant source for every tenant-sensitive element.
- Shared resources must branch by panel mode instead of mixing admin and tenant rules inside one execution path.
- Persisted tenant filter state is never trusted without synchronization.
- Search, list, detail, and deep-link behavior cannot exceed the same tenant boundary.
- Existing destructive or governance-sensitive actions keep their confirmations and authorization while gaining tenant-target parity.