import 'dotenv/config'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import db from '../src/database/models/index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const { Location, LocationHierarchy } = db; async function run() { console.log('--- Migrating Real Geo Data to Normalized Location Models ---'); try { // Read the original seeder file as text so we don't have to duplicate the 350 items const seederPath = path.join(__dirname, '../seeders/20240127-seed-geo-data.js'); const content = fs.readFileSync(seederPath, 'utf8'); // Extract the arrays using eval since it's a known static JS file const zonesMatch = content.match(/const ZONES_DATA = \[([\s\S]*?)\];/); const statesMatch = content.match(/const STATES_DATA = \[([\s\S]*?)\];/); const citiesMatch = content.match(/const CITIES_DATA = \[([\s\S]*?)\];/); if (!zonesMatch || !statesMatch || !citiesMatch) { throw new Error('Could not parse geo data arrays!'); } const ZONES_DATA = eval(`[${zonesMatch[1]}]`); const STATES_DATA = eval(`[${statesMatch[1]}]`); const CITIES_DATA = eval(`[${citiesMatch[1]}]`); console.log(`Extracted ${ZONES_DATA.length} Zones, ${STATES_DATA.length} States, and ${CITIES_DATA.length} Cities.`); // 1. Insert Zones const zoneIdMap = new Map(); for (const z of ZONES_DATA) { const [loc] = await Location.findOrCreate({ where: { name: z.name, type: 'zone' }, defaults: { name: z.name, type: 'zone' } }); zoneIdMap.set(z.code, loc.id); z._dbId = loc.id; } // 2. Insert States and link to Zones const stateIdMap = new Map(); for (const s of STATES_DATA) { const [loc] = await Location.findOrCreate({ where: { name: s.name, type: 'state' }, defaults: { name: s.name, type: 'state' } }); stateIdMap.set(s.id, loc.id); // Find which zone string array it belongs to const parentZone = ZONES_DATA.find((z: any) => z.states.includes(s.name)); if (parentZone) { await LocationHierarchy.findOrCreate({ where: { locationId: loc.id, parentId: parentZone._dbId }, defaults: { locationId: loc.id, parentId: parentZone._dbId } }); } } // 3. Insert Cities (Districts) and link to States let cityCount = 0; for (const c of CITIES_DATA) { const stateDbId = stateIdMap.get(c.state_id); if (stateDbId) { const [loc] = await Location.findOrCreate({ where: { name: c.name, type: 'district' }, defaults: { name: c.name, type: 'district' } }); await LocationHierarchy.findOrCreate({ where: { locationId: loc.id, parentId: stateDbId }, defaults: { locationId: loc.id, parentId: stateDbId } }); cityCount++; } } console.log(`✅ Successfully seeded Real Geo Data! Created ${cityCount} districts tied to their respective states and zones.`); process.exit(0); } catch (e: any) { console.error('❌ Failed:', e.message); process.exit(1); } } run();