Blog
Catatan teknis seputar web development, DevOps, dan integrasi AI.
500 artikel
- 10.44database
Satu Tabel untuk Banyak Tipe Organisasi
Satu tabel organisasi dengan kolom nullable per tipe lebih murah dirawat daripada satu tabel per tipe, asal tiga konsekuensinya diterima sadar.
TL;DR: Saya membuat portal layanan publik. Tabel organizations memuat semua kolom yang dimiliki tipe mana pun. Saya pilih satu tabel generik dengan kolom tambahan nullable.
#mysql#database-schema#migration - 22.05backend
Dua Bucket dan Satu Tutup: Meredam Endpoint Saran Kritik
Endpoint umpan balik publik butuh dua pertahanan sekaligus: batas ukuran badan permintaan sebelum decode dan dua bucket rate limit per akun setelah autentikasi.
TL;DR: Endpoint form saran lolos tes fungsional, tapi review keamanan nemu dua bolong: body JSON tanpa batas ukuran dan nggak ada rate limit. Fixnya gampang: MaxBytesReader 32 KiB buat ukuran, plus dua bucket limit per akun (1 kirim per 10 menit, 5 per hari) yang dipasang setelah auth biar kuncinya ID user, bukan IP. Terakhir, array kosong admin jangan jadi null.
#go#security#rate-limit - 20.43backend
Batas Upload 8 MiB: Satu Angka, Empat Lapisan
Satu batas upload bukan satu setting: FastAPI ternyata tidak menolak berkas besar. Gerbang aslinya ada di browser, nginx, dan Next.js.
TL;DR: Unggahan 8,5 MiB di KotaPortal gagal nyeleneh, tadinya dikira FastAPI yang nolak. Ternyata FastAPI nggak nolak otomatis, gerbangnya ada di empat tempat: browser, nginx (default 1 MiB), Server Actions Next.js (default 1 MB), dan kode aplikasi. Solusinya gampang: samain konstanta 8 MiB di keempat lapisan biar nggak ada celah.
#file-upload#nginx#fastapi - 19.51devops
Memperbaiki Tautan Bukti Setelah Penulisan Ulang Riwayat Git
Hash commit berubah massal saat riwayat git ditulis ulang. Remap referensi Bukti lewat commit-map, termasuk penanganan hash nol.
TL;DR: Jadi gini, pas riwayat repo dibersihin, hash commit ikut berubah semua, bukan cuma yang ada datanya. Hash lama di kolom Bukti jadi mati, tapi tenang, file commit-map nyimpen pemetaan lama ke baru. Pelajarannya: jangan simpen hash mentah buat jangka panjang, mending pakai tag atau branch per isu.
#git#git-filter-repo#commit-map - 19.06security
Roster Publik Tanpa Bocor PII: Topeng di API, Bukan di Layar
Menyembunyikan kolom sensitif di UI bukan perlindungan. Topeng yang benar ada di lapisan API, dibuktikan asersi negatif E2E.
TL;DR: Sering banget kolom sensitif disembunyiin di layar tapi API tetap kirim semua data, nah itu bocor bahkan ada namanya di OWASP. Solusinya masking di lapisan API pakai DTO yang cuma isinya data publik, sesuai UU PDP soal pengumpulan yang terbatas. Terus diuji pakai asersi negatif biar kebukti data pribadi nggak pernah nyampe ke browser.
#privacy#security#playwright - 04.27backend
Seed Migration dan Status Mapping untuk Import Fasilitas Budaya
Membuat kategori baru lewat seed migration yang idempoten, lalu import data fasilitas budaya dengan pemetaan status eksisting dan rencana.
TL;DR: Artikel ini cerita soal import 8 fasilitas budaya PPKD pas kategori "Sarana Budaya" belum ada di database. Solusinya pakai seed migration idempoten dengan ON DUPLICATE KEY UPDATE, jadi aman dijalankan ulang di environment mana aja. Fasilitas eksisting langsung published, yang rencana masuk draft, dan importernya ada dry-run plus guard development biar gak ada duplikat.
#go#mysql#data-import - 04.22backend
Koreksi Data Cagar Budaya: Pool Matching Tanpa Kunci Unik
Proses korektif data cagar budaya PPKD gagal karena nomor SK bukan kunci unik. Pool kandidat dan overlap coefficient menyelesaikan masalah pencocokan 1:1.
TL;DR: Import data cagar budaya dari PPKD ternyata ribet karena satu nomor SK bisa isinya banyak objek, jadi nggak bisa dipakai sebagai kunci unik. Solusinya, data dicocokin pakai pool kandidat berdasarkan kemiripan nama dengan overlap coefficient, plus guard biar satu entitas nggak ketimpa dua kali. Kolom yang di-update juga dibatesin biar data yang udah bener nggak rusak.
#go#mysql#data-import - 23.52backend
Kontrak Tanggal Polos Bukan Instant pada Form Agenda KotaPortal
event_date pernah meninggalkan browser sebagai instant T00:00:00Z. Kontraknya kini YYYY-MM-DD polos, dan helper klien yang dulu memperbaikinya dihapus.
TL;DR: Field tanggal acara tadinya dikirim sebagai instant UTC tengah malam, jadi tanggalnya bisa geser sehari gara-gara zona waktu. Fix-nya: ubah kontrak API jadi format date polos YYYY-MM-DD, validasi di service, dan tipe Go diganti *string biar decoder nggak protes. Klien lama yang masih kirim instant bakal gagal keras, tapi itu lebih sehat daripada salah simpen diam-diam.
#api#openapi#go - 22.51devops
Menutup Pintu Tidak Menyembunyikan Laci
Port deploy ditutup, /.git/ tetap kebaca lewat hostname staging. Dua lapis penutup berikutnya: guard regex nginx edge dan network split api/db.
TL;DR: Tutup port inbound doang ternyata belum cukup aman, soalnya path sensitif kayak .git dan .env masih kebuka lewat hostname staging. Solusinya tiga lapis: blokir dotfiles di nginx edge, pisah network Docker per kelompok service biar nggak ada jalur lateral, plus server_tokens off buat sembunyiin versi. Kuncinya, satu lapis nggak cukup, harus saling nutup lubang.
#nginx#docker#devops