## Summary - introduce a canonical admin tenant filter-state helper and route all in-scope workspace-admin tenant resolution through `OperateHubShell::activeEntitledTenant()` - align operations monitoring, operation-run deep links, Entra group admin list/view/search behavior, and shared context-bar rendering with the documented scope contract - add the Spec 135 design artifacts, architecture note, focused guardrail coverage, and non-regression tests for filter persistence, direct-record access, and global search safety ## Validation - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact tests/Feature/Monitoring/OperationsKpiHeaderTenantContextTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php tests/Feature/Spec085/OperationsIndexHeaderTest.php tests/Feature/Spec085/RunDetailBackAffordanceTest.php tests/Feature/Filament/OperationRunListFiltersTest.php tests/Feature/Filament/EntraGroupAdminScopeTest.php tests/Feature/Filament/EntraGroupGlobalSearchScopeTest.php tests/Feature/DirectoryGroups/BrowseGroupsTest.php tests/Feature/Filament/EntraGroupEnterpriseDetailPageTest.php tests/Feature/Filament/PolicyVersionResolvedReferenceLinksTest.php tests/Feature/Filament/EntraGroupResolvedReferencePresentationTest.php tests/Feature/Guards/AdminTenantResolverGuardTest.php tests/Feature/OpsUx/OperateHubShellTest.php tests/Feature/Filament/Alerts/AlertsKpiHeaderTest.php tests/Feature/Alerts/AlertDeliveryDeepLinkFiltersTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/Filament/TableStatePersistenceTest.php tests/Feature/Filament/TenantScopingTest.php tests/Feature/Filament/Alerts/AlertDeliveryViewerTest.php tests/Unit/Support/References/CapabilityAwareReferenceResolverTest.php` ## Notes - Filament v5 remains on Livewire v4.0+ compliant surfaces only. - No provider registration changes were needed; Laravel 12 provider registration remains in `bootstrap/providers.php`. - Entra group global search remains enabled and is now scoped to the canonical admin tenant contract. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #164
121 lines
4.2 KiB
YAML
121 lines
4.2 KiB
YAML
version: 1
|
|
feature: 135-canonical-tenant-context-resolution
|
|
title: Canonical Tenant Context Resolution Matrix
|
|
type: internal-behavior-contract
|
|
|
|
canonical_rules:
|
|
tenant_panel:
|
|
source_of_truth: Filament::getTenant()
|
|
fallback_behavior: none
|
|
notes:
|
|
- Tenant-panel-native routes keep panel semantics.
|
|
- Remembered admin tenant state must not override tenant-panel context.
|
|
workspace_admin:
|
|
source_of_truth: App\Support\OperateHub\OperateHubShell::activeEntitledTenant
|
|
priority_order:
|
|
- entitled_filament_tenant
|
|
- entitled_remembered_workspace_tenant
|
|
- none
|
|
no_context_outcome_by_surface:
|
|
operations_monitoring_index: workspace_scoped_all_tenants_state_with_no_tenant_default_filter_and_no_tenant_only_kpis
|
|
tenantless_operation_run_detail: render_only_if_workspace_scope_and_tenant_entitlement_still_pass_otherwise_not_found
|
|
admin_entra_group_list_and_view: not_found
|
|
admin_entra_group_global_search: no_results_for_tenant_owned_records
|
|
|
|
request_states:
|
|
remembered_only:
|
|
filament_tenant: null
|
|
remembered_tenant: entitled
|
|
resolved_source: remembered
|
|
filament_only:
|
|
filament_tenant: entitled
|
|
remembered_tenant: null
|
|
resolved_source: filament
|
|
conflict:
|
|
filament_tenant: entitled
|
|
remembered_tenant: entitled_and_different
|
|
resolved_source: filament
|
|
no_context:
|
|
filament_tenant: null_or_not_entitled
|
|
remembered_tenant: null_or_not_entitled
|
|
resolved_source: none
|
|
|
|
surfaces:
|
|
- name: operations_monitoring_index
|
|
route: /admin/operations
|
|
panel: admin
|
|
expectations:
|
|
- header_scope_label_matches_resolved_tenant
|
|
- kpi_cards_match_resolved_tenant
|
|
- table_query_matches_resolved_tenant
|
|
- filter_defaults_match_resolved_tenant
|
|
- no_context_renders_workspace_scoped_all_tenants_state
|
|
- no_context_clears_tenant_default_filters
|
|
- no_context_hides_tenant_only_kpi_behavior
|
|
|
|
- name: tenantless_operation_run_detail
|
|
route: /admin/operations/{run}
|
|
panel: admin
|
|
expectations:
|
|
- authorization_uses_workspace_and_tenant_entitlement
|
|
- detail_visibility_is_not_broader_than_index_scope
|
|
- navigation_labels_use_same_resolved_tenant_as_admin_shell
|
|
- no_context_renders_only_when_workspace_scope_and_tenant_entitlement_still_pass
|
|
- no_context_otherwise_returns_not_found
|
|
|
|
- name: operation_run_filters
|
|
route: /admin/operations with persisted table filters
|
|
panel: admin
|
|
expectations:
|
|
- tenant_filter_options_do_not_exceed_list_scope
|
|
- tenant_filter_default_uses_resolved_tenant
|
|
- persisted_tenant_sensitive_values_are_revalidated_per_request
|
|
|
|
- name: entra_group_list_and_view
|
|
route: /admin/.../groups and /admin/.../groups/{record}
|
|
panel: mixed
|
|
expectations:
|
|
- tenant_panel_routes_use_panel_native_tenant
|
|
- admin_sensitive_access_paths_use_explicit_scope_rule
|
|
- direct_record_resolution_matches_list_scope
|
|
- admin_no_context_returns_not_found
|
|
- out_of_scope_access_returns_not_found
|
|
|
|
- name: entra_group_global_search
|
|
route: global-search
|
|
panel: mixed
|
|
expectations:
|
|
- search_results_follow_same_scope_as_list_and_detail
|
|
- non_members_receive_no_hints
|
|
- admin_no_context_returns_no_tenant_owned_results
|
|
- resource_search_is_disabled_if_scope_parity_cannot_be_guaranteed
|
|
|
|
- name: alert_delivery_reference_pattern
|
|
route: /admin/alert-deliveries
|
|
panel: admin
|
|
expectations:
|
|
- existing_admin_query_and_filter_alignment_is_preserved
|
|
- resource_remains_non_regression_reference
|
|
|
|
authorization_contract:
|
|
non_member_or_out_of_scope:
|
|
response: not_found
|
|
member_missing_capability:
|
|
response: forbidden
|
|
|
|
guardrail:
|
|
purpose: prevent_new_admin_panel_raw_panel_native_tenant_reads
|
|
forbidden_patterns:
|
|
- Filament::getTenant()
|
|
- Tenant::current()
|
|
enforced_in:
|
|
- app/Filament/Pages/Monitoring
|
|
- app/Filament/Pages/Operations
|
|
- app/Filament/Resources
|
|
- app/Filament/Widgets/Operations
|
|
allowed_exceptions:
|
|
- app/Filament/Pages/ChooseTenant.php
|
|
- app/Http/Controllers/SelectTenantController.php
|
|
- app/Support/Middleware/EnsureFilamentTenantSelected.php
|
|
- app/Filament/Resources/EntraGroupResource.php
|