GempaWatch
Situs risiko gempa yang menunjukkan seberapa aktif daerah Anda, dari 70.271 gempa yang tercatat

- gempa gabungan dari BMKG dan USGS
- 70.271
- tahun riwayat gempa, sejak 1970
- 57
- wilayah dengan profil risiko terbuka
- 52
- bencana bersejarah pilihan, Aceh 2004 hingga Cianjur 2022
- 20
Di halaman ini
- Masalahnya
- Yang saya bangun
- Saya menggabungkan feed nasional dengan arsip global, lalu memberinya skor
- Saat server ditiadakan, proses build menjadi pipeline data
- Browser menjalankan hitungan risiko yang sama, dicek di 39 titik
- Riwayat gempa dicadangkan dua kali
- Saya membangun ulang beranda dan palet warna di sekitar alat pengecek risiko
- Hasilnya
- Di balik layar
Masalahnya
Indonesia adalah negara paling aktif secara seismik di dunia, dan banyak aplikasi yang menampilkan daftar gempa terbaru. Tapi daftar menjawab pertanyaan yang keliru. Yang sebenarnya ditanyakan orang bersifat pribadi: apakah kota saya berbahaya, perlukah saya khawatir, apakah di sini lebih rawan daripada Jakarta?
Dua celah membuat pertanyaan itu sulit dijawab. BMKG, lembaga resmi Indonesia, hanya menerbitkan 15 kejadian terakhir per feed, tanpa riwayat yang bisa ditelusuri. USGS menyimpan arsip lengkap, tapi cakupannya global, berbahasa Inggris, dan berupa data peta mentah. Saya membangun GempaWatch untuk warga yang ingin mengecek daerahnya, keluarga di pesisir yang memikirkan tsunami, pelajar, dan jurnalis yang butuh fakta cepat saat gempa baru terjadi.
Yang saya bangun
Saya menggabungkan feed nasional dengan arsip global, lalu memberinya skor
USGS memberi kedalaman riwayat. BMKG memberi otoritas lokal dan gempa kecil yang terasa, yang tidak pernah dicatat USGS. Kalau keduanya melaporkan gempa yang sama, dalam selisih lima menit dan 50 km, saya menyimpan satu catatan dan mempertahankan versi BMKG. BMKG lebih akurat untuk gempa di Indonesia. Tidak ada yang bisa membaca "217 gempa di atas magnitudo 4, 14 di atas 5, 2 di atas 6". Jadi saya menggabungkannya menjadi satu skor dari 100: frekuensi bernilai 40 poin, magnitudo terbesar yang tercatat 30, porsi gempa dangkal 15, dan kedekatan dengan sesar 15. Halaman metodologi mencantumkan setiap bobot, dan situs ini hanya menggambarkan riwayat, menyatakan dengan jelas bahwa ia bukan sistem peringatan dini tsunami, serta menautkan peringatan resmi BMKG.
Saat server ditiadakan, proses build menjadi pipeline data
Rancangan awalnya adalah server yang mengecek gempa baru setiap lima menit. Sekitar sebulan kemudian, saya memindahkan situs publiknya ke GitHub Pages, tanpa backend. Kini sebuah job terjadwal mengambil kejadian baru, membangun ulang profil, lalu menerbitkan situsnya. Untuk "membekukan" API, saya menjalankan kode API yang asli dan menyimpan jawabannya sebagai berkas yang mengikuti URL live. Datanya tidak bisa melenceng dari jawaban server.
Browser menjalankan hitungan risiko yang sama, dicek di 39 titik
Tanpa server, pengecekan "apakah saya di zona rawan?" harus berjalan di ponsel. Saya memindahkan mesin risikonya dari Python ke TypeScript. Dua salinan rumus lama-lama akan berbeda, jadi saya mengunci jawaban server di 39 titik uji. Deploy berhenti kalau versi browser berbeda di salah satunya. Supaya sekitar 70 ribu kejadian bisa dimuat di ponsel, saya mengemasnya dalam array angka yang ringkas, sekitar 1,1 MB.
Riwayat gempa dicadangkan dua kali
BMKG hanya menampilkan 15 kejadian terakhir, jadi setiap catatan BMKG yang lebih lama ada karena pernah disimpan oleh proses sebelumnya. Di antara proses, database-nya tersimpan di cache build yang bisa terhapus kapan saja. Saya mencadangkannya setiap hari, dan menyimpan snapshot permanen setiap bulan. Kalau pencadangan gagal, penerbitan tetap jalan. Data gempa baru lebih penting daripada cadangannya.
Saya membangun ulang beranda dan palet warna di sekitar alat pengecek risiko
Audit desain yang saya lakukan sendiri menemukan bahwa beranda yang sudah terbit lebih mengutamakan peta live dan daftar kejadian, sementara tujuan sebenarnya aplikasi ini, sebuah jawaban risiko dari data puluhan tahun, tersembunyi satu klik di balik tautan navigasi. Saya menurunkan feed live menjadi ticker, melebur tampilan perbandingan dan eksplorasi ke dalam halaman wilayah sebagai konteks inline, dan menjadikan seismogram riwayat gempa suatu wilayah sebagai objek visual utama halaman. Palet gelap yang lama memakai satu warna untuk tombol, tautan, judul, dan pita kedalaman, tepat di sebelah warna merah tingkat risiko, sehingga hasil HIGH tidak membawa makna warna tersendiri. Kini chrome-nya hanya tinta, dan warna disediakan khusus untuk kedalaman dan tingkat risiko.
Hasilnya
GempaWatch sudah live sejak Agustus 2026, dengan 70.271 gempa dari 1970 sampai 2026, gabungan BMKG dan USGS. Target di rencana awalnya lebih dari 10.000. Situs ini punya laporan risiko lokasi, profil 52 wilayah lengkap dengan grafik, papan peringkat wilayah dengan perbandingan yang sudah dilebur ke dalamnya, peta sesar dan bahaya, kartu risiko yang bisa dibagikan, dan ticker gempa live. Versi server lengkapnya, dengan peringatan email, sudah selesai dan berjalan lewat Docker Compose, tapi belum di-hosting. Saya membangunnya sendiri selama sekitar tiga bulan, dalam tiga tahap antara Juli dan September 2026.
Di balik layarDetail teknis untuk engineer
- Backend: Django dengan GeoDjango dan PostGIS, 7 app dan 6 model (EarthquakeEvent, AdminRegion, RegionRiskProfile, FaultLine, HistoricalDisaster, LocationWatch),
djangorestframework-gisuntuk GeoJSON yang langsung dipakai Leaflet. Pada deployment statis yang terbit, profil wilayah dihitung ulang setiap siklus terbit ~30 menit olehmanage.py refresh_for_export, bukan setiap malam; jadwal Celery malam hari hanya berlaku untuk rancangan mode live, dan tidak ada server live yang terkonfirmasi berjalan. Pengecekan satu titik adalah satu-satunya perhitungan live. - Deduplikasi: kejadian dalam selisih 5 menit dan 50 km dianggap satu catatan; laporan BMKG menimpa catatan USGS yang sudah tersimpan.
- Bobot skor: frekuensi 40, magnitudo maksimum 30, porsi gempa dangkal 15, kedekatan sesar 15. Atribusi BMKG wajib secara hukum, ditampilkan oleh komponen
SourceAttributiondi setiap tampilan yang memakai datanya. manage.py export_staticmenjalankan view DRF yang asli dan menulis pohon JSON yang cocok dengan URL live.api.live.tsdanapi.static.tsberbagi satu antarmuka, dipilih lewat konstanta saat build sehingga klien yang tidak dipakai ikut dibuang dari bundle.manage.py export_risk_fixturesmengunci keluaran Django di 39 titik. Suite Vitest memastikan port TypeScript cocok di setiap titik, terhadap fixture yang dibuat ulang di workflow deploy. Konvensinya: ubah Python dulu, buat ulang fixture, baru sesuaikan port-nya.- Tes frontend (Vitest): 163 tes di 6 berkas — mesin skor (33), pencarian provinsi (1), fungsi bantu pulau/geografi (18), penyusunan data seismogram (16), integritas struktur API statis di setiap wilayah yang diterbitkan (16), dan suite kecocokan Django dengan 79 tes. Tidak ada test suite backend.
- Kejadian disimpan dalam typed array paralel, sekitar 1,1 MB. Tetap Float64 karena Float32 tidak bisa menyimpan magnitudo seperti 6,6 secara tepat, dan itu akan memunculkan lagi ketidakcocokan yang ingin ditangkap fixture.
- Database dibawa antarproses CI lewat cache GitHub Actions (terhapus setelah 7 hari tidak dipakai). Cadangan: artifact workflow harian yang disimpan 90 hari, plus snapshot bulanan sebagai release asset. Dipilih release asset karena meng-commit ~8 MB per bulan ke git akan menambah ukuran setiap clone ~100 MB per tahun. Kedua langkah memakai
continue-on-error. Kalau cache hilang, database dipulihkan dari bootstrap USGS penuh, tanpa gempa terasa dari BMKG. - Cron diatur 30 menit; kesegaran yang teramati 70–90 menit. Gambar OpenGraph per wilayah kembali ke kartu situs, karena Next 14 tidak bisa prerender route gambar metadata dengan
output: export. Route yang butuh backend diberi nama*.live.tsxdan hanya didaftarkan untuk build live. - Basemap peta diganti di tengah proyek: PRD menyebut tile CartoDB/OpenStreetMap berkunci, tapi kini yang terbit adalah ekstrak Protomaps yang di-hosting sendiri dari
public/tiles/milik frontend, tanpa dependensi eksternal atau kunci saat runtime. - Palet gelap "Fault Line" dari PRD digantikan sistem "Kertas & Tinta" yang light-default, memakai Plus Jakarta Sans dan JetBrains Mono. Warna teks redup terukur sekitar 3,4:1 terhadap kartu, di bawah WCAG AA, jadi semua token teks disetel ulang. Warna hex juga diam-diam merusak modifier opacity Tailwind; kini setiap warna dideklarasikan sekali sebagai kanal RGB yang dipisah spasi.
- Data referensi: 6 fitur sesar, 52 batas wilayah administratif, 20 catatan bencana historis (Aceh 2004 sampai Cianjur 2022, naik dari 6 sebelumnya). Di luar PRD: persentil, papan peringkat wilayah, perbandingan yang dilebur ke halaman wilayah, daftar periksa kesiapsiagaan "Siap Gempa", dan langganan email pantauan lokasi.
- Semua grafik memakai Recharts; daftar "Recharts + D3.js" di PRD sudah tidak akurat, D3 tidak ada di kodenya.
- 4 viewset DRF (gempa, wilayah, sesar, bencana), 3 endpoint mandiri (pengecekan risiko, zona pesisir tsunami, meta) dan 2 endpoint peringatan; 10 route frontend statis plus 2 yang khusus live; sekitar 56 komponen; workflow CI/CD 320 baris. 119 commit dari 1 Juli sampai 27 September 2026, dalam tiga tahap; sekitar 2.800 baris Python backend dan 7.800 baris kode frontend.
Tangkapan layar
Sedang merekrut, atau membangun hal serupa?
Saya terbuka untuk posisi full-time dan proyek freelance tertentu.