Implements Spec 119 (Drift Golden Master Cutover): - Baseline Compare is the only drift writer (`source = baseline.compare`). - Drift findings now store diff-compatible `evidence_jsonb` (summary.kind, baseline/current policy_version_id refs, fidelity + provenance). - Findings UI renders one-sided diffs for `missing_policy`/`unexpected_policy` when a single ref exists; otherwise shows explicit “diff unavailable”. - Removes legacy drift generator runtime (jobs/services/UI) and related tests. - Adds one-time migration to delete legacy drift findings (`finding_type=drift` where source is null or != baseline.compare). - Scopes baseline capture & landing duplicate warnings to latest completed inventory sync. - Canonicalizes compliance `scheduledActionsForRule` drift signal and keeps legacy snapshots comparable. Tests: - `vendor/bin/sail artisan test --compact` (full suite per tasks) - Focused pack: BaselinePolicyVersionResolverTest, BaselineCompareDriftEvidenceContractTest, DriftFindingDiffUnavailableTest, LegacyDriftFindingsCleanupMigrationTest, ComplianceNoncomplianceActionsDriftTest Notes: - Livewire v4+ / Filament v5 compatible (no legacy APIs). - No new external dependencies. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #144
63 lines
1.7 KiB
PHP
63 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Verification;
|
|
|
|
use App\Models\OperationRun;
|
|
use App\Support\OperationRunStatus;
|
|
|
|
final class PreviousVerificationReportResolver
|
|
{
|
|
public static function resolvePreviousReportId(OperationRun $run): ?int
|
|
{
|
|
$runId = $run->getKey();
|
|
|
|
if (! is_int($runId) || $runId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$providerConnectionId = self::providerConnectionId($run);
|
|
|
|
$query = OperationRun::query()
|
|
->where('tenant_id', (int) $run->tenant_id)
|
|
->where('workspace_id', (int) $run->workspace_id)
|
|
->where('type', (string) $run->type)
|
|
->where('run_identity_hash', (string) $run->run_identity_hash)
|
|
->where('status', OperationRunStatus::Completed->value)
|
|
->where('id', '<', $runId)
|
|
->orderByDesc('id');
|
|
|
|
if ($providerConnectionId !== null) {
|
|
$query->where('context->provider_connection_id', $providerConnectionId);
|
|
} else {
|
|
$query->whereNull('context->provider_connection_id');
|
|
}
|
|
|
|
$previousId = $query->value('id');
|
|
|
|
return is_int($previousId) ? $previousId : null;
|
|
}
|
|
|
|
private static function providerConnectionId(OperationRun $run): ?int
|
|
{
|
|
$context = $run->context;
|
|
|
|
if (! is_array($context)) {
|
|
return null;
|
|
}
|
|
|
|
$providerConnectionId = $context['provider_connection_id'] ?? null;
|
|
|
|
if (is_int($providerConnectionId)) {
|
|
return $providerConnectionId;
|
|
}
|
|
|
|
if (is_string($providerConnectionId) && ctype_digit(trim($providerConnectionId))) {
|
|
return (int) trim($providerConnectionId);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|