TenantAtlas/app/Services/PermissionPosture/PostureScoreCalculator.php
ahmido ef380b67d1 feat(104): Provider Permission Posture (#127)
Implements Spec 104: Provider Permission Posture.

What changed
- Generates permission posture findings after each tenant permission compare (queued)
- Stores immutable posture snapshots as StoredReports (JSONB payload)
- Adds global Finding resolved lifecycle (`resolved_at`, `resolved_reason`) with `resolve()` / `reopen()`
- Adds alert pipeline event type `permission_missing` (Alerts v1) and Filament option for Alert Rules
- Adds retention pruning command + daily schedule for StoredReports
- Adds badge mappings for `resolved` finding status and `permission_posture` finding type

UX fixes discovered during manual verification
- Hide “Diff” section for non-drift findings (only drift findings show diff)
- Required Permissions page: “Re-run verification” now links to Tenant view (not onboarding)
- Preserve Technical Details `<details>` open state across Livewire re-renders (Alpine state)

Verification
- Ran `vendor/bin/sail artisan test --compact --filter=PermissionPosture` (50 tests)
- Ran `vendor/bin/sail artisan test --compact --filter="FindingResolved|FindingBadge|PermissionMissingAlert"` (20 tests)
- Ran `vendor/bin/sail bin pint --dirty`

Filament v5 / Livewire v4 compliance
- Filament v5 + Livewire v4: no Livewire v3 usage.

Panel provider registration (Laravel 11+)
- No new panels added. Existing panel providers remain registered via `bootstrap/providers.php`.

Global search rule
- No changes to global-searchable resources.

Destructive actions
- No new destructive Filament actions were added in this PR.

Assets / deploy notes
- No new Filament assets registered. Existing deploy step `php artisan filament:assets` remains unchanged.

Test coverage
- New/updated Pest feature tests cover generator behavior, job integration, alerting, retention pruning, and resolved lifecycle.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #127
2026-02-21 22:32:52 +00:00

42 lines
1008 B
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace App\Services\PermissionPosture;
/**
* Calculates a normalized posture score (0100) from a permission comparison result.
*
* Pure function: no side effects, no DB access.
*/
final class PostureScoreCalculator
{
/**
* @param array{permissions: array<int, array{status: string, ...}>, ...} $permissionComparison
*/
public function calculate(array $permissionComparison): int
{
$permissions = $permissionComparison['permissions'] ?? [];
if (! is_array($permissions)) {
return 100;
}
$requiredCount = count($permissions);
if ($requiredCount === 0) {
return 100;
}
$grantedCount = 0;
foreach ($permissions as $permission) {
if (is_array($permission) && ($permission['status'] ?? null) === 'granted') {
$grantedCount++;
}
}
return (int) round($grantedCount / $requiredCount * 100);
}
}