Files
saqel/backend/app/Services/VideoReviewReportValidator.php
T

45 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services;
/** A human approval must not silently override missing or blocking findings. */
final class VideoReviewReportValidator
{
public static function approvable(array $report): bool
{
$coverage = $report['coverage'] ?? null;
if (!is_array($coverage) || ($coverage['truncated'] ?? true) !== false ||
!array_key_exists('unprocessed_intervals', $coverage) || $coverage['unprocessed_intervals'] !== [] ||
!is_array($coverage['section_results'] ?? null) || $coverage['section_results'] === [] ||
!is_array($coverage['objective_results'] ?? null) || $coverage['objective_results'] === [] ||
($report['missing_inputs'] ?? null) !== [] || !is_array($report['issues'] ?? null)) {
return false;
}
foreach (['section_results', 'objective_results'] as $field) {
foreach ($coverage[$field] as $result) {
if (!is_array($result) || !in_array($result['status'] ?? null, ['covered', 'out_of_declared_scope'], true)) {
return false;
}
if (($result['status'] ?? '') === 'covered' &&
empty($result['evidence_refs']) && empty($result['evidence_ref'])) {
return false;
}
if (($result['status'] ?? '') === 'out_of_declared_scope' &&
trim((string)($result['reason'] ?? '')) === '') {
return false;
}
}
}
foreach ($report['issues'] as $issue) {
if (!is_array($issue) ||
(in_array($issue['severity'] ?? null, ['critical', 'major'], true) &&
(($issue['resolution_status'] ?? '') !== 'resolved' ||
trim((string)($issue['resolution_evidence'] ?? '')) === ''))) {
return false;
}
}
return true;
}
}