import { PrismaClient } from '@prisma/client'; import { PrismaPg } from '@prisma/adapter-pg'; import * as https from 'https'; import * as http from 'http'; const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); const prisma = new PrismaClient({ adapter }); // ─── HELPERS ────────────────────────────────────────────────────────────────── function fetch(url: string): Promise { return new Promise((resolve, reject) => { const client = url.startsWith('https') ? https : http; let data = ''; client.get(url, (res) => { if (res.statusCode === 301 || res.statusCode === 302) { return fetch(res.headers.location!).then(resolve).catch(reject); } res.on('data', (chunk) => (data += chunk)); res.on('end', () => resolve(data)); }).on('error', reject); }); } // ─── SEED UBIGEO INEI 2025 ──────────────────────────────────────────────────── async function seedUbigeo() { console.log('📍 Descargando ubigeos INEI 2025...'); const csv = await fetch('https://raw.githubusercontent.com/MichaelSuarez0/ubigeos_peru/main/databases/ubigeo_inei_2025.csv'); const lines = csv.trim().split('\n').slice(1); // skip header console.log(` ${lines.length} registros encontrados`); const depMap = new Map(); const provMap = new Map(); const distritos: any[] = []; for (const line of lines) { const parts = line.split(';'); if (parts.length < 10) continue; const [depNombre, provNombre, distNombre, ubigeo, capital, categoria, altitud, poblacion, lat, lon] = parts; if (!ubigeo || ubigeo.length !== 6) continue; const codDep = ubigeo.substring(0, 2); const codProv = ubigeo.substring(0, 4); const latNum = parseFloat(lat) || undefined; const lonNum = parseFloat(lon) || undefined; if (!depMap.has(codDep)) { depMap.set(codDep, { nombre: depNombre.trim(), lat: latNum, lon: lonNum }); } if (!provMap.has(codProv)) { provMap.set(codProv, { nombre: provNombre.trim(), depCod: codDep, lat: latNum, lon: lonNum }); } distritos.push({ codigo: ubigeo.trim(), codigoProv: codProv, codigoDep: codDep, nombre: distNombre.trim(), capital: capital?.trim() || null, categoria: categoria?.trim() || null, altitud: parseFloat(altitud) || null, poblacion: parseInt(poblacion) || null, latitud: latNum, longitud: lonNum, }); } console.log(` Departamentos: ${depMap.size} | Provincias: ${provMap.size} | Distritos: ${distritos.length}`); // Insertar departamentos console.log(' Insertando departamentos...'); await prisma.departamento.deleteMany(); for (const [codigo, { nombre, lat, lon }] of depMap) { await prisma.departamento.create({ data: { codigo, nombre, latitud: lat, longitud: lon }, }); } // Insertar provincias console.log(' Insertando provincias...'); await prisma.provincia.deleteMany(); for (const [codigo, { nombre, depCod, lat, lon }] of provMap) { await prisma.provincia.create({ data: { codigo, codigoDep: depCod, nombre, latitud: lat, longitud: lon }, }); } // Insertar distritos en batches console.log(' Insertando distritos...'); await prisma.distrito.deleteMany(); const batchSize = 100; for (let i = 0; i < distritos.length; i += batchSize) { const batch = distritos.slice(i, i + batchSize); await prisma.distrito.createMany({ data: batch, skipDuplicates: true }); process.stdout.write(`\r Progreso: ${Math.min(i + batchSize, distritos.length)}/${distritos.length}`); } console.log('\n ✅ Ubigeos insertados'); } // ─── SEED PAÍSES ────────────────────────────────────────────────────────────── async function seedPaises() { console.log('\n🌍 Descargando países del mundo...'); const raw = await fetch('https://restcountries.com/v3.1/all?fields=name,cca2,cca3,capital,region,subregion,latlng,flag'); const countries = JSON.parse(raw); console.log(` ${countries.length} países encontrados`); await prisma.pais.deleteMany(); const data = countries .filter((c: any) => c.cca3 && c.cca2) .map((c: any) => ({ codigo: c.cca3, codigoAlpha2: c.cca2, nombre: c.name?.translations?.spa?.official || c.name?.translations?.spa?.common || c.name?.common || '', nombreEn: c.name?.common || '', capital: Array.isArray(c.capital) ? c.capital[0] || '' : '', region: c.region || '', subregion: c.subregion || '', emoji: c.flag || '', latitud: c.latlng?.[0] || null, longitud: c.latlng?.[1] || null, })) .filter((c: any) => c.nombre); await prisma.pais.createMany({ data, skipDuplicates: true }); console.log(` ✅ ${data.length} países insertados`); } // ─── MAIN ───────────────────────────────────────────────────────────────────── async function main() { console.log('🚀 Iniciando seed...\n'); try { await seedUbigeo(); await seedPaises(); const stats = { departamentos: await prisma.departamento.count(), provincias: await prisma.provincia.count(), distritos: await prisma.distrito.count(), paises: await prisma.pais.count(), }; console.log('\n✅ Seed completado:'); console.log(` Departamentos: ${stats.departamentos}`); console.log(` Provincias: ${stats.provincias}`); console.log(` Distritos: ${stats.distritos}`); console.log(` Países: ${stats.paises}`); } catch (e) { console.error('❌ Error en seed:', e); process.exit(1); } finally { await prisma.$disconnect(); } } main();