Files
Investidor-V2/tools/portal-segmentation-identity-qa.php
T
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

61 lines
5.8 KiB
PHP

<?php
// Record the owner's exemplar alias on this private QA resource; never reimport.
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
$workspace = dirname(__DIR__);
$private = $workspace.'/storage/app/private/investmoz-v2/portal-audit';
$directory = $private.'/segmentation-identity-confirmation-20261011';
$confirmation = json_decode(file_get_contents($directory.'/identity-confirmation.json'), true, 512, JSON_THROW_ON_ERROR);
$plan = json_decode(file_get_contents($private.'/portal-stability-latest.json'), true, 512, JSON_THROW_ON_ERROR);
putenv('STABILITY_QA_MODE=consumers');
$app = (static fn (string $file) => require $file)($plan['source'].'/tools/portal-stability-runtime.php');
$target = DB::selectOne('select current_database() as database,inet_server_port() as port');
throw_unless($target->database === 'stability_consumers_20261011_084534_test' && (int) $target->port === 55441 && app()->environment('testing'), RuntimeException::class, 'Exact isolated QA required.');
throw_unless(User::findOrFail(17)->can('manage-portal'), RuntimeException::class, 'Existing authorized QA manager required.');
$counts = static function (): array {
$counts = [];
foreach (['documents', 'portal_resources', 'portal_resource_revisions', 'document_malware_scans', 'audit_events', 'users', 'organizations', 'memberships', 'opportunities'] as $table) {
$counts[$table] = DB::table($table)->count();
}
return $counts;
};
$before = $counts();
$proof = DB::transaction(function () use ($confirmation): array {
$document = DB::table('documents')->where('id', '589ed9ac-967e-439e-9dde-b0fb3996e546')->lockForUpdate()->first();
$resource = DB::table('portal_resources')->where('id', 29)->lockForUpdate()->first();
throw_unless($document?->sha256 === $confirmation['sha256'] && $resource?->document_id === $document->id && ! $resource->published, RuntimeException::class, 'Only the existing private QA source is eligible.');
$externalId = $document->external_id.'-identity-confirmation-3';
$already = DB::table('audit_events')->where('source_system', 'document-batch-import')->where('external_id', $externalId)->exists();
if (! $already) {
throw_unless((int) $resource->metadata_version === 2, RuntimeException::class, 'Unexpected metadata version; stop.');
$old = 'O nome pedido v1(3) ainda não foi confirmado; não declarar identidade entre exemplares.';
throw_unless(str_contains($resource->source_reference, $old), RuntimeException::class, 'Source statement changed; stop.');
$reference = str_replace($old, 'Identidade binária com segmentar processos v1(3).docx confirmada pelo responsável em 11/10/2026. Nome local do mesmo exemplar: segmentar processos v1.docx. Hash verificado; sem nova importação ou alteração de requisitos funcionais.', $resource->source_reference);
DB::table('portal_resources')->where('id', 29)->update(['source_reference' => $reference, 'metadata_version' => 3, 'updated_at' => now()]);
DB::table('portal_resource_revisions')->insert(['resource_id' => 29, 'revision_no' => 3, 'change_type' => 'metadata_updated',
'snapshot' => json_encode(['resource' => DB::table('portal_resources')->where('id', 29)->first(), 'associations' => []], JSON_THROW_ON_ERROR), 'actor_user_id' => 17, 'created_at' => now()]);
DB::table('audit_events')->insert(['id' => (string) Str::uuid(), 'source_system' => 'document-batch-import', 'external_id' => $externalId,
'data_classification' => 'internal', 'actor_user_id' => 17, 'entity_type' => 'document', 'entity_id' => $document->id, 'action' => 'source_identity_confirmed',
'before_data' => json_encode(['source_reference' => $resource->source_reference, 'metadata_version' => 2], JSON_THROW_ON_ERROR),
'after_data' => json_encode(['resource_id' => 29, 'source_reference' => $reference, 'metadata_version' => 3, 'confirmation' => $confirmation], JSON_THROW_ON_ERROR), 'occurred_at' => now(), 'created_at' => now()]);
}
$current = DB::table('portal_resources')->where('id', 29)->first();
throw_unless($current->metadata_version === 3 && ! $current->published && $current->document_date === null && $document->issued_on === null, RuntimeException::class, 'Current source metadata is inconsistent.');
throw_unless($document->malware_scan_status === 'clean' && $document->malware_scanned_sha256 === $confirmation['sha256'], RuntimeException::class, 'Retain the clean original scan.');
return ['result' => 'passed', 'at' => gmdate('c'), 'resource_id' => 29, 'document_id' => $document->id, 'source_sha256' => $document->sha256,
'metadata_version' => 3, 'historical_revisions' => DB::table('portal_resource_revisions')->where('resource_id', 29)->count(),
'identity_confirmation_recorded' => true, 'prior_revisions_preserved' => true, 'reimport' => false, 'scan_repeated' => false,
'original_import_audit_count' => DB::table('audit_events')->where('entity_id', $document->id)->where('action', 'private_document_batch_imported')->count(),
'identity_audit_count' => DB::table('audit_events')->where('external_id', $externalId)->count(), 'active_writes' => 0];
});
$after = $counts();
foreach (['documents', 'portal_resources', 'document_malware_scans', 'users', 'organizations', 'memberships', 'opportunities'] as $table) {
throw_unless($before[$table] === $after[$table], RuntimeException::class, 'No new documents, scans, identities or opportunities.');
}
$proof += ['target' => $target, 'before' => $before, 'after' => $after];
file_put_contents($directory.'/source-identity-qa.json', json_encode($proof, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR));
echo json_encode(['result' => 'passed', 'resource_id' => 29, 'metadata_version' => 3, 'new_documents' => 0, 'reimport' => false, 'active_writes' => 0], JSON_THROW_ON_ERROR).PHP_EOL;