Harden published curriculum and student flows
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
/** Structural coverage gate. Content accuracy still requires academic review. */
|
||||
final class VideoCoverageValidator
|
||||
{
|
||||
public static function valid(array $coverage, int $durationSeconds, string $videoSha256): bool
|
||||
{
|
||||
if ($durationSeconds <= 0 || $durationSeconds > 4 * 60 * 60 ||
|
||||
!preg_match('/^[0-9a-f]{64}$/i', $videoSha256) ||
|
||||
!hash_equals(strtolower($videoSha256), strtolower((string)($coverage['video_sha256'] ?? ''))) ||
|
||||
($coverage['truncated'] ?? true) !== false ||
|
||||
!empty($coverage['gaps']) ||
|
||||
!is_array($coverage['segments'] ?? null) || $coverage['segments'] === []) {
|
||||
return false;
|
||||
}
|
||||
$lastEnd = 0.0;
|
||||
foreach ($coverage['segments'] as $segment) {
|
||||
if (!is_array($segment) ||
|
||||
!is_numeric($segment['start_seconds'] ?? null) ||
|
||||
!is_numeric($segment['end_seconds'] ?? null) ||
|
||||
!is_string($segment['transcript_ref'] ?? null) || trim($segment['transcript_ref']) === '' ||
|
||||
!is_string($segment['visual_ref'] ?? null) || trim($segment['visual_ref']) === '') {
|
||||
return false;
|
||||
}
|
||||
$start = (float)$segment['start_seconds'];
|
||||
$end = (float)$segment['end_seconds'];
|
||||
if (!is_finite($start) || !is_finite($end) ||
|
||||
abs($start - $lastEnd) > 0.5 || $end <= $start || $end > $durationSeconds + 0.5) {
|
||||
return false;
|
||||
}
|
||||
$lastEnd = $end;
|
||||
}
|
||||
return abs($lastEnd - $durationSeconds) <= 0.5;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user