make(Kernel::class)->bootstrap(); if (! $app->environment('local') || DB::connection()->getDriverName() !== 'pgsql') { throw new RuntimeException('Local PostgreSQL only.'); } $root = storage_path('app/private/'); $before = json_decode(file_get_contents($root.'territory-workbook-candidates-before-designation-fix.json'), true, 512, JSON_THROW_ON_ERROR); $after = json_decode(file_get_contents($root.'territory-workbook-candidates.json'), true, 512, JSON_THROW_ON_ERROR); if (($after['mapping_version'] ?? 0) !== 2 || $before['checksum'] !== $after['checksum'] || hash_file('sha256', 'C:/Mac/Home/Documents/eBAU/cartografia_moz.xlsx') !== $after['checksum']) { throw new RuntimeException('Source or mapping mismatch.'); } $old = array_column($before['nodes'], null, 'id'); $new = array_column($after['nodes'], null, 'id'); $result = DB::transaction(function () use ($old, $new, $after) { DB::select('SELECT pg_advisory_xact_lock(280926, 150000)'); $renamed = $quarantined = 0; foreach ($old as $id => $prior) { $record = DB::table('geo_locations')->where('id', $id)->where('source_system', 'cartografia-workbook')->where('external_id', $after['checksum'].':'.$id)->lockForUpdate()->first(); if (! $record || $record->parent_id !== $prior['parent_id'] || $record->code !== $prior['code'] || $record->location_type !== $prior['location_type']) { throw new RuntimeException('Existing reference changed: '.$id); } $desired = $new[$id] ?? null; if (! $desired) { if ($record->deleted_at === null) { DB::table('geo_locations')->where('id', $id)->update(['data_classification' => 'internal', 'deleted_at' => now(), 'version_no' => $record->version_no + 1]); $quarantined++; } continue; } if ($record->name === $desired['name']) { continue; } if ($record->name !== $prior['name'] || $record->deleted_at !== null) { throw new RuntimeException('Manual edit must not be overwritten: '.$id); } DB::table('geo_locations')->where('id', $id)->update(['name' => $desired['name'], 'version_no' => $record->version_no + 1]); $renamed++; } foreach ($new as $id => $node) { if (! isset($old[$id])) { throw new RuntimeException('Unexpected identity change: '.$id); } } $result = ['renamed' => $renamed, 'quarantined' => $quarantined, 'mapping_version' => 2, 'checksum' => $after['checksum']]; if ($renamed || $quarantined) { DB::table('audit_events')->insert(['source_system' => 'cartografia-workbook', 'entity_type' => 'geo_locations', 'action' => 'designation_mapping_corrected', 'after_data' => json_encode($result, JSON_THROW_ON_ERROR)]); } return $result; }); echo json_encode($result, JSON_THROW_ON_ERROR).PHP_EOL;