91 lines
3.5 KiB
TypeScript
91 lines
3.5 KiB
TypeScript
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();
|