TenantAtlas/apps/platform/app/Support/ReviewPublicationResolution/ReviewPublicationResolutionStepAuthorizer.php
ahmido ba7622a158 feat: implement ReviewPublicationResolutionWorkflow (Spec 386) (#457)
## Summary\n- Implements the ReviewPublicationResolutionWorkflow for Spec 386.\n- Adds resolution case/step persistence, policies, services, audit action IDs, and Filament integration.\n- Updates specs, UI/UX documentation, screenshots, and Pest coverage.\n\n## Tests\n- Not run during this handoff; branch was already clean and pushed.\n\n## Target\n- Base: platform-dev\n- Head/topic: 386-review-publication-resolution-workflow-v1

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #457
2026-06-18 21:06:20 +00:00

70 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Support\ReviewPublicationResolution;
use App\Models\ManagedEnvironment;
use App\Models\ReviewPublicationResolutionCase;
use App\Models\ReviewPublicationResolutionStep;
use App\Models\User;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
final class ReviewPublicationResolutionStepAuthorizer
{
public function __construct(
private readonly CapabilityResolver $capabilities,
) {}
public function canExecuteCurrentStep(User $user, ReviewPublicationResolutionCase $case): bool
{
$case->loadMissing(['tenant', 'steps.operationRun']);
$tenant = $case->tenant;
$step = $case->currentStep();
if (! $tenant instanceof ManagedEnvironment || ! $step instanceof ReviewPublicationResolutionStep) {
return false;
}
return $this->canExecuteStep($user, $tenant, $step);
}
public function canExecuteStep(User $user, ManagedEnvironment $tenant, ReviewPublicationResolutionStep $step): bool
{
$capability = $this->requiredCapability($step);
return is_string($capability) && $this->capabilities->can($user, $tenant, $capability);
}
public function requiredCapability(ReviewPublicationResolutionStep $step): ?string
{
$stepKey = $step->stepKeyEnum();
return match ($stepKey) {
ReviewPublicationResolutionStepKey::CompleteRequiredReports => $this->requiredReportCapability($step),
ReviewPublicationResolutionStepKey::CollectEvidenceSnapshot => Capabilities::EVIDENCE_MANAGE,
ReviewPublicationResolutionStepKey::RefreshReviewComposition,
ReviewPublicationResolutionStepKey::GenerateReviewPack,
ReviewPublicationResolutionStepKey::ReturnToPublication => Capabilities::ENVIRONMENT_REVIEW_MANAGE,
ReviewPublicationResolutionStepKey::ValidateReviewReadiness,
null => null,
};
}
private function requiredReportCapability(ReviewPublicationResolutionStep $step): ?string
{
$missingDimensions = array_values(array_filter(
(array) data_get($step->summary, 'missing_report_dimensions', []),
static fn (mixed $dimension): bool => is_string($dimension) && trim($dimension) !== '',
));
return match ((string) ($missingDimensions[0] ?? '')) {
'permission_posture' => Capabilities::PROVIDER_RUN,
'entra_admin_roles' => Capabilities::ENTRA_ROLES_MANAGE,
default => null,
};
}
}