$rawPayload * @param array $normalizedPayload * @param array $permissionContext */ public function append( TenantConfigurationResource $resource, TenantConfigurationResourceType $resourceType, ProviderConnection $providerConnection, OperationRun $operationRun, CoverageSourceContractDecision $decision, array $rawPayload, array $normalizedPayload, string $payloadHash, array $permissionContext = [], ): TenantConfigurationResourceEvidence { if (! $decision->capturable()) { throw new InvalidArgumentException('Cannot append captured evidence for a non-capturable source contract decision.'); } $this->assertScoped($resource, $resourceType, $providerConnection, $operationRun); /** @var TenantConfigurationResourceEvidence $evidence */ $evidence = DB::transaction(function () use ( $resource, $resourceType, $providerConnection, $operationRun, $decision, $rawPayload, $normalizedPayload, $payloadHash, $permissionContext, ): TenantConfigurationResourceEvidence { $capturedAt = now(); $evidence = TenantConfigurationResourceEvidence::query()->create([ 'resource_id' => (int) $resource->getKey(), 'workspace_id' => (int) $resource->workspace_id, 'managed_environment_id' => (int) $resource->managed_environment_id, 'provider_connection_id' => (int) $providerConnection->getKey(), 'resource_type_id' => (int) $resourceType->getKey(), 'operation_run_id' => (int) $operationRun->getKey(), 'source_contract_key' => (string) $decision->contractKey, 'source_endpoint' => (string) $decision->sourceEndpoint, 'source_version' => $decision->sourceVersion, 'source_schema_hash' => $decision->sourceSchemaHash, 'source_metadata' => $decision->sourceMetadata, 'raw_payload' => $rawPayload, 'normalized_payload' => $normalizedPayload, 'payload_hash' => $payloadHash, 'permission_context' => $permissionContext, 'evidence_state' => EvidenceState::ContentBacked->value, 'coverage_level' => CoverageLevel::ContentBacked->value, 'capture_outcome' => CaptureOutcome::Captured->value, 'captured_at' => $capturedAt, ]); $resource->forceFill([ 'latest_evidence_id' => (int) $evidence->getKey(), 'latest_evidence_state' => EvidenceState::ContentBacked->value, 'latest_identity_state' => $resourceType->default_identity_state, 'latest_claim_state' => $resourceType->default_claim_state, 'latest_payload_hash' => $payloadHash, 'latest_captured_at' => $capturedAt, ])->save(); return $evidence; }); return $evidence; } private function assertScoped( TenantConfigurationResource $resource, TenantConfigurationResourceType $resourceType, ProviderConnection $providerConnection, OperationRun $operationRun, ): void { if ((int) $resource->resource_type_id !== (int) $resourceType->getKey()) { throw new InvalidArgumentException('Resource type mismatch while appending tenant configuration evidence.'); } if ((int) $resource->provider_connection_id !== (int) $providerConnection->getKey()) { throw new InvalidArgumentException('Provider connection mismatch while appending tenant configuration evidence.'); } if ((int) $operationRun->workspace_id !== (int) $resource->workspace_id || (int) $operationRun->managed_environment_id !== (int) $resource->managed_environment_id ) { throw new InvalidArgumentException('Operation run scope mismatch while appending tenant configuration evidence.'); } } }