generated from MuhammadIqbalMaulana/UAS-SIG
166 lines
7.2 KiB
JavaScript
166 lines
7.2 KiB
JavaScript
const db = require('../config/database');
|
|
|
|
// Mengambil data status bantuan warga beserta lokasi pangkalan ibadah
|
|
const cek_status_nik = (req, res) => {
|
|
const nik_warga = req.params.nik;
|
|
|
|
// Praktik keamanan: Memastikan input NIK murni berupa 16 digit angka untuk mencegah manipulasi query
|
|
if (!/^\d{16}$/.test(nik_warga)) {
|
|
return res.status(400).json({ error: 'Format NIK tidak valid.' });
|
|
}
|
|
|
|
// Baris kompleks: Operasi LEFT JOIN menghubungkan tabel MUSTAHIK dengan RUMAH_IBADAH berdasarkan Foreign Key id_rumah_ibadah untuk menarik koordinat pangkalan distribusi secara simultan dalam satu siklus I/O.
|
|
const kueri_pencarian = `
|
|
SELECT m.nik, m.nama_kk, m.status_validasi, m.lat, m.lng, m.agama,
|
|
r.nama_tempat AS rumah_ibadah_nama,
|
|
r.lat AS rumah_ibadah_lat,
|
|
r.lng AS rumah_ibadah_lng
|
|
FROM MUSTAHIK m
|
|
LEFT JOIN RUMAH_IBADAH r ON m.id_rumah_ibadah = r.id
|
|
WHERE m.nik = ?
|
|
`;
|
|
|
|
db.get(kueri_pencarian, [nik_warga], (error_sistem, baris_data) => {
|
|
if (error_sistem) {
|
|
console.error('Sistem gagal membaca tabel gabungan:', error_sistem.message);
|
|
return res.status(500).json({ error: 'Terjadi kegagalan server internal.' });
|
|
}
|
|
|
|
if (!baris_data) {
|
|
return res.status(404).json({ error: 'Data tidak ditemukan.' });
|
|
}
|
|
|
|
res.status(200).json(baris_data);
|
|
});
|
|
};
|
|
|
|
// Mengontrol alur penerimaan data survei lapangan beserta penentuan pangkalan bantuan
|
|
const submit_survey_data = async (req, res) => {
|
|
try {
|
|
const {
|
|
nik,
|
|
nama_kk,
|
|
no_kk,
|
|
jumlah_tanggungan,
|
|
lat,
|
|
lng,
|
|
agama,
|
|
indikator_bps
|
|
} = req.body;
|
|
|
|
// Praktik keamanan: Validasi input dasar untuk mencegah insersi data kosong (null pointer exception)
|
|
if (!nik || !nama_kk || !lat || !lng || !agama || !indikator_bps) {
|
|
return res.status(400).json({ error: 'Payload data survei tidak lengkap dari klien.' });
|
|
}
|
|
|
|
// Memulai transaksi basis data untuk menjaga integritas penyimpanan parsial
|
|
db.serialize(() => {
|
|
db.run('BEGIN TRANSACTION');
|
|
|
|
// Baris kompleks: Memanfaatkan db.serialize untuk memastikan kueri SELECT pencarian pangkalan ibadah selesai dieksekusi sebelum beralih ke perintah INSERT transaksional berikutnya guna menghindari balapan data (race condition).
|
|
const kueri_cari_pangkalan = `SELECT id FROM RUMAH_IBADAH WHERE agama = ? LIMIT 1`;
|
|
|
|
db.get(kueri_cari_pangkalan, [agama], (error_cari, baris_pangkalan) => {
|
|
if (error_cari) {
|
|
db.run('ROLLBACK');
|
|
console.error('Gagal mencocokkan rumah ibadah:', error_cari.message);
|
|
return res.status(500).json({ error: 'Gagal memproses penentuan lokasi bantuan.' });
|
|
}
|
|
|
|
const id_pangkalan_terpilih = baris_pangkalan ? baris_pangkalan.id : null;
|
|
|
|
// 1. Menyimpan data identitas dan relasi pangkalan ke tabel MUSTAHIK
|
|
const kueri_mustahik = `
|
|
INSERT INTO MUSTAHIK (nik, nama_kk, no_kk, jumlah_tanggungan, lat, lng, agama, id_rumah_ibadah)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`;
|
|
|
|
db.run(kueri_mustahik, [nik, nama_kk, no_kk, jumlah_tanggungan, lat, lng, agama, id_pangkalan_terpilih], function(error_mustahik) {
|
|
if (error_mustahik) {
|
|
db.run('ROLLBACK');
|
|
console.error('Gagal menyimpan DML MUSTAHIK:', error_mustahik.message);
|
|
return res.status(500).json({ error: 'Gagal menyimpan data identitas warga, NIK mungkin sudah terdaftar.' });
|
|
}
|
|
|
|
const id_mustahik_baru = this.lastID;
|
|
const {
|
|
luas_lantai_per_kapita,
|
|
material_lantai,
|
|
material_dinding,
|
|
fasilitas_sanitasi,
|
|
sumber_air_minum,
|
|
sumber_penerangan,
|
|
pekerjaan_utama,
|
|
pendapatan_bulanan,
|
|
frekuensi_makan,
|
|
kepemilikan_aset
|
|
} = indikator_bps;
|
|
|
|
// 2. Menyimpan 10 parameter kondisi ke tabel INDIKATOR_BPS
|
|
const kueri_indikator = `
|
|
INSERT INTO INDIKATOR_BPS (
|
|
id_mustahik, luas_lantai_per_kapita, material_lantai, material_dinding,
|
|
fasilitas_sanitasi, sumber_air_minum, sumber_penerangan,
|
|
pekerjaan_utama, pendapatan_bulanan, frekuensi_makan, kepemilikan_aset
|
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
`;
|
|
|
|
db.run(kueri_indikator, [
|
|
id_mustahik_baru,
|
|
luas_lantai_per_kapita,
|
|
material_lantai,
|
|
material_dinding,
|
|
fasilitas_sanitasi,
|
|
sumber_air_minum,
|
|
sumber_penerangan,
|
|
pekerjaan_utama,
|
|
pendapatan_bulanan,
|
|
frekuensi_makan,
|
|
kepemilikan_aset
|
|
], function(error_indikator) {
|
|
if (error_indikator) {
|
|
db.run('ROLLBACK');
|
|
console.error('Gagal menyimpan DML INDIKATOR_BPS:', error_indikator.message);
|
|
return res.status(500).json({ error: 'Gagal merekam indikator ekonomi BPS.' });
|
|
}
|
|
|
|
// Secara permanen menerapkan semua kueri yang tertunda ke dalam file SQLite
|
|
db.run('COMMIT');
|
|
res.status(201).json({
|
|
message: 'Data survei kriteria BPS dan pangkalan bantuan berhasil disimpan.',
|
|
id_mustahik: id_mustahik_baru
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
} catch (error_sistem) {
|
|
console.error('Kesalahan eksekusi sistem:', error_sistem);
|
|
res.status(500).json({ error: 'Kegagalan pemrosesan internal server.' });
|
|
}
|
|
};
|
|
|
|
// Menarik agregasi data statistik untuk ditampilkan di halaman publik
|
|
const ambil_statistik_publik = (req, res) => {
|
|
const kueri_statistik = `
|
|
SELECT
|
|
COUNT(CASE WHEN status_validasi = 'Verified' THEN 1 END) AS terverifikasi,
|
|
COUNT(CASE WHEN status_validasi = 'Pending' THEN 1 END) AS diproses
|
|
FROM MUSTAHIK
|
|
`;
|
|
|
|
db.get(kueri_statistik, [], (error_sql, baris_data) => {
|
|
if (error_sql) {
|
|
console.error('Gagal menarik agregasi statistik:', error_sql.message);
|
|
return res.status(500).json({ error: 'Gagal memuat statistik.' });
|
|
}
|
|
res.status(200).json(baris_data);
|
|
});
|
|
};
|
|
|
|
module.exports = {
|
|
cek_status_nik,
|
|
submit_survey_data,
|
|
ambil_statistik_publik
|
|
}; |