MIF_E31221222/sigap-website/prisma/seeds/demographic.ts

95 lines
2.6 KiB
TypeScript

// prisma/seeds/DemographicsSeeder.ts
import { PrismaClient } from '@prisma/client';
import path from 'path';
import XLSX from 'xlsx';
export class DemographicsSeeder {
constructor(private prisma: PrismaClient) {}
async run(): Promise<void> {
console.log('📥 Seeding demographics data from Excel...');
// Clear existing data
await this.prisma.demographics.deleteMany({});
const districts = await this.prisma.districts.findMany();
// await this.prisma.$executeRaw`TRUNCATE TABLE "demographics" CASCADE`;
// Load Excel
const filePath = path.join(
__dirname,
'../data/excels/administrations/demographics.xlsx'
);
const workbook = XLSX.readFile(filePath);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = XLSX.utils.sheet_to_json(sheet) as any[];
let counter = 0;
for (const row of data) {
const districtName = String(row['Kecamatan']).trim();
const year = Number(row['Tahun']);
const population = Number(row['Jumlah_Penduduk']);
const unemployed = Number(row['Jumlah_Pengangguran']);
const district = districts.find(
(d) => d.name.toLowerCase() === districtName.toLowerCase()
);
if (!district) {
console.warn(`⚠️ District "${districtName}" not found in database.`);
continue;
}
const districtLandArea = await this.getDistrictLandArea(district.id);
const populationDensity =
districtLandArea > 0 ? population / districtLandArea : 0;
await this.prisma.demographics.create({
data: {
district_id: district.id,
year,
population,
population_density: populationDensity,
number_of_unemployed: unemployed,
},
});
counter++;
console.log(
`Seeding demographic data for district: ${districtName}, year: ${year}`
);
}
console.log(`${counter} demographic records seeded from Excel`);
}
private getRandomNumber(min: number, max: number): number {
return Math.random() * (max - min) + min;
}
private async getDistrictLandArea(districtId: string): Promise<number> {
const geo = await this.prisma.geographics.findFirst({
where: { district_id: districtId },
select: {
land_area: true,
},
});
if (!geo) {
console.error(`⚠️ Land area not found for district ID: ${districtId}`);
return 0;
}
return geo.land_area || 0;
}
private async getCityLandArea(): Promise<number> {
const districtsGeo = await this.prisma.locations.findMany({});
return districtsGeo.reduce((sum, geo) => sum + (geo.land_area || 0), 0);
}
}