2.6 KiB
Data Model: RBAC UI Enforcement Helper v2
Branch: 066-rbac-ui-enforcement-helper-v2
Date: 2026-01-30
Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas-066-rbac-ui-enforcement-helper-v2/specs/066-rbac-ui-enforcement-helper/spec.md
Overview
This feature does not introduce new database tables. It defines contracts and behaviors that compose existing tenant-plane RBAC (membership + capability gates) into consistent Filament UI states across tenant-scoped and record-scoped surfaces.
Entities (existing)
Tenant
The isolation boundary for all tenant-plane actions.
Identity
tenants.id(PK)- A user is a “member” if
user->canAccessTenant($tenant)is true.
User
Authenticated tenant-plane actor.
Key behaviors
- Must support membership checks (
canAccessTenant($tenant)). - Capability checks are performed via Gates/Policies using
Capabilities::*identifiers.
TenantMembership
Joins a User to a Tenant with a role mapped to capabilities (Feature 065).
Key behaviors
- Role → capabilities mapping is centralized and deterministic.
- Requests should avoid repeated membership DB queries (request-scope cache).
Capability (registry)
Canonical capability keys live in app/Support/Auth/Capabilities.php and must be referenced via constants (Capabilities::*).
Entities (conceptual, not persisted)
UiEnforcementContext
Context used to evaluate membership/capability for an action.
Fields
user: current authenticated user (or null)tenantResolver: one of:tenantFromFilament(tenant-scoped)tenantFromRecord(record == tenant)tenantFrom(callable)(record → tenant mapping)
record: optional record for table/record actionscapability: required capability identifier (fromCapabilities::*)
UiEnforcementDecision
The derived UI behavior applied to a Filament action.
Fields
isVisible: boolean (non-members must not be able to discover actions)isEnabled: boolean (members without capability see disabled action)disabledTooltip: string (standardized viaUiTooltips)requiresConfirmation: boolean (destructive/high-impact actions)
BulkSelectionAuthorization (preflight)
Derived authorization status for a bulk action selection.
Fields
selectedIds: list of record IDsresolvedTenants: list of tenant IDs derived via tenant resolver (record == tenant or mapping)unauthorizedCount: count of records failing authorization (determines all-or-nothing disable)ineligibleCount: optional count of business-ineligible records (may be skipped with deterministic feedback; does not affect authorization disable by default)