Files
api-ubigeo/prisma/seed/seed.ts

165 lines
6.1 KiB
TypeScript

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<string> {
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<string, { nombre: string; lat?: number; lon?: number }>();
const provMap = new Map<string, { nombre: string; depCod: string; lat?: number; lon?: number }>();
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();