# Quickstart: 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`

## Local setup

1. Start the app stack:
   - `./vendor/bin/sail up -d`
2. Install dependencies (if needed):
   - `./vendor/bin/sail composer install`

## Recipes (once implemented)

> Scope: Tenant plane only (`/admin/t/{tenant}`). Platform plane (`/system`) is out of scope.

### Tenant-scoped action (default tenant from Filament)

- Use `UiEnforcement` with the required `Capabilities::*` constant.
- Non-members should never see the action (routing already denies them).
- Members without capability see a disabled action + standard tooltip.

### Mixed visibility (business visibility + RBAC)

- If the surface already has business visibility rules, use composition:
  - **Tenant-scoped**: you may use `preserveVisibility()` to keep existing visibility closures unchanged.
  - **Record-scoped / cross-tenant lists**: do not use `preserveVisibility()`; instead use `andVisibleWhen(...)` / `andHiddenWhen(...)` so non-members cannot discover actions.

### Record-scoped tenant (record == tenant)

- Configure enforcement with `tenantFromRecord()` so membership/capability checks are evaluated per row/record tenant.
- Non-members must be deny-as-not-found (404) on direct access/execution attempts.

### Bulk actions (authorization-only all-or-nothing)

- Use bulk preflight to disable the action if any selected record is unauthorized.
- Keep business eligibility separate (e.g., skip inactive/archived records with deterministic feedback).

## Notes on Filament execution semantics

- Hidden actions do not execute (silent no-op). This is acceptable for the non-member contract.
- Disabled actions do not execute (silent no-op). This is acceptable for member-without-capability.
- Server-side authorization remains required (UI is not security). Where reachable:
  - Non-member: deny-as-not-found (404)
  - Member without capability: 403

## Manual QA checklist (once implemented)

- Log in as a tenant member without the capability:
  - Action visible but disabled, with tooltip “Insufficient permission — ask a tenant Owner.”
  - Clicking does not execute.
- Remove membership:
  - Action hidden; direct access returns 404.
- Bulk selection with mixed authorization:
  - Bulk action is disabled; no partial execution.

## Test run (once implemented)

- `./vendor/bin/sail bin pint --dirty`
- `./vendor/bin/sail artisan test tests/Feature/Guards --compact`
- `./vendor/bin/sail artisan test tests/Feature/Filament --compact`
- `./vendor/bin/sail artisan test tests/Feature/Rbac --compact`
