46 lines
3.9 KiB
PHP
46 lines
3.9 KiB
PHP
<?php
|
|
|
|
foreach (['APP_ENV' => 'testing', 'DB_CONNECTION' => 'pgsql', 'DB_HOST' => '127.0.0.1', 'DB_PORT' => '55441',
|
|
'DB_DATABASE' => 'simulator_fiscal_delta_20261021_test', 'DB_USERNAME' => 'postgres', 'DB_PASSWORD' => '', 'DB_URL' => '', 'SESSION_DRIVER' => 'array'] as $k => $v) {
|
|
putenv($k.'='.$v); $_ENV[$k] = $_SERVER[$k] = $v;
|
|
}
|
|
require __DIR__.'/../vendor/autoload.php';
|
|
$app = require __DIR__.'/../bootstrap/app.php';
|
|
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Models\Opportunity;
|
|
use App\Services\CorridorAgribusinessOpportunities;
|
|
use App\Services\OpportunityPromotion;
|
|
$target = DB::selectOne('SELECT current_database() AS name, inet_server_port() AS port');
|
|
if (! app()->environment('testing') || $target->name !== 'simulator_fiscal_delta_20261021_test' || (int) $target->port !== 55441) throw new RuntimeException('QA only');
|
|
config(['portal.profile_access_enabled' => true]);
|
|
$actor = App\Models\User::findOrFail(295);
|
|
// QA-role simulation, like the bounded tests; this is not evidence of a real production MFA login.
|
|
session(['portal.mfa_actor' => $actor->id, 'portal.mfa_at' => time(), 'login.id' => null]);
|
|
$request = Illuminate\Http\Request::create('/minhas-oportunidades', 'GET');
|
|
$request->setUserResolver(fn () => $actor); $app->instance('request', $request);
|
|
$entries = app(CorridorAgribusinessOpportunities::class)->entries();
|
|
$dir = storage_path('app/private/agribusiness-opportunities-20261023');
|
|
$records = Opportunity::whereIn('management_creation_key', array_column($entries, 'key'))->get();
|
|
if (! file_exists($dir.'/before-disclosure.json')) file_put_contents($dir.'/before-disclosure.json', json_encode($records->map(fn ($r) => $r->getRawOriginal())->all(), JSON_THROW_ON_ERROR));
|
|
$result = DB::transaction(function () use ($actor, $entries) {
|
|
DB::select('SELECT pg_advisory_xact_lock(231026, 34)');
|
|
$result = [];
|
|
foreach ($entries as $entry) {
|
|
$record = Opportunity::where('management_creation_key', $entry['key'])->lockForUpdate()->firstOrFail();
|
|
if ($record->status !== 'published') {
|
|
$values = app(App\Services\OpportunityManagement::class)->values($record);
|
|
if ($record->status !== 'draft' || ($values['canonical']['official_title'] ?? null) !== $entry['title'] || ($values['canonical']['executive_summary'] ?? null) !== $entry['summary']) throw new RuntimeException('Edited or withdrawn record requires individual review: '.$record->id);
|
|
$input = $record->workflow_context['promotional_summary']['input'];
|
|
$preview = app(OpportunityPromotion::class)->preview($actor, $record, [...$input, 'source_date' => null, 'action' => 'disclose', 'etag' => app(App\Services\OpportunityManagement::class)->etag($record)]);
|
|
app(OpportunityPromotion::class)->confirm($actor, $record->id, ['token' => $preview['token'], 'operation_key' => (string) Illuminate\Support\Str::uuid(), 'confirm' => true,
|
|
'reason' => 'QA automatizada: divulgação das 34 fichas de Agronegócio expressamente instruída pela Tempo; em preparação, sem autorização de execução.']);
|
|
} elseif (data_get($record->workflow_context, 'publication.purpose') !== OpportunityPromotion::PURPOSE) throw new RuntimeException('Different publication preserved');
|
|
$result[] = ['id' => $record->id, 'title' => $entry['title'], 'corridor' => $entry['corridor'], 'url' => '/oportunidades/'.$record->slug];
|
|
}
|
|
return $result;
|
|
});
|
|
$receipt = ['target' => $target, 'published' => count($result), 'authentication' => 'QA role simulation only; no production authentication claimed', 'source_sha256' => CorridorAgribusinessOpportunities::SOURCE_HASH, 'records' => $result, 'active_writes' => 0];
|
|
file_put_contents($dir.'/disclosure-receipt.json', json_encode($receipt, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
|
echo json_encode(['published' => count($result), 'target' => $target, 'active_writes' => 0]).PHP_EOL;
|