From 6f925484e796645b9dc948f7d8a24de33706630e Mon Sep 17 00:00:00 2001 From: mhmmadbayuu Date: Thu, 11 Jun 2026 19:22:04 +0700 Subject: [PATCH] Migrasi ke Docker Compose --- docker-compose.yml | 46 +++ init-db/01-schema.sql | 384 ++++++++++++++++++++ init-db/02-schema_webgis_spbu.sql | 469 +++++++++++++++++++++++++ webgis-spbu/sql/schema_webgis_spbu.sql | 3 + 4 files changed, 902 insertions(+) create mode 100644 docker-compose.yml create mode 100644 init-db/01-schema.sql create mode 100644 init-db/02-schema_webgis_spbu.sql diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4eb1ff5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,46 @@ +version: '3.8' + +services: + web: + build: . + container_name: webgis_app + ports: + - "8000:80" + environment: + - DB_HOST=db + - DB_PORT=3306 + - DB_USER=root + - DB_PASSWORD=rahasia + # DB_NAME tidak didefinisikan agar fallback ke 'webgis_kemiskinan' dan 'webgis_spbu' otomatis berfungsi + depends_on: + - db + restart: unless-stopped + + db: + image: mysql:8.0 + container_name: webgis_db + environment: + - MYSQL_ROOT_PASSWORD=rahasia + volumes: + - db_data:/var/lib/mysql + # Menyambungkan folder init-db agar tabel otomatis terbuat saat pertama kali dinyalakan + - ./init-db:/docker-entrypoint-initdb.d + ports: + - "3307:3306" + restart: unless-stopped + + phpmyadmin: + image: phpmyadmin/phpmyadmin:latest + container_name: webgis_pma + environment: + - PMA_HOST=db + - PMA_USER=root + - PMA_PASSWORD=rahasia + ports: + - "8080:80" + depends_on: + - db + restart: unless-stopped + +volumes: + db_data: diff --git a/init-db/01-schema.sql b/init-db/01-schema.sql new file mode 100644 index 0000000..8009642 --- /dev/null +++ b/init-db/01-schema.sql @@ -0,0 +1,384 @@ +-- ============================================================ +-- WebGIS Pengentasan Kemiskinan Berbasis Masyarakat & Rumah Ibadah +-- Schema Lengkap v2.0 — FIXED VERSION +-- Engine: MySQL / MariaDB | Charset: utf8mb4 +-- ============================================================ + +-- PENTING: Buat database terlebih dahulu jika belum ada +CREATE DATABASE IF NOT EXISTS webgis_kemiskinan CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE webgis_kemiskinan; + +SET FOREIGN_KEY_CHECKS = 0; +SET NAMES utf8mb4; + +-- ============================================================ +-- DROP TABLES (urutan terbalik dari dependensi FK) +-- ============================================================ +DROP TABLE IF EXISTS notifikasi; +DROP TABLE IF EXISTS log_aktivitas; +DROP TABLE IF EXISTS pesan; +DROP TABLE IF EXISTS laporan; +DROP TABLE IF EXISTS histori_bantuan; +DROP TABLE IF EXISTS jenis_bantuan; +DROP TABLE IF EXISTS riwayat_pelatihan; +DROP TABLE IF EXISTS penduduk; +DROP TABLE IF EXISTS keluarga; +DROP TABLE IF EXISTS rumah_ibadah; +DROP TABLE IF EXISTS users; +DROP TABLE IF EXISTS roles; +DROP TABLE IF EXISTS jalan_lines; +DROP TABLE IF EXISTS parsil_tanah; + +-- ============================================================ +-- 1. ROLES & USERS +-- ============================================================ + +CREATE TABLE roles ( + id TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nama VARCHAR(50) NOT NULL UNIQUE, + label VARCHAR(80) NOT NULL, + deskripsi TEXT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO roles (nama, label) VALUES + ('admin', 'Administrator Sistem'), + ('pengurus', 'Pengurus Rumah Ibadah'), + ('pimpinan', 'Pimpinan Daerah'), + ('masyarakat', 'Masyarakat Umum'); + +-- ============================================================ +-- 2. RUMAH IBADAH (dibuat sebelum users karena users FK ke sini) +-- ============================================================ + +CREATE TABLE rumah_ibadah ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nama VARCHAR(200) NOT NULL, + jenis ENUM('Masjid','Musholla','Gereja Protestan','Gereja Katolik','Pura','Vihara','Klenteng','Lainnya') NOT NULL DEFAULT 'Lainnya', + kontak VARCHAR(120) NULL, + radius_meter DOUBLE NOT NULL DEFAULT 300, + latitude DECIMAL(10,7) NOT NULL, + longitude DECIMAL(10,7) NOT NULL, + alamat TEXT NULL, + kelurahan VARCHAR(120) NULL, + kecamatan VARCHAR(120) NULL, + kota VARCHAR(120) NULL, + deskripsi TEXT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_ri_jenis (jenis), + INDEX idx_ri_latlng (latitude, longitude) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 3. USERS (setelah roles & rumah_ibadah) +-- ============================================================ + +CREATE TABLE users ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + role_id TINYINT UNSIGNED NOT NULL DEFAULT 4, + nama VARCHAR(150) NOT NULL, + username VARCHAR(60) NOT NULL UNIQUE, + email VARCHAR(150) NULL UNIQUE, + password_hash VARCHAR(255) NOT NULL, + no_telp VARCHAR(20) NULL, + foto VARCHAR(255) NULL, + aktif TINYINT(1) NOT NULL DEFAULT 1, + rumah_ibadah_id INT UNSIGNED NULL, + last_login DATETIME NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_users_role (role_id), + CONSTRAINT fk_users_role FOREIGN KEY (role_id) REFERENCES roles(id), + CONSTRAINT fk_users_ri FOREIGN KEY (rumah_ibadah_id) REFERENCES rumah_ibadah(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 4. KELUARGA (KK) +-- ============================================================ + +CREATE TABLE keluarga ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + no_kk VARCHAR(20) NOT NULL UNIQUE, + nama_kk VARCHAR(200) NOT NULL, + alamat TEXT NULL, + kelurahan VARCHAR(120) NULL, + kecamatan VARCHAR(120) NULL, + kota VARCHAR(120) NULL, + latitude DECIMAL(10,7) NULL, + longitude DECIMAL(10,7) NULL, + status_ekonomi ENUM('miskin','rentan','mampu') NOT NULL DEFAULT 'rentan', + rumah_ibadah_id INT UNSIGNED NULL, + jarak_ri_meter DOUBLE NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_kk_status (status_ekonomi), + INDEX idx_kk_latlng (latitude, longitude), + INDEX idx_kk_ri (rumah_ibadah_id), + CONSTRAINT fk_kk_ri FOREIGN KEY (rumah_ibadah_id) REFERENCES rumah_ibadah(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 5. PENDUDUK +-- ============================================================ + +CREATE TABLE penduduk ( + nik VARCHAR(16) NOT NULL PRIMARY KEY, + id_keluarga INT UNSIGNED NULL, + nama_lengkap VARCHAR(200) NOT NULL, + jenis_kelamin ENUM('L','P') NOT NULL, + tanggal_lahir DATE NOT NULL, + umur TINYINT UNSIGNED GENERATED ALWAYS AS ( + TIMESTAMPDIFF(YEAR, tanggal_lahir, CURDATE()) + ) VIRTUAL, + status_keluarga ENUM('kepala_keluarga','istri','anak','menantu','cucu','orang_tua','mertua','anggota_lain') NOT NULL DEFAULT 'anggota_lain', + status_perkawinan ENUM('belum_kawin','kawin','cerai_hidup','cerai_mati') NOT NULL DEFAULT 'belum_kawin', + status_hidup ENUM('hidup','meninggal') NOT NULL DEFAULT 'hidup', + pendidikan_terakhir ENUM('tidak_sekolah','SD','SMP','SMA','SMK','D1','D2','D3','S1','S2','S3') NOT NULL DEFAULT 'tidak_sekolah', + status_pendidikan ENUM('sekolah','tidak_sekolah','lulus') NOT NULL DEFAULT 'tidak_sekolah', + pekerjaan VARCHAR(150) NULL, + penghasilan DECIMAL(15,2) NULL DEFAULT 0, + status_ekonomi ENUM('miskin','rentan','mampu') NOT NULL DEFAULT 'rentan', + kondisi_kesehatan ENUM('sehat','sakit_ringan','sakit_parah','disabilitas') NOT NULL DEFAULT 'sehat', + catatan_kesehatan TEXT NULL, + no_telp VARCHAR(20) NULL, + alamat TEXT NULL, + latitude DECIMAL(10,7) NULL, + longitude DECIMAL(10,7) NULL, + foto VARCHAR(255) NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_pddk_keluarga (id_keluarga), + INDEX idx_pddk_status_ek (status_ekonomi), + INDEX idx_pddk_status_hid (status_hidup), + INDEX idx_pddk_latlng (latitude, longitude), + CONSTRAINT fk_pddk_keluarga FOREIGN KEY (id_keluarga) REFERENCES keluarga(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 6. RIWAYAT PELATIHAN +-- ============================================================ + +CREATE TABLE riwayat_pelatihan ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nik VARCHAR(16) NOT NULL, + nama_pelatihan VARCHAR(200) NOT NULL, + penyelenggara VARCHAR(150) NULL, + tanggal_mulai DATE NULL, + tanggal_selesai DATE NULL, + sertifikat VARCHAR(255) NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + INDEX idx_platihan_nik (nik), + CONSTRAINT fk_platihan_nik FOREIGN KEY (nik) REFERENCES penduduk(nik) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 7. JENIS BANTUAN (master) +-- ============================================================ + +CREATE TABLE jenis_bantuan ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nama VARCHAR(150) NOT NULL, + kategori ENUM('sembako','pendidikan','kesehatan','ekonomi','perumahan','lainnya') NOT NULL DEFAULT 'lainnya', + sumber VARCHAR(150) NULL, + satuan VARCHAR(50) NULL, + deskripsi TEXT NULL, + aktif TINYINT(1) NOT NULL DEFAULT 1, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +INSERT INTO jenis_bantuan (nama, kategori, sumber, satuan) VALUES + ('Sembako Bulanan', 'sembako', 'Rumah Ibadah', '1 paket/bulan'), + ('Beasiswa Pendidikan', 'pendidikan','BAZNAS', 'Rp/semester'), + ('Bantuan Kesehatan', 'kesehatan', 'Puskesmas', '1 kali/kunjungan'), + ('Modal Usaha Mikro', 'ekonomi', 'Baznas', 'Rp/program'), + ('Renovasi Rumah', 'perumahan', 'Pemerintah', 'paket/unit'); + +-- ============================================================ +-- 8. HISTORI BANTUAN +-- ============================================================ + +CREATE TABLE histori_bantuan ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nik VARCHAR(16) NOT NULL, + id_jenis_bantuan INT UNSIGNED NOT NULL, + id_keluarga INT UNSIGNED NULL, + rumah_ibadah_id INT UNSIGNED NULL, + tanggal DATE NOT NULL, + jumlah VARCHAR(100) NULL, + nilai_rupiah DECIMAL(15,2) NULL, + status_penyaluran ENUM('dijadwalkan','disalurkan','dibatalkan') NOT NULL DEFAULT 'dijadwalkan', + catatan TEXT NULL, + bukti_file VARCHAR(255) NULL, + disalurkan_oleh INT UNSIGNED NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_hb_nik (nik), + INDEX idx_hb_tanggal (tanggal), + INDEX idx_hb_status (status_penyaluran), + CONSTRAINT fk_hb_nik FOREIGN KEY (nik) REFERENCES penduduk(nik) ON DELETE CASCADE, + CONSTRAINT fk_hb_jenis FOREIGN KEY (id_jenis_bantuan) REFERENCES jenis_bantuan(id), + CONSTRAINT fk_hb_kk FOREIGN KEY (id_keluarga) REFERENCES keluarga(id) ON DELETE SET NULL, + CONSTRAINT fk_hb_ri FOREIGN KEY (rumah_ibadah_id) REFERENCES rumah_ibadah(id) ON DELETE SET NULL, + CONSTRAINT fk_hb_user FOREIGN KEY (disalurkan_oleh) REFERENCES users(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 9. LAPORAN MASYARAKAT +-- ============================================================ + +CREATE TABLE laporan ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nama_pelapor VARCHAR(150) NULL, + pelapor_id INT UNSIGNED NULL, + nik_terdampak VARCHAR(16) NULL, + deskripsi TEXT NOT NULL, + kategori ENUM('darurat_pangan','darurat_kesehatan','darurat_ekonomi','butuh_bantuan_lain') NOT NULL DEFAULT 'butuh_bantuan_lain', + tingkat_urgensi ENUM('rendah','sedang','tinggi','darurat') NOT NULL DEFAULT 'sedang', + latitude DECIMAL(10,7) NULL, + longitude DECIMAL(10,7) NULL, + alamat TEXT NULL, + foto VARCHAR(255) NULL, + status ENUM('pending','diverifikasi','diproses','selesai','ditolak') NOT NULL DEFAULT 'pending', + catatan_verifikasi TEXT NULL, + diverifikasi_oleh INT UNSIGNED NULL, + ditangani_oleh INT UNSIGNED NULL, + tanggal_selesai DATETIME NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_lap_status (status), + INDEX idx_lap_urgensi (tingkat_urgensi), + INDEX idx_lap_latlng (latitude, longitude), + CONSTRAINT fk_lap_nik FOREIGN KEY (nik_terdampak) REFERENCES penduduk(nik) ON DELETE SET NULL, + CONSTRAINT fk_lap_pelapor FOREIGN KEY (pelapor_id) REFERENCES users(id) ON DELETE SET NULL, + CONSTRAINT fk_lap_verif FOREIGN KEY (diverifikasi_oleh) REFERENCES users(id) ON DELETE SET NULL, + CONSTRAINT fk_lap_tangan FOREIGN KEY (ditangani_oleh) REFERENCES users(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 10. PESAN / CHAT ANTAR PENGURUS +-- ============================================================ + +CREATE TABLE pesan ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + dari_user_id INT UNSIGNED NOT NULL, + ke_user_id INT UNSIGNED NULL, + ke_rumah_ibadah_id INT UNSIGNED NULL, + isi TEXT NOT NULL, + dibaca TINYINT(1) NOT NULL DEFAULT 0, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + INDEX idx_pesan_dari (dari_user_id), + INDEX idx_pesan_ke (ke_user_id), + CONSTRAINT fk_pesan_dari FOREIGN KEY (dari_user_id) REFERENCES users(id) ON DELETE CASCADE, + CONSTRAINT fk_pesan_ke FOREIGN KEY (ke_user_id) REFERENCES users(id) ON DELETE SET NULL, + CONSTRAINT fk_pesan_ri FOREIGN KEY (ke_rumah_ibadah_id) REFERENCES rumah_ibadah(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 11. LOG AKTIVITAS (audit trail) +-- ============================================================ + +CREATE TABLE log_aktivitas ( + id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + user_id INT UNSIGNED NULL, + aksi VARCHAR(50) NOT NULL, + tabel VARCHAR(60) NULL, + record_id VARCHAR(32) NULL, + data_lama JSON NULL, + data_baru JSON NULL, + ip_address VARCHAR(45) NULL, + user_agent VARCHAR(255) NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + INDEX idx_log_user (user_id), + INDEX idx_log_tabel (tabel), + INDEX idx_log_aksi (aksi), + INDEX idx_log_time (created_at), + CONSTRAINT fk_log_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 12. LAYER SPASIAL TAMBAHAN +-- ============================================================ + +CREATE TABLE jalan_lines ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + nama_jalan VARCHAR(200) NOT NULL, + status_jalan ENUM('Nasional','Provinsi','Kabupaten','Desa') NOT NULL DEFAULT 'Kabupaten', + panjang_meter DOUBLE NOT NULL DEFAULT 0, + geojson LONGTEXT NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_jalan_status (status_jalan) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE parsil_tanah ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + status_kepemilikan ENUM('SHM','HGB','HGU','HP','Wakaf','Lainnya') NOT NULL DEFAULT 'SHM', + luas_m2 DOUBLE NOT NULL DEFAULT 0, + geojson LONGTEXT NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_parsil_status (status_kepemilikan) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- ============================================================ +-- 13. NOTIFIKASI +-- ============================================================ + +CREATE TABLE notifikasi ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + user_id INT UNSIGNED NOT NULL, + judul VARCHAR(200) NOT NULL, + isi TEXT NOT NULL, + tipe ENUM('laporan','bantuan','sistem','pesan') NOT NULL DEFAULT 'sistem', + ref_id INT UNSIGNED NULL, + dibaca TINYINT(1) NOT NULL DEFAULT 0, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + INDEX idx_notif_user (user_id), + INDEX idx_notif_dibaca (dibaca), + CONSTRAINT fk_notif_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +SET FOREIGN_KEY_CHECKS = 1; + +-- ============================================================ +-- DATA DUMMY +-- ============================================================ + +INSERT IGNORE INTO users (role_id, nama, username, email, password_hash) VALUES + (1, 'Administrator', 'admin', 'admin@webgis.local', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'), + (2, 'H. Ahmad Fauzi', 'pengurus1', 'pengurus1@webgis.local', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'), + (3, 'Camat Pontianak Selatan','pimpinan1', 'pimpinan@webgis.local', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'), + (4, 'Budi Santoso', 'warga1', 'warga1@webgis.local', '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'); + +INSERT IGNORE INTO rumah_ibadah (nama, jenis, kontak, radius_meter, latitude, longitude, alamat, kelurahan, kecamatan) VALUES + ('Masjid Al-Falah', 'Masjid', '08113001234', 400, -0.0200, 109.3410, 'Jl. Gajah Mada No. 1', 'Benua Melayu Darat', 'Pontianak Selatan'), + ('Masjid Raya Mujahidin', 'Masjid', '08113005678', 600, -0.0250, 109.3430, 'Jl. Ahmad Yani No. 10', 'Akcaya', 'Pontianak Selatan'), + ('GKE Pontianak', 'Gereja Protestan', '08113009999', 300, -0.0280, 109.3480, 'Jl. Nusa Indah', 'Sungai Bangkong', 'Pontianak Kota'), + ('Vihara Bodhicitta', 'Vihara', '08113004321', 250, -0.0310, 109.3520, 'Jl. Tanjungpura No. 5', 'Mariana', 'Pontianak Kota'); + +INSERT IGNORE INTO keluarga (no_kk, nama_kk, alamat, kelurahan, kecamatan, latitude, longitude, status_ekonomi, rumah_ibadah_id) VALUES + ('6171010101010001', 'Ahmad Firdaus', 'Jl. Melati No. 3', 'Benua Melayu Darat', 'Pontianak Selatan', -0.0210, 109.3415, 'miskin', 1), + ('6171010101010002', 'Siti Rahma', 'Jl. Kenanga No. 5', 'Benua Melayu Darat', 'Pontianak Selatan', -0.0220, 109.3420, 'miskin', 1), + ('6171010101010003', 'Budi Hermawan','Jl. Mawar No. 7', 'Akcaya', 'Pontianak Selatan', -0.0240, 109.3435, 'rentan', 2), + ('6171010101010004', 'Maria Goretti','Jl. Nusa Indah No.2', 'Sungai Bangkong', 'Pontianak Kota', -0.0275, 109.3475, 'miskin', 3), + ('6171010101010005', 'Tan Ah Kow', 'Jl. Tanjungpura 12', 'Mariana', 'Pontianak Kota', -0.0305, 109.3515, 'rentan', 4); + +INSERT IGNORE INTO penduduk (nik, id_keluarga, nama_lengkap, jenis_kelamin, tanggal_lahir, status_keluarga, status_perkawinan, status_ekonomi, pekerjaan, penghasilan, kondisi_kesehatan, alamat, latitude, longitude) VALUES + ('6171010101010001', 1, 'Ahmad Firdaus', 'L', '1980-03-15', 'kepala_keluarga', 'kawin', 'miskin', 'Buruh Harian', 800000, 'sehat', 'Jl. Melati No. 3', -0.0210, 109.3415), + ('6171010101010002', 1, 'Siti Aisyah', 'P', '1983-07-22', 'istri', 'kawin', 'miskin', 'Ibu Rumah Tangga', 0, 'sehat', 'Jl. Melati No. 3', -0.0210, 109.3415), + ('6171010101010003', 1, 'Reza Firdaus', 'L', '2010-11-05', 'anak', 'belum_kawin', 'miskin', 'Pelajar', 0, 'sehat', 'Jl. Melati No. 3', -0.0210, 109.3415), + ('6171020202020001', 2, 'Siti Rahma', 'P', '1975-01-10', 'kepala_keluarga', 'cerai_mati', 'miskin', 'Pedagang Kecil', 500000, 'sakit_ringan','Jl. Kenanga No. 5', -0.0220, 109.3420), + ('6171020202020002', 2, 'Dewi Rahma', 'P', '2008-05-30', 'anak', 'belum_kawin', 'miskin', 'Pelajar', 0, 'sehat', 'Jl. Kenanga No. 5', -0.0220, 109.3420), + ('6171030303030001', 3, 'Budi Hermawan', 'L', '1990-09-20', 'kepala_keluarga', 'kawin', 'rentan', 'Ojek Online', 1500000, 'sehat', 'Jl. Mawar No. 7', -0.0240, 109.3435), + ('6171040404040001', 4, 'Yohanes Goretti', 'L', '1970-12-01', 'kepala_keluarga', 'kawin', 'miskin', 'Tidak bekerja', 0, 'sakit_parah', 'Jl. Nusa Indah No.2', -0.0275, 109.3475), + ('6171050505050001', 5, 'Tan Ah Kow', 'L', '1968-06-18', 'kepala_keluarga', 'kawin', 'rentan', 'Pedagang', 1200000, 'sehat', 'Jl. Tanjungpura 12', -0.0305, 109.3515); + +INSERT IGNORE INTO histori_bantuan (nik, id_jenis_bantuan, id_keluarga, rumah_ibadah_id, tanggal, jumlah, status_penyaluran, catatan) VALUES + ('6171010101010001', 1, 1, 1, CURDATE() - INTERVAL 30 DAY, '1 paket sembako', 'disalurkan', 'Penyaluran rutin bulan lalu'), + ('6171020202020001', 2, 2, 1, CURDATE() - INTERVAL 15 DAY, 'Rp 500.000', 'disalurkan', 'Bantuan pendidikan anak'), + ('6171040404040001', 3, 4, 3, CURDATE() - INTERVAL 7 DAY, '1 kali pemeriksaan', 'disalurkan', 'Kunjungan kesehatan darurat'); + +INSERT IGNORE INTO laporan (nama_pelapor, nik_terdampak, deskripsi, kategori, tingkat_urgensi, latitude, longitude, alamat, status) VALUES + ('Anonim', '6171020202020001', 'Ibu Siti sudah 3 hari tidak makan, anaknya juga sakit', 'darurat_pangan', 'darurat', -0.0220, 109.3420, 'Jl. Kenanga No. 5', 'pending'), + ('Pak RT 03', NULL, 'Ada lansia sebatang kara tidak ada yang merawat di RT 03','butuh_bantuan_lain','tinggi', -0.0265, 109.3460, 'RT 03 Sungai Bangkong','diverifikasi'), + ('Maria Magdalena', '6171040404040001', 'Pak Yohanes sakit parah, tidak ada biaya berobat', 'darurat_kesehatan', 'darurat', -0.0275, 109.3475, 'Jl. Nusa Indah No.2', 'diproses'); diff --git a/init-db/02-schema_webgis_spbu.sql b/init-db/02-schema_webgis_spbu.sql new file mode 100644 index 0000000..214c739 --- /dev/null +++ b/init-db/02-schema_webgis_spbu.sql @@ -0,0 +1,469 @@ +-- Schema WebGIS SPBU + Jalan + Parsil (MySQL / MariaDB) +-- Catatan: +-- - Data LINE/POLYGON disimpan sebagai GeoJSON geometry (tipe: geojson) di kolom LONGTEXT `geojson`. +-- - Panjang (meter) dan luas (m2) dihitung otomatis di LeafletJS, bukan input manual. + +CREATE DATABASE IF NOT EXISTS webgis_spbu CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE webgis_spbu; + +CREATE TABLE IF NOT EXISTS spbu_points ( + id INT AUTO_INCREMENT PRIMARY KEY, + nama VARCHAR(150) NOT NULL, + no VARCHAR(60) NOT NULL, + deskripsi TEXT NULL, + status_24jam TINYINT(1) NOT NULL DEFAULT 0, + latitude DECIMAL(10,7) NOT NULL, + longitude DECIMAL(10,7) NOT NULL, + -- opsional (kompatibilitas): simpan GeoJSON Point sebagai string + geom LONGTEXT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_spbu_status24 (status_24jam), + INDEX idx_spbu_latlng (latitude, longitude) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS jalan_lines ( + id INT AUTO_INCREMENT PRIMARY KEY, + nama_jalan VARCHAR(200) NOT NULL, + status_jalan VARCHAR(20) NOT NULL, -- Nasional | Provinsi | Kabupaten + panjang_meter DOUBLE NOT NULL DEFAULT 0, + geojson LONGTEXT NOT NULL, -- GeoJSON geometry: { "type":"LineString", "coordinates":[...] } + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_jalan_status (status_jalan) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS parsil_tanah ( + id INT AUTO_INCREMENT PRIMARY KEY, + status_kepemilikan VARCHAR(10) NOT NULL, -- SHM | HGB | HGU | HP + luas_m2 DOUBLE NOT NULL DEFAULT 0, + geojson LONGTEXT NOT NULL, -- GeoJSON geometry: { "type":"Polygon", "coordinates":[...] } + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_parsil_status (status_kepemilikan) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS rumah_ibadah_points ( + id INT AUTO_INCREMENT PRIMARY KEY, + nama VARCHAR(200) NOT NULL, + jenis VARCHAR(30) NOT NULL DEFAULT 'Lainnya', -- Masjid|Musholla|Gereja|Katolik|Pura|Vihara|Klenteng|Lainnya + kontak VARCHAR(120) NULL, + radius_meter DOUBLE NOT NULL DEFAULT 300, + latitude DECIMAL(10,7) NOT NULL, + longitude DECIMAL(10,7) NOT NULL, + address TEXT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_ibadah_jenis (jenis), + INDEX idx_ibadah_latlng (latitude, longitude) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS pemukiman_miskin_points ( + id INT AUTO_INCREMENT PRIMARY KEY, + kk_nama VARCHAR(200) NOT NULL, + nik VARCHAR(32) NULL, + jumlah_anggota INT NOT NULL DEFAULT 0, + latitude DECIMAL(10,7) NOT NULL, + longitude DECIMAL(10,7) NOT NULL, + address TEXT NULL, + kelurahan VARCHAR(120) NULL, + kecamatan VARCHAR(120) NULL, + status_bantuan VARCHAR(24) NOT NULL DEFAULT 'Belum dibantu', -- Belum dibantu|Sudah dibantu|Menunggu verifikasi + jenis_bantuan VARCHAR(120) NULL, + tanggal_bantuan DATE NULL, + bukti_file VARCHAR(255) NULL, + jarak_meter DOUBLE NULL, + -- id rumah ibadah yang menaungi (hasil pencarian radius terdekat) + rumah_ibadah_id INT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_miskin_latlng (latitude, longitude), + INDEX idx_miskin_ibadah (rumah_ibadah_id), + INDEX idx_miskin_status (status_bantuan), + CONSTRAINT fk_miskin_ibadah FOREIGN KEY (rumah_ibadah_id) REFERENCES rumah_ibadah_points(id) + ON DELETE SET NULL ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS anggota_keluarga ( + id INT AUTO_INCREMENT PRIMARY KEY, + penduduk_id INT NOT NULL, + nama VARCHAR(200) NOT NULL, + hubungan VARCHAR(60) NOT NULL, + umur INT NULL, + pekerjaan VARCHAR(120) NULL, + keterangan VARCHAR(255) NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + INDEX idx_anggota_penduduk (penduduk_id), + CONSTRAINT fk_anggota_penduduk FOREIGN KEY (penduduk_id) REFERENCES pemukiman_miskin_points(id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- (Opsional) User login untuk admin/operator. +CREATE TABLE IF NOT EXISTS users ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(120) NOT NULL, + username VARCHAR(60) NOT NULL UNIQUE, + password_hash VARCHAR(255) NOT NULL, + role VARCHAR(20) NOT NULL DEFAULT 'operator', -- admin|operator + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- Jika ingin strict value, bisa pakai ENUM, misal: +-- status_jalan ENUM('Nasional','Provinsi','Kabupaten') +-- status_kepemilikan ENUM('SHM','HGB','HGU','HP') + + +-- ========================================================== +-- MIGRATION (ALTER) UNTUK DATABASE LAMA (TANPA HILANGKAN DATA) +-- ========================================================== +-- Kapan perlu menjalankan bagian ini? +-- - Jika database Anda dibuat dari project lama (kolom/tipe berbeda), +-- misalnya masih pakai kolom spatial `geom` atau belum punya kolom +-- `latitude/longitude/status_24jam/geojson`. +-- - Jika database Anda sudah dibuat pakai schema di atas (CREATE TABLE), +-- Anda biasanya TIDAK perlu ALTER apa-apa. +-- +-- Cara pakai: +-- - Jalankan file ini di phpMyAdmin / MySQL client. +-- - Bagian CREATE TABLE aman (IF NOT EXISTS). +-- - Bagian MIGRATION ini aman (cek INFORMATION_SCHEMA sebelum ALTER). + +DELIMITER $$ + +DROP PROCEDURE IF EXISTS migrate_webgis_spbu $$ +CREATE PROCEDURE migrate_webgis_spbu() +BEGIN + -- ---------------------- + -- spbu_points + -- ---------------------- + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' + ) THEN + + -- Kolom atribut inti + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'no' + ) THEN + ALTER TABLE spbu_points ADD COLUMN no VARCHAR(60) NULL AFTER nama; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'deskripsi' + ) THEN + ALTER TABLE spbu_points ADD COLUMN deskripsi TEXT NULL AFTER no; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'status_24jam' + ) THEN + ALTER TABLE spbu_points ADD COLUMN status_24jam TINYINT(1) NOT NULL DEFAULT 0 AFTER deskripsi; + END IF; + + -- Lat/Lng: untuk menjaga data lama, dibuat NULL-able dulu. + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'latitude' + ) THEN + ALTER TABLE spbu_points ADD COLUMN latitude DECIMAL(10,7) NULL AFTER status_24jam; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'longitude' + ) THEN + ALTER TABLE spbu_points ADD COLUMN longitude DECIMAL(10,7) NULL AFTER latitude; + END IF; + + -- Kolom geom (opsional) untuk kompatibilitas legacy + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'geom' + ) THEN + ALTER TABLE spbu_points ADD COLUMN geom LONGTEXT NULL AFTER longitude; + END IF; + + -- Index (jika belum ada) + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND index_name = 'idx_spbu_status24' + ) THEN + ALTER TABLE spbu_points ADD INDEX idx_spbu_status24 (status_24jam); + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND index_name = 'idx_spbu_latlng' + ) THEN + ALTER TABLE spbu_points ADD INDEX idx_spbu_latlng (latitude, longitude); + END IF; + + -- Backfill latitude/longitude dari geom GeoJSON (jika geom berisi JSON valid) + -- Catatan: ini hanya mengisi yang masih NULL supaya tidak menimpa data baru. + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'spbu_points' AND column_name = 'geom' + ) THEN + -- Optional: JSON_VALID/JSON_EXTRACT bisa tidak tersedia pada versi tertentu. + -- Best-effort: jika fungsi tidak didukung, blok ini di-skip tanpa menghentikan migrasi. + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + UPDATE spbu_points + SET + longitude = CAST(JSON_UNQUOTE(JSON_EXTRACT(geom, '$.coordinates[0]')) AS DECIMAL(10,7)), + latitude = CAST(JSON_UNQUOTE(JSON_EXTRACT(geom, '$.coordinates[1]')) AS DECIMAL(10,7)) + WHERE (latitude IS NULL OR longitude IS NULL) + AND geom IS NOT NULL + AND JSON_VALID(geom) = 1 + AND JSON_UNQUOTE(JSON_EXTRACT(geom, '$.type')) = 'Point'; + END; + END IF; + END IF; + + -- ---------------------- + -- jalan_lines + -- ---------------------- + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = DATABASE() AND table_name = 'jalan_lines' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'jalan_lines' AND column_name = 'panjang_meter' + ) THEN + ALTER TABLE jalan_lines ADD COLUMN panjang_meter DOUBLE NOT NULL DEFAULT 0 AFTER status_jalan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'jalan_lines' AND column_name = 'geojson' + ) THEN + ALTER TABLE jalan_lines ADD COLUMN geojson LONGTEXT NULL AFTER panjang_meter; + END IF; + + -- Backfill geojson dari kolom spatial geom (jika ada) + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'jalan_lines' AND column_name = 'geom' + ) THEN + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + UPDATE jalan_lines + SET geojson = ST_AsGeoJSON(geom) + WHERE (geojson IS NULL OR geojson = '') AND geom IS NOT NULL; + END; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'jalan_lines' AND index_name = 'idx_jalan_status' + ) THEN + ALTER TABLE jalan_lines ADD INDEX idx_jalan_status (status_jalan); + END IF; + END IF; + + -- ---------------------- + -- parsil_tanah + -- ---------------------- + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = DATABASE() AND table_name = 'parsil_tanah' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'parsil_tanah' AND column_name = 'luas_m2' + ) THEN + ALTER TABLE parsil_tanah ADD COLUMN luas_m2 DOUBLE NOT NULL DEFAULT 0 AFTER status_kepemilikan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'parsil_tanah' AND column_name = 'geojson' + ) THEN + ALTER TABLE parsil_tanah ADD COLUMN geojson LONGTEXT NULL AFTER luas_m2; + END IF; + + -- Backfill geojson dari kolom spatial geom (jika ada) + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'parsil_tanah' AND column_name = 'geom' + ) THEN + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + UPDATE parsil_tanah + SET geojson = ST_AsGeoJSON(geom) + WHERE (geojson IS NULL OR geojson = '') AND geom IS NOT NULL; + END; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'parsil_tanah' AND index_name = 'idx_parsil_status' + ) THEN + ALTER TABLE parsil_tanah ADD INDEX idx_parsil_status (status_kepemilikan); + END IF; + END IF; + + -- ---------------------- + -- rumah_ibadah_points + -- ---------------------- + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' AND column_name = 'jenis' + ) THEN + ALTER TABLE rumah_ibadah_points ADD COLUMN jenis VARCHAR(30) NOT NULL DEFAULT 'Lainnya' AFTER nama; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' AND column_name = 'kontak' + ) THEN + ALTER TABLE rumah_ibadah_points ADD COLUMN kontak VARCHAR(120) NULL AFTER jenis; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' AND column_name = 'radius_meter' + ) THEN + ALTER TABLE rumah_ibadah_points ADD COLUMN radius_meter DOUBLE NOT NULL DEFAULT 300 AFTER kontak; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' AND column_name = 'address' + ) THEN + ALTER TABLE rumah_ibadah_points ADD COLUMN address TEXT NULL AFTER longitude; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'rumah_ibadah_points' AND index_name = 'idx_ibadah_latlng' + ) THEN + ALTER TABLE rumah_ibadah_points ADD INDEX idx_ibadah_latlng (latitude, longitude); + END IF; + END IF; + + -- ---------------------- + -- pemukiman_miskin_points + -- ---------------------- + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' + ) THEN + -- Backward compat: kalau masih pakai kolom `nama`, migrasikan ke `kk_nama` + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'kk_nama' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN kk_nama VARCHAR(200) NULL AFTER id; + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + UPDATE pemukiman_miskin_points + SET kk_nama = COALESCE(NULLIF(kk_nama, ''), NULLIF(nama, '')) + WHERE (kk_nama IS NULL OR kk_nama = ''); + END; + -- jadikan NOT NULL kalau sudah terisi + BEGIN + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; + ALTER TABLE pemukiman_miskin_points MODIFY kk_nama VARCHAR(200) NOT NULL; + END; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'nik' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN nik VARCHAR(32) NULL AFTER kk_nama; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'jumlah_anggota' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN jumlah_anggota INT NOT NULL DEFAULT 0 AFTER nik; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'kelurahan' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN kelurahan VARCHAR(120) NULL AFTER address; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'kecamatan' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN kecamatan VARCHAR(120) NULL AFTER kelurahan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'status_bantuan' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN status_bantuan VARCHAR(24) NOT NULL DEFAULT 'Belum dibantu' AFTER kecamatan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'jenis_bantuan' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN jenis_bantuan VARCHAR(120) NULL AFTER status_bantuan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'tanggal_bantuan' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN tanggal_bantuan DATE NULL AFTER jenis_bantuan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'bukti_file' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN bukti_file VARCHAR(255) NULL AFTER tanggal_bantuan; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'jarak_meter' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN jarak_meter DOUBLE NULL AFTER bukti_file; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND column_name = 'rumah_ibadah_id' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD COLUMN rumah_ibadah_id INT NULL AFTER jarak_meter; + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND index_name = 'idx_miskin_ibadah' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD INDEX idx_miskin_ibadah (rumah_ibadah_id); + END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.statistics + WHERE table_schema = DATABASE() AND table_name = 'pemukiman_miskin_points' AND index_name = 'idx_miskin_latlng' + ) THEN + ALTER TABLE pemukiman_miskin_points ADD INDEX idx_miskin_latlng (latitude, longitude); + END IF; + END IF; +END $$ + +-- Jalankan migrasi (aman dijalankan berulang) +CALL migrate_webgis_spbu() $$ +DROP PROCEDURE IF EXISTS migrate_webgis_spbu $$ + +DELIMITER ; diff --git a/webgis-spbu/sql/schema_webgis_spbu.sql b/webgis-spbu/sql/schema_webgis_spbu.sql index 28f9b1b..214c739 100644 --- a/webgis-spbu/sql/schema_webgis_spbu.sql +++ b/webgis-spbu/sql/schema_webgis_spbu.sql @@ -3,6 +3,9 @@ -- - Data LINE/POLYGON disimpan sebagai GeoJSON geometry (tipe: geojson) di kolom LONGTEXT `geojson`. -- - Panjang (meter) dan luas (m2) dihitung otomatis di LeafletJS, bukan input manual. +CREATE DATABASE IF NOT EXISTS webgis_spbu CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE webgis_spbu; + CREATE TABLE IF NOT EXISTS spbu_points ( id INT AUTO_INCREMENT PRIMARY KEY, nama VARCHAR(150) NOT NULL,