Files
SGF/scripts/settlements-demo-state.php
2026-10-30 08:13:34 +02:00

51 lines
4.0 KiB
PHP

<?php
// Hash-only preservation check of existing synthetic demonstration data. No credential columns.
$phase = $argv[1] ?? '';
if (! in_array($phase, ['before', 'after'], true)) throw new LogicException('Choose before/after.');
if (! isset($argv[2])) {
foreach (['compras', 'sgf'] as $mode) {
$php = $mode === 'compras' ? 'C:/Users/macbook/.config/investmoz/php-8.5.11/php.exe' : 'C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe';
passthru(escapeshellarg($php).' '.escapeshellarg(__FILE__).' '.$phase.' '.$mode, $status);
if ($status) exit($status);
}
exit;
}
$mode = $argv[2]; if (! in_array($mode, ['compras', 'sgf'], true)) throw new LogicException('Unknown synthetic host.');
$s = json_decode(file_get_contents('C:/laragon/data/sgf-tempo/secrets/payables-demo-'.$mode.'.json'), true, 32, JSON_THROW_ON_ERROR);
foreach ($s as $k => $v) { putenv($k.'='.$v); $_ENV[$k] = $_SERVER[$k] = $v; }
require $s['HOST_ROOT'].'/vendor/autoload.php'; $app = require $s['HOST_ROOT'].'/bootstrap/app.php'; $app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
use Illuminate\Support\Facades\DB;
use Tempo\Finance\Payables\Payables;
$db = DB::connection();
if (! preg_match('/^(compras_receipts_test_|payable_sgf_)[a-f0-9]{12}$/D', $db->getDatabaseName()) || $db->getConfig('host') !== '127.0.0.1'
|| $db->selectOne('select current_database() as d')->d !== $s['DB_DATABASE']) throw new LogicException('Synthetic database guard.');
$newActions = ['payments_view', 'payment_prepare', 'payment_confirm', 'allocation_prepare', 'allocation_confirm'];
$tables = ['pa_sources', 'pa_proposals', 'pa_obligations', 'pa_events', 'pa_commands', 'pa_outbox', 'pa_history_imports', 'pa_imported_payments', 'pa_payment_decisions', 'pa_imported_sources', 'permission_grants'];
if ($mode === 'compras') $tables = [...$tables, 'invoices', 'invoice_items', 'purchase_orders', 'goods_receipts', 'goods_receipt_items', 'stock_movements', 'budget_entries', 'budget_consumptions', 'external_payments'];
$hashes = []; $counts = [];
DB::transaction(function () use ($db, $tables, $newActions, &$hashes, &$counts): void {
$db->statement('SET TRANSACTION READ ONLY');
foreach ($tables as $table) {
if (! $db->getSchemaBuilder()->hasTable($table)) { $hashes[$table] = null; continue; }
$rows = $db->table($table)->orderBy($table === 'pa_outbox' ? 'event_id' : 'id')->get()->map(fn ($r) => (array) $r)->all();
$hashes[$table] = hash('sha256', Payables::canonical($rows)); $counts[$table] = count($rows);
}
$users = $db->table('users')->orderBy('id')->get(['id', 'name', 'email'])->map(fn ($r) => (array) $r)->all();
$hashes['accounts_without_credentials'] = hash('sha256', Payables::canonical($users)); $counts['users'] = count($users);
$access = $db->table('pa_access')->whereNotIn('action', $newActions)->orderBy('id')->get()->map(fn ($r) => (array) $r)->all();
$hashes['existing_access'] = hash('sha256', Payables::canonical($access));
});
$path = __DIR__.'/../docs/proofs/supplier-settlements-demo-'.$mode.'.json';
if ($phase === 'before') {
file_put_contents($path, json_encode(['host' => $mode, 'hashes_before' => $hashes, 'counts_before' => $counts, 'checked_at' => gmdate('c')], JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR).PHP_EOL);
echo $mode." synthetic baseline recorded.\n";
} else {
$before = json_decode(file_get_contents($path), true, 32, JSON_THROW_ON_ERROR);
if ($before['hashes_before'] !== $hashes || $before['counts_before'] !== $counts) throw new LogicException('Existing synthetic data changed; investigate without reset.');
$ps = []; foreach (\Tempo\Finance\Payables\SettlementSchema::TABLES as $t) $ps[$t] = $db->table($t)->count();
$result = $before + ['preserved' => true, 'schema_counts' => $ps, 'checked_after' => gmdate('c')];
file_put_contents($path, json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR).PHP_EOL);
echo $mode." original documents, history, accounts and access preserved; synthetic settlements installed.\n";
}