103 lines
8.2 KiB
PHP
103 lines
8.2 KiB
PHP
<?php
|
|
|
|
use App\Models\EconomicCluster;
|
|
use App\Models\InvestmentDossier;
|
|
use App\Models\Opportunity;
|
|
use App\Models\Project;
|
|
use App\Models\Sector;
|
|
use App\Models\User;
|
|
use App\Models\ValueChain;
|
|
use Illuminate\Contracts\Console\Kernel;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Str;
|
|
|
|
foreach (['APP_ENV' => '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;
|