diff --git a/prisma/_seeder_list/kesehatan/seed_balita.ts b/prisma/_seeder_list/kesehatan/seed_balita.ts new file mode 100644 index 00000000..574a0c46 --- /dev/null +++ b/prisma/_seeder_list/kesehatan/seed_balita.ts @@ -0,0 +1,502 @@ +import prisma from "@/lib/prisma"; +import { JenisKelaminBalita, StatusStunting } from "@prisma/client"; + +// Fokus data: proporsi stunting realistis untuk simulasi dashboard +// 10 STUNTING, 7 ALERT, 8 NORMAL dari 25 total +const BALITA_DATA = [ + // ===== STUNTING (TB/U < -2 SD dari median WHO) ===== + { + id: "balita_001", + nama: "Wayan Aditya Pratama", + nik: "5101014505230001", + tanggalLahir: new Date("2023-05-04"), // 36 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 11.5, + tinggiBadanCm: 83.0, // median 96cm, -2SD ~89cm + namaOrtu: "I Wayan Suardika", + alamat: "Banjar Pudak, Desa Darmasaba", + noHpOrtu: "08123456801", + posyanduId: "cmkanjnmx0006vntz1cn7owpb", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.8 SD. Dalam program PMT (Pemberian Makanan Tambahan). Orang tua sudah mendapat konseling gizi.", + }, + { + id: "balita_002", + nama: "Ni Kadek Mira Sari", + nik: "5101014501240002", + tanggalLahir: new Date("2024-01-04"), // 16 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 7.8, + tinggiBadanCm: 70.5, // median ~78cm + namaOrtu: "I Kadek Suartha", + alamat: "Banjar Dahlia, Desa Darmasaba", + noHpOrtu: "08123456802", + posyanduId: "posyandu_dahlia_001", + imunisasiLengkap: false, + giziBaik: false, + pemeriksaanRutin: false, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -3.1 SD. Imunisasi belum lengkap. Ibu bekerja, kunjungan posyandu tidak rutin. Perlu pendampingan kader.", + }, + { + id: "balita_003", + nama: "Putu Rian Saputra", + nik: "5101014501220003", + tanggalLahir: new Date("2022-01-04"), // 40 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 12.5, + tinggiBadanCm: 89.0, // median 103cm + namaOrtu: "Ni Putu Sumiati", + alamat: "Banjar Dahlia, Desa Darmasaba", + noHpOrtu: "08123456803", + posyanduId: "posyandu_dahlia_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -3.2 SD. Sudah dirujuk ke Puskesmas Abiansemal 3 untuk pemeriksaan lebih lanjut.", + }, + { + id: "balita_004", + nama: "Ni Komang Ayu Lestari", + nik: "5101014507230004", + tanggalLahir: new Date("2023-07-04"), // 22 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 8.2, + tinggiBadanCm: 74.0, // median ~84cm + namaOrtu: "I Komang Sudiarta", + alamat: "Banjar Anggrek, Desa Darmasaba", + noHpOrtu: "08123456804", + posyanduId: "posyandu_anggrek_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.5 SD. Riwayat BBLR (berat lahir rendah) 2.3 kg.", + }, + { + id: "balita_005", + nama: "Ketut Agus Pratama", + nik: "5101014507240005", + tanggalLahir: new Date("2024-07-04"), // 10 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 6.9, + tinggiBadanCm: 66.0, // median ~72cm + namaOrtu: "Ni Ketut Sariani", + alamat: "Banjar Kamboja, Desa Darmasaba", + noHpOrtu: "08123456805", + posyanduId: "posyandu_kamboja_001", + imunisasiLengkap: false, + giziBaik: false, + pemeriksaanRutin: false, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.3 SD. Lahir prematur 35 minggu. Keluarga prasejahtera, masuk program PKH.", + }, + { + id: "balita_006", + nama: "Ni Made Sinta Dewi", + nik: "5101014507220006", + tanggalLahir: new Date("2022-07-04"), // 34 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 11.0, + tinggiBadanCm: 84.5, // median ~94cm + namaOrtu: "I Made Sudarsana", + alamat: "Banjar Melur, Desa Darmasaba", + noHpOrtu: "08123456806", + posyanduId: "posyandu_melur_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.6 SD. Nafsu makan rendah, sedang dalam pantauan ahli gizi Puskesmas.", + }, + { + id: "balita_007", + nama: "Made Dani Putra", + nik: "5101014501250007", + tanggalLahir: new Date("2025-01-04"), // 4 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 5.0, + tinggiBadanCm: 57.0, // median ~63cm + namaOrtu: "Ni Made Suparni", + alamat: "Banjar Kenanga, Desa Darmasaba", + noHpOrtu: "08123456807", + posyanduId: "posyandu_kenanga_001", + imunisasiLengkap: false, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.4 SD. BBLR 2.1 kg, ibu ASI eksklusif. Kunjungan rutin ke posyandu.", + }, + { + id: "balita_008", + nama: "Ni Putu Ratna Sari", + nik: "5101014507210008", + tanggalLahir: new Date("2021-07-04"), // 46 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 13.0, + tinggiBadanCm: 92.0, // median ~106cm + namaOrtu: "I Putu Suarjana", + alamat: "Banjar Mawar, Desa Darmasaba", + noHpOrtu: "08123456808", + posyanduId: "posyandu_mawar_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.9 SD. Sudah 6 bulan dalam program intervensi stunting desa.", + }, + { + id: "balita_009", + nama: "Gede Yoga Pratama", + nik: "5101014505210009", + tanggalLahir: new Date("2021-05-04"), // 48 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 13.5, + tinggiBadanCm: 91.0, // median ~108cm + namaOrtu: "Ni Wayan Suarningsih", + alamat: "Banjar Pudak, Desa Darmasaba", + noHpOrtu: "08123456809", + posyanduId: "cmkanjnmx0006vntz1cn7owpb", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: false, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -3.0 SD. Keluarga baru pindah dari luar desa. Sedang proses pendataan ulang.", + }, + { + id: "balita_010", + nama: "Ni Nyoman Sari Utami", + nik: "5101014505230010", + tanggalLahir: new Date("2023-05-04"), // 24 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 9.5, + tinggiBadanCm: 80.0, // median ~87cm + namaOrtu: "I Nyoman Sueca", + alamat: "Banjar Melati, Desa Darmasaba", + noHpOrtu: "08123456810", + posyanduId: "posyandu_melati_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.STUNTING, + catatan: "TB/U -2.2 SD. Batas bawah stunting. Perlu dipantau ketat tiap bulan.", + }, + + // ===== ALERT (TB/U antara -1 SD dan -2 SD) ===== + { + id: "balita_011", + nama: "Wayan Krisna Dewa", + nik: "5101014501240011", + tanggalLahir: new Date("2024-01-04"), // 16 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 9.8, + tinggiBadanCm: 74.0, // median ~78cm, -1SD ~75cm + namaOrtu: "I Wayan Artana", + alamat: "Banjar Mawar, Desa Darmasaba", + noHpOrtu: "08123456811", + posyanduId: "posyandu_mawar_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.5 SD. Perlu pemantauan lebih lanjut, gizi cukup baik.", + }, + { + id: "balita_012", + nama: "Ni Wayan Novi Andriani", + nik: "5101014505230012", + tanggalLahir: new Date("2023-05-04"), // 24 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 10.8, + tinggiBadanCm: 83.0, // median ~87cm + namaOrtu: "Ni Wayan Artini", + alamat: "Banjar Melati, Desa Darmasaba", + noHpOrtu: "08123456812", + posyanduId: "posyandu_melati_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.8 SD. Nafsu makan baik, BB naik konsisten.", + }, + { + id: "balita_013", + nama: "Putu Deva Mahendra", + nik: "5101014511240013", + tanggalLahir: new Date("2024-11-04"), // 6 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 6.8, + tinggiBadanCm: 63.5, // median ~67cm + namaOrtu: "I Putu Ariana", + alamat: "Banjar Anggrek, Desa Darmasaba", + noHpOrtu: "08123456813", + posyanduId: "posyandu_anggrek_001", + imunisasiLengkap: false, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.6 SD. ASI eksklusif. Jadwal imunisasi DPT ketiga belum terlaksana.", + }, + { + id: "balita_014", + nama: "Ni Komang Dewi Lestari", + nik: "5101014501220014", + tanggalLahir: new Date("2022-01-04"), // 40 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 14.0, + tinggiBadanCm: 96.0, // median ~103cm + namaOrtu: "I Komang Wirawan", + alamat: "Banjar Kamboja, Desa Darmasaba", + noHpOrtu: "08123456814", + posyanduId: "posyandu_kamboja_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.4 SD. Konsumsi protein hewani belum cukup, edukasi diberikan.", + }, + { + id: "balita_015", + nama: "Made Surya Darma", + nik: "5101014511230015", + tanggalLahir: new Date("2023-11-04"), // 18 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 10.2, + tinggiBadanCm: 76.0, // median ~82cm + namaOrtu: "Ni Made Sudarmi", + alamat: "Banjar Melur, Desa Darmasaba", + noHpOrtu: "08123456815", + posyanduId: "posyandu_melur_001", + imunisasiLengkap: true, + giziBaik: false, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.9 SD. Sedang mendapat PMT (makanan tambahan) dari desa.", + }, + { + id: "balita_016", + nama: "Ni Kadek Ayu Purnami", + nik: "5101014505250016", + tanggalLahir: new Date("2025-05-04"), // 0 bulan (baru lahir - 1 bulan) + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 3.5, + tinggiBadanCm: 49.0, // median ~52cm + namaOrtu: "I Kadek Suartha", + alamat: "Banjar Kenanga, Desa Darmasaba", + noHpOrtu: "08123456816", + posyanduId: "posyandu_kenanga_001", + imunisasiLengkap: false, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.7 SD. Bayi baru, lahir 2.8 kg. Dipantau dari awal.", + }, + { + id: "balita_017", + nama: "Ketut Bayu Setiawan", + nik: "5101014511220017", + tanggalLahir: new Date("2022-11-04"), // 30 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 13.2, + tinggiBadanCm: 88.0, // median ~93cm + namaOrtu: "Ni Ketut Suarni", + alamat: "Banjar Dahlia, Desa Darmasaba", + noHpOrtu: "08123456817", + posyanduId: "posyandu_dahlia_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.ALERT, + catatan: "TB/U -1.3 SD. Tumbuh kembang membaik dalam 3 bulan terakhir.", + }, + + // ===== NORMAL ===== + { + id: "balita_018", + nama: "Ni Made Intan Permata", + nik: "5101014501240018", + tanggalLahir: new Date("2024-01-04"), // 16 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 10.5, + tinggiBadanCm: 78.0, + namaOrtu: "I Made Sudiarsa", + alamat: "Banjar Mawar, Desa Darmasaba", + noHpOrtu: "08123456818", + posyanduId: "posyandu_mawar_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_019", + nama: "Wayan Arya Nugraha", + nik: "5101014505230019", + tanggalLahir: new Date("2023-05-04"), // 24 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 12.0, + tinggiBadanCm: 87.0, + namaOrtu: "Ni Wayan Suarni", + alamat: "Banjar Pudak, Desa Darmasaba", + noHpOrtu: "08123456819", + posyanduId: "cmkanjnmx0006vntz1cn7owpb", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_020", + nama: "Ni Putu Cantika Dewi", + nik: "5101014501220020", + tanggalLahir: new Date("2022-01-04"), // 40 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 15.5, + tinggiBadanCm: 103.0, + namaOrtu: "I Putu Sudiarta", + alamat: "Banjar Melati, Desa Darmasaba", + noHpOrtu: "08123456820", + posyanduId: "posyandu_melati_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_021", + nama: "Komang Danu Mahesa", + nik: "5101014505250021", + tanggalLahir: new Date("2025-05-04"), // 0 bulan (newborn) + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 3.8, + tinggiBadanCm: 52.0, + namaOrtu: "Ni Komang Artini", + alamat: "Banjar Anggrek, Desa Darmasaba", + noHpOrtu: "08123456821", + posyanduId: "posyandu_anggrek_001", + imunisasiLengkap: false, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_022", + nama: "Ni Nyoman Suka Rani", + nik: "5101014505210022", + tanggalLahir: new Date("2021-05-04"), // 48 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 16.5, + tinggiBadanCm: 105.0, + namaOrtu: "I Nyoman Suarman", + alamat: "Banjar Kamboja, Desa Darmasaba", + noHpOrtu: "08123456822", + posyanduId: "posyandu_kamboja_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_023", + nama: "Made Giri Putra Santosa", + nik: "5101014511240023", + tanggalLahir: new Date("2024-11-04"), // 6 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 8.1, + tinggiBadanCm: 67.5, + namaOrtu: "Ni Made Suciati", + alamat: "Banjar Melur, Desa Darmasaba", + noHpOrtu: "08123456823", + posyanduId: "posyandu_melur_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_024", + nama: "Ni Wayan Arta Yanti", + nik: "5101014511230024", + tanggalLahir: new Date("2023-11-04"), // 18 bulan + jenisKelamin: JenisKelaminBalita.P, + beratBadanKg: 11.0, + tinggiBadanCm: 82.0, + namaOrtu: "I Wayan Suarsa", + alamat: "Banjar Kenanga, Desa Darmasaba", + noHpOrtu: "08123456824", + posyanduId: "posyandu_kenanga_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, + { + id: "balita_025", + nama: "Kadek Dika Permana", + nik: "5101014511220025", + tanggalLahir: new Date("2022-11-04"), // 30 bulan + jenisKelamin: JenisKelaminBalita.L, + beratBadanKg: 14.0, + tinggiBadanCm: 93.0, + namaOrtu: "Ni Kadek Suriati", + alamat: "Banjar Dahlia, Desa Darmasaba", + noHpOrtu: "08123456825", + posyanduId: "posyandu_dahlia_001", + imunisasiLengkap: true, + giziBaik: true, + pemeriksaanRutin: true, + statusStunting: StatusStunting.NORMAL, + }, +]; + +export async function seedBalita() { + console.log("🔄 Seeding Balita..."); + + for (const d of BALITA_DATA) { + await prisma.balita.upsert({ + where: { id: d.id }, + update: { + nama: d.nama, + nik: d.nik, + tanggalLahir: d.tanggalLahir, + jenisKelamin: d.jenisKelamin, + beratBadanKg: d.beratBadanKg, + tinggiBadanCm: d.tinggiBadanCm, + namaOrtu: d.namaOrtu, + alamat: d.alamat, + noHpOrtu: d.noHpOrtu, + posyanduId: d.posyanduId, + imunisasiLengkap: d.imunisasiLengkap, + giziBaik: d.giziBaik, + pemeriksaanRutin: d.pemeriksaanRutin, + statusStunting: d.statusStunting, + catatan: d.catatan ?? null, + }, + create: { + id: d.id, + nama: d.nama, + nik: d.nik, + tanggalLahir: d.tanggalLahir, + jenisKelamin: d.jenisKelamin, + beratBadanKg: d.beratBadanKg, + tinggiBadanCm: d.tinggiBadanCm, + namaOrtu: d.namaOrtu, + alamat: d.alamat, + noHpOrtu: d.noHpOrtu, + posyanduId: d.posyanduId, + imunisasiLengkap: d.imunisasiLengkap, + giziBaik: d.giziBaik, + pemeriksaanRutin: d.pemeriksaanRutin, + statusStunting: d.statusStunting, + catatan: d.catatan ?? null, + }, + }); + console.log(`✅ Balita seeded: ${d.nama} (${d.statusStunting})`); + } + + console.log("🎉 Balita seed selesai"); +} diff --git a/prisma/_seeder_list/kesehatan/seed_ibu_hamil.ts b/prisma/_seeder_list/kesehatan/seed_ibu_hamil.ts new file mode 100644 index 00000000..9959b666 --- /dev/null +++ b/prisma/_seeder_list/kesehatan/seed_ibu_hamil.ts @@ -0,0 +1,222 @@ +import prisma from "@/lib/prisma"; +import { IbuHamilStatus } from "@prisma/client"; + +const IBU_HAMIL_DATA = [ + { + id: "ibu_hamil_001", + nama: "Ni Wayan Sari Dewi", + nik: "5101014504960001", + usiaKehamilan: 28, + hpht: new Date("2025-10-20"), + taksiranLahir: new Date("2026-07-26"), + alamat: "Banjar Pudak, Desa Darmasaba", + noHp: "08123456701", + posyanduId: "cmkanjnmx0006vntz1cn7owpb", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_002", + nama: "Ni Made Artini", + nik: "5101012808980002", + usiaKehamilan: 16, + hpht: new Date("2026-01-13"), + taksiranLahir: new Date("2026-10-20"), + alamat: "Banjar Mawar, Desa Darmasaba", + noHp: "08123456702", + posyanduId: "posyandu_mawar_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_003", + nama: "Ni Putu Rahayu", + nik: "5101010109000003", + usiaKehamilan: 32, + hpht: new Date("2025-09-22"), + taksiranLahir: new Date("2026-06-29"), + alamat: "Banjar Melati, Desa Darmasaba", + noHp: "08123456703", + posyanduId: "posyandu_melati_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_004", + nama: "Ni Komang Lestari", + nik: "5101011505010004", + usiaKehamilan: 8, + hpht: new Date("2026-03-10"), + taksiranLahir: new Date("2026-12-14"), + alamat: "Banjar Dahlia, Desa Darmasaba", + noHp: "08123456704", + posyanduId: "posyandu_dahlia_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_005", + nama: "Ni Nyoman Suartini", + nik: "5101012012990005", + usiaKehamilan: 24, + hpht: new Date("2025-11-17"), + taksiranLahir: new Date("2026-08-24"), + alamat: "Banjar Anggrek, Desa Darmasaba", + noHp: "08123456705", + posyanduId: "posyandu_anggrek_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_006", + nama: "Ni Ketut Suriani", + nik: "5101010307970006", + usiaKehamilan: 20, + hpht: new Date("2025-12-15"), + taksiranLahir: new Date("2026-09-21"), + alamat: "Banjar Kamboja, Desa Darmasaba", + noHp: "08123456706", + posyanduId: "posyandu_kamboja_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_007", + nama: "Ni Wayan Rustini", + nik: "5101011806960007", + usiaKehamilan: 36, + hpht: new Date("2025-08-25"), + taksiranLahir: new Date("2026-06-01"), + alamat: "Banjar Melur, Desa Darmasaba", + noHp: "08123456707", + posyanduId: "posyandu_melur_001", + status: IbuHamilStatus.AKTIF, + catatan: "Tekanan darah perlu dipantau rutin", + }, + { + id: "ibu_hamil_008", + nama: "Ni Made Sudiani", + nik: "5101010202020008", + usiaKehamilan: 12, + hpht: new Date("2026-02-10"), + taksiranLahir: new Date("2026-11-17"), + alamat: "Banjar Kenanga, Desa Darmasaba", + noHp: "08123456708", + posyanduId: "posyandu_kenanga_001", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_009", + nama: "Ni Putu Yuliani", + nik: "5101011507980009", + usiaKehamilan: 28, + hpht: new Date("2025-10-20"), + taksiranLahir: new Date("2026-07-26"), + alamat: "Banjar Pudak, Desa Darmasaba", + noHp: "08123456709", + posyanduId: "cmkanjnmx0006vntz1cn7owpb", + status: IbuHamilStatus.AKTIF, + }, + { + id: "ibu_hamil_010", + nama: "Ni Nyoman Darmayanti", + nik: "5101012309010010", + usiaKehamilan: 16, + hpht: new Date("2026-01-13"), + taksiranLahir: new Date("2026-10-20"), + alamat: "Banjar Mawar, Desa Darmasaba", + noHp: "08123456710", + posyanduId: "posyandu_mawar_001", + status: IbuHamilStatus.AKTIF, + catatan: "Anemia ringan, konsumsi suplemen zat besi", + }, + { + id: "ibu_hamil_011", + nama: "Ni Wayan Purwati", + nik: "5101010905950011", + usiaKehamilan: 40, + hpht: new Date("2025-07-28"), + taksiranLahir: new Date("2026-05-04"), + alamat: "Banjar Melati, Desa Darmasaba", + noHp: "08123456711", + posyanduId: "posyandu_melati_001", + status: IbuHamilStatus.MELAHIRKAN, + catatan: "Melahirkan normal di Puskesmas Abiansemal 3", + }, + { + id: "ibu_hamil_012", + nama: "Ni Made Suarningsih", + nik: "5101011403930012", + usiaKehamilan: 39, + hpht: new Date("2025-08-04"), + taksiranLahir: new Date("2026-05-11"), + alamat: "Banjar Dahlia, Desa Darmasaba", + noHp: "08123456712", + posyanduId: "posyandu_dahlia_001", + status: IbuHamilStatus.MELAHIRKAN, + }, + { + id: "ibu_hamil_013", + nama: "Ni Komang Sugiantari", + nik: "5101012706010013", + usiaKehamilan: 10, + alamat: "Banjar Anggrek, Desa Darmasaba", + noHp: "08123456713", + posyanduId: "posyandu_anggrek_001", + status: IbuHamilStatus.KEGUGURAN, + catatan: "Keguguran pada usia kehamilan 10 minggu, sudah ditangani", + }, + { + id: "ibu_hamil_014", + nama: "Ni Putu Aryanti", + nik: "5101010508940014", + usiaKehamilan: 0, + alamat: "Banjar Kamboja, Desa Darmasaba", + noHp: "08123456714", + posyanduId: "posyandu_kamboja_001", + status: IbuHamilStatus.NONAKTIF, + catatan: "Data lama, tidak aktif terdaftar", + }, + { + id: "ibu_hamil_015", + nama: "Ni Ketut Suparmi", + nik: "5101011912920015", + usiaKehamilan: 0, + alamat: "Banjar Melur, Desa Darmasaba", + noHp: "08123456715", + posyanduId: "posyandu_melur_001", + status: IbuHamilStatus.NONAKTIF, + }, +]; + +export async function seedIbuHamil() { + console.log("🔄 Seeding Ibu Hamil..."); + + for (const d of IBU_HAMIL_DATA) { + await prisma.ibuHamil.upsert({ + where: { id: d.id }, + update: { + nama: d.nama, + nik: d.nik, + usiaKehamilan: d.usiaKehamilan, + hpht: d.hpht ?? null, + taksiranLahir: d.taksiranLahir ?? null, + alamat: d.alamat, + noHp: d.noHp, + posyanduId: d.posyanduId, + status: d.status, + catatan: d.catatan ?? null, + }, + create: { + id: d.id, + nama: d.nama, + nik: d.nik, + usiaKehamilan: d.usiaKehamilan, + hpht: d.hpht ?? null, + taksiranLahir: d.taksiranLahir ?? null, + alamat: d.alamat, + noHp: d.noHp, + posyanduId: d.posyanduId, + status: d.status, + catatan: d.catatan ?? null, + }, + }); + console.log(`✅ Ibu hamil seeded: ${d.nama} (${d.status})`); + } + + console.log("🎉 Ibu Hamil seed selesai"); +} diff --git a/prisma/_seeder_list/kesehatan/seed_ringkasan_kesehatan.ts b/prisma/_seeder_list/kesehatan/seed_ringkasan_kesehatan.ts index 482a0ec9..9f43b5b7 100644 --- a/prisma/_seeder_list/kesehatan/seed_ringkasan_kesehatan.ts +++ b/prisma/_seeder_list/kesehatan/seed_ringkasan_kesehatan.ts @@ -7,17 +7,8 @@ export async function seedRingkasanKesehatan() { await prisma.ringkasanKesehatanDesa.upsert({ where: { id: SINGLETON_ID }, - update: { - ibuHamilAkh: 87, - balitaTerdaftar: 342, - alertStunting: 12, - }, - create: { - id: SINGLETON_ID, - ibuHamilAkh: 87, - balitaTerdaftar: 342, - alertStunting: 12, - }, + update: { targetStuntingPct: 10 }, + create: { id: SINGLETON_ID, targetStuntingPct: 10 }, }); console.log("✅ Ringkasan Kesehatan Desa seeded"); diff --git a/prisma/migrations/20260504200000_slim_ringkasan_kesehatan_desa/migration.sql b/prisma/migrations/20260504200000_slim_ringkasan_kesehatan_desa/migration.sql new file mode 100644 index 00000000..e6c72169 --- /dev/null +++ b/prisma/migrations/20260504200000_slim_ringkasan_kesehatan_desa/migration.sql @@ -0,0 +1,9 @@ +-- Drop redundant columns from RingkasanKesehatanDesa. +-- These values are auto-derived live from IbuHamil + Balita tables (see stats endpoint). +-- Only targetStuntingPct is a policy config that needs to be stored. +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "ibuHamilAkh"; +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "balitaTerdaftar"; +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "alertStunting"; +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "imunisasiLengkapPct"; +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "pemeriksaanRutinPct"; +ALTER TABLE "RingkasanKesehatanDesa" DROP COLUMN "giziBaikPct"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 672b7925..4e9b1419 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -2546,16 +2546,10 @@ model Balita { // ========================================= RINGKASAN KESEHATAN DESA ========================================= // model RingkasanKesehatanDesa { - id String @id @default(cuid()) - ibuHamilAkh Int @default(0) - balitaTerdaftar Int @default(0) - alertStunting Int @default(0) - imunisasiLengkapPct Int @default(0) - pemeriksaanRutinPct Int @default(0) - giziBaikPct Int @default(0) - targetStuntingPct Int @default(0) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - isActive Boolean @default(true) + id String @id @default(cuid()) + targetStuntingPct Int @default(0) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + isActive Boolean @default(true) } diff --git a/prisma/seed.ts b/prisma/seed.ts index a67f08c1..c8803e20 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -48,6 +48,8 @@ import { seedPuskesmas } from "./_seeder_list/kesehatan/puskesmas/seed_puskesmas import { seedGrafikKepuasan } from "./_seeder_list/kesehatan/seed_grafik_kepuasan"; import { seedKelahiranKematian } from "./_seeder_list/kesehatan/seed_kelahiran_kematian"; import { seedRingkasanKesehatan } from "./_seeder_list/kesehatan/seed_ringkasan_kesehatan"; +import { seedIbuHamil } from "./_seeder_list/kesehatan/seed_ibu_hamil"; +import { seedBalita } from "./_seeder_list/kesehatan/seed_balita"; import { seedDesaAntiKorupsi } from "./_seeder_list/landing-page/desa-anti-korupsi/seed_desa_anti_korupsi"; import { seedPrestasiDesa } from "./_seeder_list/landing-page/prestasi-desa/seed_prestasi_desa"; import { seedMediaSosial } from "./_seeder_list/landing-page/profil_landing_page/seed_media_sosial"; @@ -244,6 +246,10 @@ import seedAssets from "./seed_assets"; // // ==================== SUBMENU POSYANDU ========================= await seedPosyandu(); + // // ==================== SUBMENU IBU HAMIL + BALITA ========================= + await seedIbuHamil(); + await seedBalita(); + // // ==================== SUBMENU PUSKESMAS ========================= await seedPuskesmas(); diff --git a/src/app/admin/(dashboard)/_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan.ts b/src/app/admin/(dashboard)/_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan.ts index 6fa5b2d1..5728bac9 100644 --- a/src/app/admin/(dashboard)/_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan.ts +++ b/src/app/admin/(dashboard)/_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan.ts @@ -1,4 +1,3 @@ -import { Prisma } from "@prisma/client"; import { toast } from "react-toastify"; import { proxy } from "valtio"; import { z } from "zod"; @@ -19,33 +18,7 @@ const intPct = z .min(0, { message: "Minimal 0" }) .max(100, { message: "Maksimal 100" }); -const intCount = z - .number({ invalid_type_error: "Harus berupa angka" }) - .int({ message: "Harus bilangan bulat" }) - .min(0, { message: "Minimal 0" }); - -const templateForm = z.object({ - ibuHamilAkh: intCount, - balitaTerdaftar: intCount, - alertStunting: intCount, - imunisasiLengkapPct: intPct, - pemeriksaanRutinPct: intPct, - giziBaikPct: intPct, - targetStuntingPct: intPct, -}); - -const defaultForm = { - ibuHamilAkh: 0, - balitaTerdaftar: 0, - alertStunting: 0, - imunisasiLengkapPct: 0, - pemeriksaanRutinPct: 0, - giziBaikPct: 0, - targetStuntingPct: 0, -}; - const ringkasanKesehatanState = proxy({ - // Derived stats aggregated from IbuHamil + Balita tables findStats: { data: null as StatsData | null, loading: false, @@ -57,7 +30,8 @@ const ringkasanKesehatanState = proxy({ const result = await res.json(); ringkasanKesehatanState.findStats.data = result?.data ?? null; if (result?.data) { - ringkasanKesehatanState.update.form.targetStuntingPct = result.data.targetStuntingPct; + ringkasanKesehatanState.update.form.targetStuntingPct = + result.data.targetStuntingPct; } } else { ringkasanKesehatanState.findStats.data = null; @@ -71,42 +45,8 @@ const ringkasanKesehatanState = proxy({ }, }, - // Kept for backward-compat — now only used internally for targetStuntingPct config - findUnique: { - data: null as Prisma.RingkasanKesehatanDesaGetPayload | null, - loading: false, - async load() { - try { - ringkasanKesehatanState.findUnique.loading = true; - const res = await fetch(`/api/kesehatan/ringkasankesehatan/find`); - if (res.ok) { - const result = await res.json(); - ringkasanKesehatanState.findUnique.data = result?.data ?? null; - if (result?.data) { - ringkasanKesehatanState.update.form = { - ibuHamilAkh: result.data.ibuHamilAkh, - balitaTerdaftar: result.data.balitaTerdaftar, - alertStunting: result.data.alertStunting, - imunisasiLengkapPct: result.data.imunisasiLengkapPct, - pemeriksaanRutinPct: result.data.pemeriksaanRutinPct, - giziBaikPct: result.data.giziBaikPct, - targetStuntingPct: result.data.targetStuntingPct, - }; - } - } else { - ringkasanKesehatanState.findUnique.data = null; - } - } catch (error) { - console.error("Error fetching ringkasan kesehatan:", error); - ringkasanKesehatanState.findUnique.data = null; - } finally { - ringkasanKesehatanState.findUnique.loading = false; - } - }, - }, - update: { - form: { ...defaultForm }, + form: { targetStuntingPct: 0 }, loading: false, async submitTarget() { const pct = ringkasanKesehatanState.update.form.targetStuntingPct; @@ -120,7 +60,7 @@ const ringkasanKesehatanState = proxy({ const response = await fetch(`/api/kesehatan/ringkasankesehatan/update`, { method: "PUT", headers: { "Content-Type": "application/json" }, - body: JSON.stringify(ringkasanKesehatanState.update.form), + body: JSON.stringify({ targetStuntingPct: pct }), }); const result = await response.json(); if (result.success) { @@ -138,41 +78,6 @@ const ringkasanKesehatanState = proxy({ ringkasanKesehatanState.update.loading = false; } }, - // Kept for backward-compat (full update) - async submit() { - const cek = templateForm.safeParse(ringkasanKesehatanState.update.form); - if (!cek.success) { - const err = `[${cek.error.issues - .map((v) => `${v.path.join(".")}`) - .join("\n")}] invalid`; - toast.error(err); - return false; - } - try { - ringkasanKesehatanState.update.loading = true; - const response = await fetch(`/api/kesehatan/ringkasankesehatan/update`, { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(ringkasanKesehatanState.update.form), - }); - const result = await response.json(); - if (result.success) { - toast.success(result.message || "Berhasil disimpan"); - await ringkasanKesehatanState.findUnique.load(); - return true; - } - throw new Error(result.message || "Gagal menyimpan"); - } catch (error) { - console.error("Error updating ringkasan kesehatan:", error); - toast.error(error instanceof Error ? error.message : "Gagal menyimpan"); - return false; - } finally { - ringkasanKesehatanState.update.loading = false; - } - }, - reset() { - ringkasanKesehatanState.update.form = { ...defaultForm }; - }, }, }); diff --git a/src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx index edcff128..7953dffe 100644 --- a/src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/ringkasan-kesehatan/page.tsx @@ -24,7 +24,7 @@ import { IconAlertTriangle, } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; +import { useEffect, useCallback } from 'react'; import { useProxy } from 'valtio/utils'; import ringkasanKesehatanState from '../../_state/kesehatan/ringkasan-kesehatan/ringkasanKesehatan'; @@ -71,13 +71,8 @@ export default function RingkasanKesehatanPage() { const state = useProxy(ringkasanKesehatanState); const stats = state.findStats.data; - useEffect(() => { - state.findStats.load(); - }, []); // eslint-disable-line react-hooks/exhaustive-deps - - const handleSaveTarget = async () => { - await state.update.submitTarget(); - }; + const loadStats = useCallback(() => { ringkasanKesehatanState.findStats.load(); }, []); + useEffect(() => { loadStats(); }, [loadStats]); const isLoading = state.findStats.loading; @@ -175,7 +170,7 @@ export default function RingkasanKesehatanPage() { style={{ flex: 1 }} />