Files
Investidor-V2/tools/opportunity-workflow-verify-qa.php
nala 01405cbf8a
tests / ci (push) Canceled after 0s
oportunidades 5
2026-10-10 14:15:28 +02:00

59 lines
4.1 KiB
PHP

<?php
use App\Models\Opportunity;
use App\Models\User;
use App\Services\OpportunityCanonicalContract;
use App\Services\PortalProfileAccess;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
$root = dirname(__DIR__);
require $root.'/vendor/autoload.php';
require __DIR__.'/portal-qa-environment.php';
$target = portalQaEnvironment();
$app = require $root.'/bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
$identity = portalQaAssertTarget($target);
config(['portal.profile_access_enabled' => true, 'portal.opportunity_specialized_drafts_enabled' => true]);
$directory = $root.'/storage/app/private/investmoz-v2/portal-audit';
$actors = json_decode(file_get_contents($directory.'/profiles-v1-actors-private.json'), true, 512, JSON_THROW_ON_ERROR);
$promoter = User::whereKey($actors['promoter']['id'])->firstOrFail();
throw_unless($promoter->id === 21 && str_ends_with($promoter->email, '@example.invalid'), RuntimeException::class, 'Synthetic QA actor mismatch');
$label = 'Promotor QA — conta sintética 21';
if ($promoter->name !== $label) {
$before = $promoter->name;
$promoter->name = $label;
$promoter->save();
app(PortalProfileAccess::class)->audit($promoter, 'qa_fixture_labeled', ['actor_id' => $promoter->id, 'before' => $before, 'after' => $label, 'reason' => 'Identificação inequívoca do ensaio QA; sem alterar identidade/permissões']);
}
DB::beginTransaction();
DB::statement('SET TRANSACTION READ ONLY');
$proof = json_decode(file_get_contents($directory.'/opportunity-workflow-http-qa.json'), true, 512, JSON_THROW_ON_ERROR);
$result = ['target' => $identity, 'captured_at' => gmdate('c'), 'active_writes' => 0, 'visual_pending' => true,
'promoter_qa' => ['id' => $promoter->id, 'name' => $promoter->name, 'mfa_confirmed' => $promoter->two_factor_confirmed_at !== null, 'contexts' => app(PortalProfileAccess::class)->navigation($promoter)['contexts']],
'categories' => [], 'five_phases_nineteen_steps_preserved' => true];
foreach ($proof['cases'] as $case) {
$record = Opportunity::whereKey($case['id'])->firstOrFail();
$row = ['id' => $record->id, 'category' => $case['category'], 'working_state' => app(PortalProfileAccess::class)->state($record), 'publication_status' => $record->status];
try {
$snapshot = app(OpportunityCanonicalContract::class)->validateSubmission($record);
$row['canonical_validation'] = 'passed';
$row['payload_sha256'] = $snapshot['hash'];
$row['resources'] = array_map('count', $snapshot['resources']);
$row['country'] = array_map(fn ($l) => $l['payload']['country_code'], $snapshot['resources']['locations']);
} catch (ValidationException $error) {
$row['canonical_validation'] = 'blocked';
$row['missing'] = array_keys($error->errors());
}
$result['categories'][] = $row;
}
$docIds = DB::table('opportunity_documents')->whereIn('opportunity_id', array_column($proof['cases'], 'id'))->pluck('document_id')->all();
$imageIds = DB::table('opportunity_images')->whereIn('opportunity_id', array_column($proof['cases'], 'id'))->pluck('document_id')->all();
$result['document_scans'] = DB::table('documents')->whereIn('id', [...$docIds, ...$imageIds])->get(['id', 'media_type', 'sha256', 'malware_scanned_sha256', 'malware_scan_status', 'malware_engine', 'storage_encryption']);
$result['territories'] = ['registered' => DB::table('geo_locations')->whereNull('deleted_at')->count(), 'geometries' => DB::table('geo_geometries')->count(), 'visual' => 'pending'];
$result['task_counts'] = DB::table('tasks')->where('source_system', 'opportunity-workflow')->selectRaw('status,count(*) as total')->groupBy('status')->pluck('total', 'status');
DB::rollBack();
file_put_contents($directory.'/opportunity-workflow-verification-qa.json', json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
echo json_encode(['target' => $identity, 'promoter_qa_id' => $promoter->id, 'categories' => array_count_values(array_column($result['categories'], 'canonical_validation')), 'active_writes' => 0, 'visual_pending' => true]).PHP_EOL;