prepare($sql); $stmt->execute($params); jsonSuccess($stmt->fetchAll()); } public function show(string $id): void { requireAuth([ROLE_ADMIN, ROLE_PENGURUS, ROLE_PIMPINAN]); $db = getDB(); $stmt = $db->prepare( "SELECT k.*, ri.nama AS nama_ri FROM keluarga k LEFT JOIN rumah_ibadah ri ON k.id_rumah_ibadah = ri.id WHERE k.id = ?" ); $stmt->execute([$id]); $kk = $stmt->fetch(); if (!$kk) jsonError('Keluarga tidak ditemukan', 404); $anggota = $db->prepare( "SELECT nik, nama_lengkap, jenis_kelamin, status_keluarga, TIMESTAMPDIFF(YEAR, tanggal_lahir, CURDATE()) AS umur, pekerjaan, penghasilan, status_ekonomi, kondisi_kesehatan, pendidikan_terakhir, status_pendidikan, status_hidup FROM penduduk WHERE id_keluarga = ? ORDER BY status_keluarga" ); $anggota->execute([$id]); $kk['anggota'] = $anggota->fetchAll(); jsonSuccess($kk); } public function store(): void { requireAuth([ROLE_ADMIN, ROLE_PENGURUS]); $body = getBody(); $errs = required($body, ['no_kk', 'nama_kepala']); if ($errs) jsonError(implode('; ', $errs)); if (!preg_match('/^\d{16}$/', $body['no_kk'])) jsonError('No KK harus 16 digit'); $db = getDB(); $chk = $db->prepare("SELECT id FROM keluarga WHERE no_kk = ?"); $chk->execute([$body['no_kk']]); if ($chk->fetch()) jsonError('No KK sudah terdaftar', 409); $db->prepare( "INSERT INTO keluarga (no_kk, id_rumah_ibadah, nama_kepala, alamat, rt, rw, kelurahan, kecamatan, lat, lng, status_ekonomi) VALUES (?,?,?,?,?,?,?,?,?,?,?)" )->execute([ $body['no_kk'], $body['id_rumah_ibadah'] ?? null, sanitize($body['nama_kepala']), sanitize($body['alamat'] ?? ''), sanitize($body['rt'] ?? ''), sanitize($body['rw'] ?? ''), sanitize($body['kelurahan'] ?? ''), sanitize($body['kecamatan'] ?? ''), $body['lat'] ?? null, $body['lng'] ?? null, $body['status_ekonomi'] ?? 'rentan', ]); $newId = $db->lastInsertId(); logActivity('create_keluarga', 'keluarga', $newId, [], $body); jsonSuccess(['id' => $newId], 'Data keluarga berhasil disimpan', 201); } public function update(string $id): void { requireAuth([ROLE_ADMIN, ROLE_PENGURUS]); $db = getDB(); $body = getBody(); $db->prepare( "UPDATE keluarga SET id_rumah_ibadah=?, nama_kepala=?, alamat=?, rt=?, rw=?, kelurahan=?, kecamatan=?, lat=?, lng=?, status_ekonomi=? WHERE id=?" )->execute([ $body['id_rumah_ibadah'] ?? null, sanitize($body['nama_kepala'] ?? ''), sanitize($body['alamat'] ?? ''), sanitize($body['rt'] ?? ''), sanitize($body['rw'] ?? ''), sanitize($body['kelurahan'] ?? ''), sanitize($body['kecamatan'] ?? ''), $body['lat'] ?? null, $body['lng'] ?? null, $body['status_ekonomi'] ?? 'rentan', $id, ]); logActivity('update_keluarga', 'keluarga', $id, [], $body); jsonSuccess([], 'Data keluarga diperbarui'); } public function destroy(string $id): void { requireAuth([ROLE_ADMIN]); $db = getDB(); $chk = $db->prepare("SELECT COUNT(*) AS c FROM penduduk WHERE id_keluarga = ?"); $chk->execute([$id]); if ($chk->fetch()['c'] > 0) jsonError('Tidak bisa hapus — masih ada anggota keluarga', 409); $db->prepare("DELETE FROM keluarga WHERE id = ?")->execute([$id]); logActivity('delete_keluarga', 'keluarga', $id); jsonSuccess([], 'Data keluarga dihapus'); } }