Files
Investidor-V2/tools/opportunity-origin-active-confirmation.php
nala 6ddafc95ba
tests / ci (push) Canceled after 0s
oportunidades 4
2026-10-10 07:03:59 +02:00

43 lines
3.4 KiB
PHP

<?php
// Direct PDO reader: no application kernel, migrations, seeders or active writes.
require __DIR__.'/investmoz-v2-territory-audit.php';
$directory = dirname(__DIR__).'/storage/app/private/investmoz-v2';
$backup = json_decode(file_get_contents($directory.'/opportunity-origin-backup-proof.json'), true, 512, JSON_THROW_ON_ERROR);
$pdo->exec('BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY');
$identity = $pdo->query("SELECT current_database() AS database,inet_server_port() AS port,current_setting('transaction_read_only') AS read_only")->fetch(PDO::FETCH_ASSOC);
$events = $pdo->query("SELECT id,actor_user_id,occurred_at,before_data,after_data FROM audit_events WHERE source_system='opportunity-origin-review' ORDER BY occurred_at,id")->fetchAll(PDO::FETCH_ASSOC);
$records = $pdo->query("SELECT o.id,o.reference,o.title,o.status,COALESCE((SELECT a.after_data->>'classification' FROM audit_events a WHERE a.source_system='opportunity-origin-review' AND a.after_data->>'opportunity_id'=o.id::text ORDER BY a.occurred_at DESC,a.id DESC LIMIT 1),'undetermined') AS classification FROM opportunities o WHERE o.id BETWEEN 1 AND 6 ORDER BY o.id")->fetchAll(PDO::FETCH_ASSOC);
foreach ($records as &$record) {
$record['public_scope_included'] = $record['status'] === 'published' && $record['classification'] !== 'example';
}
unset($record);
$checks = [];
$restored = $backup['restored_target'];
if (! str_ends_with($restored['database'], '_test') || (int) $restored['port'] !== 55441) {
throw new RuntimeException('Invalid isolated comparison target');
}
$baseline = new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$restored['database'], $c['username'], $c['password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$baseline->exec('BEGIN TRANSACTION READ ONLY');
$oldEvents = $baseline->query("SELECT id,row_to_json(t)::text AS row FROM audit_events t WHERE source_system IS DISTINCT FROM 'opportunity-origin-review' ORDER BY id")->fetchAll(PDO::FETCH_KEY_PAIR);
$currentEvents = $pdo->query('SELECT id,row_to_json(t)::text AS row FROM audit_events t ORDER BY id')->fetchAll(PDO::FETCH_KEY_PAIR);
$missing = $changed = 0;
foreach ($oldEvents as $id => $row) {
if (! isset($currentEvents[$id])) {
$missing++;
} elseif ($currentEvents[$id] !== $row) {
$changed++;
}
}
$baseline->exec('ROLLBACK');
foreach (['opportunities', 'opportunity_projects', 'opportunity_clusters', 'opportunity_favourites', 'interest_requests', 'interest_submission_receipts', 'investment_messages', 'tasks', 'project_locations', 'cluster_projects'] as $table) {
$key = '"public"."'.$table.'"';
$rows = $pdo->query('SELECT row_to_json(t)::text AS row FROM '.$key.' t ORDER BY row_to_json(t)::text')->fetchAll(PDO::FETCH_COLUMN);
$hash = hash('sha256', implode("\n", $rows));
$checks[$table] = ['matches_backup' => $hash === ($backup['table_hashes'][$key] ?? null), 'hash' => $hash, 'rows' => count($rows)];
}
$pdo->exec('ROLLBACK');
$proof = ['captured_at' => gmdate('c'), 'identity' => $identity, 'records' => $records, 'audit' => $events, 'preservation' => $checks, 'historical_audit' => ['baseline_events' => count($oldEvents), 'missing' => $missing, 'changed' => $changed, 'additional_events' => count($currentEvents) - count($oldEvents)], 'active_writes' => 0];
file_put_contents($directory.'/opportunity-origin-active-confirmation.json', json_encode($proof, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
echo json_encode($proof, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR).PHP_EOL;