'testing', 'DB_CONNECTION' => 'pgsql', 'DB_HOST' => '127.0.0.1', 'DB_PORT' => '55441', 'DB_DATABASE' => 'anchor_restore_20261007_test', 'DB_USERNAME' => 'postgres', 'DB_PASSWORD' => '', 'DB_URL' => ''] as $key => $value) { putenv($key.'='.$value); $_ENV[$key] = $value; $_SERVER[$key] = $value; } require dirname(__DIR__).'/vendor/autoload.php'; $app = require dirname(__DIR__).'/bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); $db = DB::connection(); if ($db->getDatabaseName() !== 'anchor_restore_20261007_test' || (string) $db->getConfig('port') !== '55441' || $db->getConfig('host') !== '127.0.0.1') { throw new RuntimeException('QA target rejected before seed.'); } $identity = $db->selectOne('select current_database() as database,inet_server_port() as port'); if ($identity->database !== 'anchor_restore_20261007_test' || (int) $identity->port !== 55441) { throw new RuntimeException('QA runtime identity rejected.'); } $uuid = fn () => (string) Str::uuid(); $manifest = $db->transaction(function () use ($db, $uuid) { $user = User::firstOrCreate(['email' => 'relationship-qa@example.invalid'], ['name' => 'Synthetic QA manager', 'email_verified_at' => now(), 'password' => Hash::make('QA-Relationship-2026!')]); $user->forceFill(['email_verified_at' => now()])->save(); $sector = Sector::firstOrCreate(['slug' => 'qa-relationship'], ['name' => 'Synthetic QA relationship sector', 'is_active' => true]); $parent = null; $ids = []; foreach (['country', 'province', 'district', 'admin_post', 'locality'] as $type) { $external = 'qa-relationship-'.$type; $node = $db->table('geo_locations')->where('source_system', 'cartografia-workbook')->where('code', $external)->first(); $id = $node?->id ?? $uuid(); if (! $node) { $db->table('geo_locations')->insert(['id' => $id, 'code' => $external, 'name' => 'QA '.$type, 'location_type' => $type, 'parent_id' => $parent, 'data_classification' => 'public', 'source_system' => 'cartografia-workbook', 'external_id' => '964a187ad32ea553b9e112cd159caa90b900050c42b7329594a75bcd798a96ff:'.$external]); } $ids[$type] = $id; $parent = $id; } $projects = []; $dossiers = []; foreach ([1, 2] as $index) { $project = Project::firstOrCreate(['code' => 'QA-ANCHOR-'.$index], ['name' => 'Synthetic QA anchor '.$index, 'source_system' => 'qa-relationship', 'status' => 'planned', 'data_classification' => 'public']); $dossier = InvestmentDossier::firstOrCreate(['project_id' => $project->id], ['title' => $project->name, 'source' => 'Synthetic browser QA fixture; no operational coordinates', 'content' => ['location' => 'QA province / district / admin_post / locality', 'description' => 'Synthetic project with documented QA fixture site'], 'publication_status' => 'published', 'published_at' => now(), 'approval_basis' => 'document_owner', 'approval_evidence' => 'Synthetic QA disclosure fixture only']); $site = $db->table('geo_locations')->where('code', 'qa-anchor-site-'.$index)->first(); $siteId = $site?->id ?? $uuid(); if (! $site) { $db->table('geo_locations')->insert(['id' => $siteId, 'code' => 'qa-anchor-site-'.$index, 'name' => 'QA documented site '.$index, 'location_type' => 'site', 'parent_id' => $parent, 'data_classification' => 'public', 'source_system' => 'qa-relationship']); } if (! $db->table('project_locations')->where('project_id', $project->id)->where('geo_location_id', $siteId)->exists()) { $db->table('project_locations')->insert(['id' => $uuid(), 'project_id' => $project->id, 'geo_location_id' => $siteId, 'role' => $index === 1 ? 'primary' : 'secondary', 'data_classification' => 'public', 'source_system' => 'qa-relationship']); } if (! $db->table('geo_geometries')->where('geo_location_id', $siteId)->exists()) { $db->table('geo_geometries')->insert(['id' => $uuid(), 'geo_location_id' => $siteId, 'geometry_type' => 'point', 'data_classification' => 'public', 'source_system' => 'synthetic QA source', 'geom' => DB::raw('ST_SetSRID(ST_MakePoint('.(32.4 + $index / 10).','.(-25.8 - $index / 10).'),4326)')]); } $projects[] = $project; $dossiers[] = $dossier; } $cluster = EconomicCluster::firstOrCreate(['code' => 'QA-REL-CLU'], ['name' => 'Synthetic QA multi-site cluster', 'sector' => 'QA', 'status' => 'planned', 'data_classification' => 'public']); $clusterDossier = InvestmentDossier::firstOrCreate(['cluster_id' => $cluster->id], ['title' => $cluster->name, 'source' => 'Synthetic QA member relationship source', 'content' => ['anchors' => 'QA-ANCHOR-1, QA-ANCHOR-2; coverage pending', 'gaps' => 'Synthetic QA chain gaps'], 'publication_status' => 'published', 'published_at' => now(), 'approval_basis' => 'document_owner', 'approval_evidence' => 'Synthetic QA fixture disclosure only']); foreach ($projects as $project) { if (! $db->table('cluster_projects')->where('cluster_id', $cluster->id)->where('project_id', $project->id)->exists()) { $db->table('cluster_projects')->insert(['id' => $uuid(), 'cluster_id' => $cluster->id, 'project_id' => $project->id, 'role' => 'anchor', 'data_classification' => 'public', 'source_system' => 'qa-relationship', 'source_reference' => 'Synthetic documented QA membership', 'validation_status' => 'pending']); } } $production = ValueChain::firstOrCreate(['cluster_id' => $cluster->id, 'code' => 'QA-PRODUCTION'], ['name' => 'QA production', 'stage' => 'production', 'data_classification' => 'public']); $processing = ValueChain::firstOrCreate(['cluster_id' => $cluster->id, 'code' => 'QA-PROCESSING'], ['name' => 'QA processing', 'stage' => 'processing', 'data_classification' => 'public']); if (! $db->table('value_chain_links')->where('from_value_chain_id', $production->id)->where('to_value_chain_id', $processing->id)->exists()) { $db->table('value_chain_links')->insert(['id' => $uuid(), 'from_value_chain_id' => $production->id, 'to_value_chain_id' => $processing->id, 'link_type' => 'supplies', 'data_classification' => 'public']); } $opportunity = Opportunity::firstOrCreate(['reference' => 'QA-ANCHOR-OPPORTUNITY'], ['sector_id' => $sector->id, 'title' => 'Synthetic QA linked opportunity', 'slug' => 'qa-anchor-opportunity', 'summary' => 'Synthetic browser QA fixture', 'status' => 'published', 'published_at' => now()]); $db->table('opportunity_projects')->insertOrIgnore(['opportunity_id' => $opportunity->id, 'project_id' => $projects[0]->id]); $db->table('opportunity_clusters')->insertOrIgnore(['opportunity_id' => $opportunity->id, 'cluster_id' => $cluster->id]); return ['target' => 'anchor_restore_20261007_test:55441', 'project_dossier' => $dossiers[0]->id, 'second_project' => $projects[1]->id, 'cluster_dossier' => $clusterDossier->id, 'opportunity_slug' => $opportunity->slug, 'opportunity_id' => $opportunity->id, 'province_id' => $ids['province']]; }); $directory = storage_path('app/private/anchor-project-reconciliation'); if (! is_dir($directory.'/qa-preview')) { mkdir($directory.'/qa-preview', 0700, true); } $plan = json_decode(file_get_contents($directory.'/preview.json'), true); $plan['target'] = ['database' => 'anchor_restore_20261007_test', 'port' => 55441]; file_put_contents($directory.'/qa-preview/preview.json', json_encode($plan, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)); $proof = json_decode(file_get_contents($directory.'/backup-proof.json'), true); $proof['target'] = $plan['target']; file_put_contents($directory.'/qa-preview/backup-proof.json', json_encode($proof, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); file_put_contents($directory.'/qa-browser-fixture.json', json_encode($manifest, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); echo json_encode($manifest).PHP_EOL;