TenantAtlas/app/Services/Auth/RoleCapabilityMap.php
ahmido 9f5c99317b Fix Review Pack generation UX + notifications (#133)
## Summary
- Fixes misleading “queued / running in background” message when Review Pack generation request reuses an existing ready pack (fingerprint dedupe).
- Improves resilience of Filament/Livewire interactions by ensuring the Livewire intercept shim applies after Livewire initializes.
- Aligns Review Pack operation notifications with Ops-UX patterns (queued + completed notifications) and removes the old ReviewPackStatusNotification.

## Key Changes
- Review Pack generate action now:
  - Shows queued toast only when a new pack is actually created/queued.
  - Shows a “Review pack already available” success notification with a link when dedupe returns an existing pack.

## Tests
- `vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/ReviewPackGenerationTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/ReviewPackResourceTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/LivewireInterceptShimTest.php`

## Notes
- No global search behavior changes for ReviewPacks (still excluded).
- Destructive actions remain confirmation-gated (`->requiresConfirmation()`).

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #133
2026-02-23 19:42:52 +00:00

151 lines
4.2 KiB
PHP

<?php
namespace App\Services\Auth;
use App\Support\Auth\Capabilities;
use App\Support\TenantRole;
/**
* Role to Capability Mapping (Single Source of Truth)
*
* This class defines which capabilities each role has.
* All capability strings MUST be references from the Capabilities registry.
*/
class RoleCapabilityMap
{
private static array $roleCapabilities = [
TenantRole::Owner->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_MANAGE,
Capabilities::TENANT_DELETE,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_MEMBERSHIP_MANAGE,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_ROLE_MAPPING_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_MANAGE,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::ENTRA_ROLES_MANAGE,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::REVIEW_PACK_MANAGE,
],
TenantRole::Manager->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_MANAGE,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_BACKUP_SCHEDULES_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_MANAGE,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::ENTRA_ROLES_MANAGE,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::REVIEW_PACK_MANAGE,
],
TenantRole::Operator->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::REVIEW_PACK_VIEW,
],
TenantRole::Readonly->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::PROVIDER_VIEW,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::REVIEW_PACK_VIEW,
],
];
/**
* Get all capabilities for a given role
*
* @return array<string>
*/
public static function getCapabilities(TenantRole|string $role): array
{
$roleValue = $role instanceof TenantRole ? $role->value : $role;
return self::$roleCapabilities[$roleValue] ?? [];
}
/**
* Get all role values that grant a given capability.
*
* @return array<string>
*/
public static function rolesWithCapability(string $capability): array
{
$roles = [];
foreach (self::$roleCapabilities as $role => $capabilities) {
if (in_array($capability, $capabilities, true)) {
$roles[] = $role;
}
}
return $roles;
}
/**
* Check if a role has a specific capability
*/
public static function hasCapability(TenantRole|string $role, string $capability): bool
{
return in_array($capability, self::getCapabilities($role), true);
}
}