Files
Investidor-V2/database/seeders/ReferenceCatalogSeeder.php
T
nala 4f35313d06
tests / ci (push) Canceled after 0s
novas funcionalidades dos formulario
2026-10-02 11:13:37 +02:00

129 lines
6.0 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use RuntimeException;
class ReferenceCatalogSeeder extends Seeder
{
private const CATALOG_IDS = [
'authorities' => 'a1000000-0000-4000-8000-000000000001',
'jurisdictions' => 'a1000000-0000-4000-8000-000000000002',
'economic-activities' => 'a1000000-0000-4000-8000-000000000003',
];
/** @var array<string,string> */
private const ACTIVITY_IDS = [
'agronegocio' => 'a2000000-0000-4000-8000-000000000001',
'energia' => 'a2000000-0000-4000-8000-000000000002',
'turismo' => 'a2000000-0000-4000-8000-000000000003',
'infraestruturas' => 'a2000000-0000-4000-8000-000000000004',
'economia-azul' => 'a2000000-0000-4000-8000-000000000005',
'mercado-financeiro' => 'a2000000-0000-4000-8000-000000000006',
];
public function run(): void
{
$territory = json_decode(File::get(database_path('data/territory-locations.json')), true, 512, JSON_THROW_ON_ERROR);
if (! is_array($territory) || ! is_array($territory['records'] ?? null) || ! is_int($territory['source_version'] ?? null)) {
throw new RuntimeException('Territorial catalog source is malformed.');
}
if (! is_string($territory['records_sha256'] ?? null)
|| ! hash_equals($territory['records_sha256'], hash('sha256', json_encode($territory['records'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR)))
|| DB::table('geo_locations')->where('source_system', 'cartografia-workbook')->where('data_classification', 'public')->count() !== count($territory['records'])) {
throw new RuntimeException('Territorial catalog version does not match its verified seed records.');
}
DB::transaction(function () use ($territory): void {
DB::select('SELECT pg_advisory_xact_lock(20261001, 300100)');
$this->catalogVersion('authorities', 1, 'authority-register-pending-source', 'pending-authority-source',
'Awaiting an approved authority source; no institution or mandate is inferred.', null, null, 'draft');
$this->catalogVersion('jurisdictions', $territory['source_version'], 'cartografia-workbook', (string) $territory['source_version'],
'database/data/territory-locations.json', $territory['source_sha256'], null, 'published');
$activities = DB::table('sectors')->whereIn('slug', array_keys(self::ACTIVITY_IDS))->orderBy('slug')->get(['id', 'name', 'slug']);
if ($activities->count() !== count(self::ACTIVITY_IDS)) {
throw new RuntimeException('The curated sector source is incomplete; economic activity seed aborted.');
}
$canonical = $activities->map(fn ($row) => ['code' => $row->slug, 'label_pt_mz' => $row->name])->values()->all();
$activityChecksum = hash('sha256', json_encode($canonical, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR));
$versionId = $this->catalogVersion('economic-activities', 1, 'investmoz-curated', 'sector-seeder-v1',
'database/seeders/SectorSeeder.php; seed is a portal grouping, not an official activity classification.',
$activityChecksum, '2026-10-01', 'published');
foreach ($activities as $activity) {
$expected = [
'id' => self::ACTIVITY_IDS[$activity->slug],
'catalog_version_id' => $versionId,
'parent_id' => null,
'sector_id' => $activity->id,
'code' => $activity->slug,
'label_pt_mz' => $activity->name,
'description_pt_mz' => null,
'version_no' => 1,
'valid_from' => '2026-10-01',
'valid_to' => null,
'status' => 'published',
];
$existing = DB::table('economic_activities')->where('catalog_version_id', $versionId)->where('code', $activity->slug)->first();
if ($existing) {
foreach ($expected as $column => $value) {
if ((string) $existing->{$column} !== (string) $value) {
throw new RuntimeException('Economic activity differs from its versioned seed: '.$activity->slug);
}
}
continue;
}
DB::table('economic_activities')->insert([...$expected, 'created_at' => now(), 'updated_at' => now()]);
}
});
}
private function catalogVersion(
string $code,
int $version,
string $source,
string $sourceVersion,
string $reference,
?string $checksum,
?string $validFrom,
string $status,
): string {
$id = self::CATALOG_IDS[$code];
$expected = [
'id' => $id,
'catalog_code' => $code,
'version_no' => $version,
'locale' => 'pt-MZ',
'source_system' => $source,
'source_version' => $sourceVersion,
'source_reference' => $reference,
'source_sha256' => $checksum,
'valid_from' => $validFrom,
'valid_to' => null,
'status' => $status,
];
$existing = DB::table('reference_catalog_versions')->where('catalog_code', $code)->where('version_no', $version)->where('locale', 'pt-MZ')->first();
if ($existing) {
foreach ($expected as $column => $value) {
if ((string) $existing->{$column} !== (string) $value) {
throw new RuntimeException('Reference catalog version differs from its packaged source: '.$code);
}
}
return $id;
}
DB::table('reference_catalog_versions')->insert([...$expected, 'created_at' => now(), 'updated_at' => now()]);
return $id;
}
}