// prisma/seeds/DemographicsSeeder.ts import { PrismaClient } from "@prisma/client"; export class DemographicsSeeder { constructor(private prisma: PrismaClient) { } async run(): Promise { console.log("Seeding demographics data..."); // Mendapatkan semua districts const districts = await this.prisma.districts.findMany(); const cities = await this.prisma.cities.findMany(); // Seed demografis untuk 6 tahun terakhir const currentYear = new Date().getFullYear(); const years = [currentYear - 5, currentYear - 4, currentYear - 3, currentYear - 2, currentYear - 1, currentYear]; // Menghapus data demographics yang sudah ada await this.prisma.$executeRaw`TRUNCATE TABLE "demographics" CASCADE`; let counter = 0; // Untuk tiap tahun for (const year of years) { // Pertama generate data level district const districtDemographics = []; for (const district of districts) { // Generate data demografis level district const districtPopulation = this.getRandomNumber(10000, 100000); const districtLandArea = await this.getDistrictLandArea(district.id); const districtDensity = districtLandArea > 0 ? districtPopulation / districtLandArea : this.getRandomNumber(500, 3000); const districtUnemployed = Math.floor(districtPopulation * this.getRandomNumber(0.03, 0.15)); // Simpan data district untuk agregasi level kota districtDemographics.push({ district_id: district.id, city_id: district.city_id, population: districtPopulation, unemployed: districtUnemployed, density: districtDensity }); // Simpan data demografis level district await this.prisma.demographics.create({ data: { city_id: district.city_id, district_id: district.id, year, population: districtPopulation, population_density: districtDensity, number_of_unemployed: districtUnemployed } }); counter++; } // Kemudian generate data level kota berdasarkan agregasi dari district for (const city of cities) { // Filter district demographics untuk kota ini const cityDistricts = districtDemographics.filter(d => d.city_id === city.id); if (cityDistricts.length > 0) { // Agregasi data dari semua district dalam kota const cityPopulation = cityDistricts.reduce((sum, d) => sum + d.population, 0); const cityUnemployed = cityDistricts.reduce((sum, d) => sum + d.unemployed, 0); // Hitung total land area kota const cityLandArea = await this.getCityLandArea(city.id); // Hitung kepadatan populasi kota const cityDensity = cityLandArea > 0 ? cityPopulation / cityLandArea : cityDistricts.reduce((sum, d) => sum + d.density, 0) / cityDistricts.length; // Simpan data demografis level kota await this.prisma.demographics.create({ data: { city_id: city.id, district_id: cityDistricts[0].district_id, // Menggunakan district pertama sebagai placeholder year, population: cityPopulation, population_density: cityDensity, number_of_unemployed: cityUnemployed } }); counter++; } } } console.log(`✅ ${counter} demographics records seeded`); } private getRandomNumber(min: number, max: number): number { return Math.random() * (max - min) + min; } private async getDistrictLandArea(districtId: string): Promise { const geo = await this.prisma.geographics.findFirst({ where: { district_id: districtId } }); return geo?.land_area || 0; } private async getCityLandArea(cityId: string): Promise { const geo = await this.prisma.geographics.findFirst({ where: { city_id: cityId, district_id: null } }); if (geo?.land_area) return geo.land_area; // Jika tidak ada data land area level kota, jumlahkan dari semua district const districtsGeo = await this.prisma.geographics.findMany({ where: { city_id: cityId, district_id: { not: null } } }); return districtsGeo.reduce((sum, geo) => sum + (geo.land_area || 0), 0); } }