requestedKeys($subjects); if ($requestedKeys === []) { return []; } $policyTypes = array_values(array_unique(array_map( static fn (array $subject): string => trim((string) ($subject['policy_type'] ?? '')), $subjects, ))); $policyTypes = array_values(array_filter($policyTypes, static fn (string $value): bool => $value !== '')); $externalIds = array_values(array_unique(array_map( static fn (array $subject): string => trim((string) ($subject['subject_external_id'] ?? '')), $subjects, ))); $externalIds = array_values(array_filter($externalIds, static fn (string $value): bool => $value !== '')); if ($policyTypes === [] || $externalIds === []) { return []; } $policies = Policy::query() ->where('tenant_id', (int) $tenant->getKey()) ->whereIn('policy_type', $policyTypes) ->whereIn('external_id', $externalIds) ->get(['id', 'policy_type', 'external_id']); /** @var Collection $policies */ $policyIdToKey = []; $policyIds = []; foreach ($policies as $policy) { if (! $policy instanceof Policy) { continue; } $key = (string) $policy->policy_type.'|'.(string) $policy->external_id; if (! array_key_exists($key, $requestedKeys)) { continue; } $policyIdToKey[(int) $policy->getKey()] = $key; $policyIds[] = (int) $policy->getKey(); } if ($policyIds === []) { return []; } $baseQuery = DB::table('policy_versions') ->select([ 'policy_versions.id', 'policy_versions.operation_run_id', 'policy_versions.capture_purpose', 'policy_versions.policy_id', 'policy_versions.policy_type', 'policy_versions.platform', 'policy_versions.captured_at', 'policy_versions.snapshot', 'policy_versions.assignments', 'policy_versions.scope_tags', 'policy_versions.version_number', ]) ->selectRaw('ROW_NUMBER() OVER (PARTITION BY policy_id ORDER BY captured_at DESC, version_number DESC, id DESC) as rn') ->where('tenant_id', (int) $tenant->getKey()) ->whereIn('policy_id', $policyIds) ->whereNull('deleted_at'); if ($since instanceof CarbonImmutable) { $baseQuery->where('captured_at', '>=', $since->toDateTimeString()); } $versions = DB::query() ->fromSub($baseQuery, 'ranked_policy_versions') ->where('rn', 1) ->get(); $resolved = []; foreach ($versions as $version) { $policyId = is_numeric($version->policy_id ?? null) ? (int) $version->policy_id : null; $key = $policyId !== null ? ($policyIdToKey[$policyId] ?? null) : null; if (! is_string($key) || $key === '' || ! array_key_exists($key, $requestedKeys)) { continue; } $policyType = is_string($version->policy_type ?? null) ? (string) $version->policy_type : ''; $subjectExternalId = (string) ($requestedKeys[$key] ?? ''); if ($policyType === '' || $subjectExternalId === '') { continue; } $snapshot = $version->snapshot ?? null; $snapshot = is_array($snapshot) ? $snapshot : (is_string($snapshot) ? json_decode($snapshot, true) : null); $snapshot = is_array($snapshot) ? $snapshot : []; $assignments = $version->assignments ?? null; $assignments = is_array($assignments) ? $assignments : (is_string($assignments) ? json_decode($assignments, true) : null); $assignments = is_array($assignments) ? $assignments : []; $scopeTags = $version->scope_tags ?? null; $scopeTags = is_array($scopeTags) ? $scopeTags : (is_string($scopeTags) ? json_decode($scopeTags, true) : null); $scopeTags = is_array($scopeTags) ? $scopeTags : []; $platform = is_string($version->platform ?? null) ? (string) $version->platform : null; $normalized = $this->settingsNormalizer->normalizeForDiff( snapshot: $snapshot, policyType: $policyType, platform: $platform, ); $normalizedAssignments = $this->assignmentsNormalizer->normalizeForDiff($assignments); $normalizedScopeTagIds = $this->scopeTagsNormalizer->normalizeIds($scopeTags); $hash = $this->hasher->hashNormalized([ 'settings' => $normalized, 'assignments' => $normalizedAssignments, 'scope_tag_ids' => $normalizedScopeTagIds, ]); $observedAt = is_string($version->captured_at ?? null) ? CarbonImmutable::parse((string) $version->captured_at) : null; $policyVersionId = is_numeric($version->id ?? null) ? (int) $version->id : null; $observedOperationRunId = is_numeric($version->operation_run_id ?? null) ? (int) $version->operation_run_id : null; $capturePurpose = is_string($version->capture_purpose ?? null) ? trim((string) $version->capture_purpose) : null; $capturePurpose = $capturePurpose !== '' ? $capturePurpose : null; $resolved[$key] = new ResolvedEvidence( policyType: $policyType, subjectExternalId: $subjectExternalId, hash: $hash, fidelity: EvidenceProvenance::FidelityContent, source: EvidenceProvenance::SourcePolicyVersion, observedAt: $observedAt, observedOperationRunId: $observedOperationRunId, meta: [ 'policy_version_id' => $policyVersionId, 'operation_run_id' => $observedOperationRunId, 'capture_purpose' => $capturePurpose, ], ); } return $resolved; } /** * @param list $subjects * @return array */ private function requestedKeys(array $subjects): array { $keys = []; foreach ($subjects as $subject) { $policyType = trim((string) ($subject['policy_type'] ?? '')); $externalId = trim((string) ($subject['subject_external_id'] ?? '')); if ($policyType === '' || $externalId === '') { continue; } $keys[$policyType.'|'.$externalId] = $externalId; } return $keys; } }