sql
Catatan teknis seputar web development, DevOps, dan integrasi AI.
29 artikel
- 10.00backend
Counter yang Bohong: Filter Tanggal dan Dua Jam
Counter bilang 12, tabel bilang 15: filter tanggal ngitung jam yang salah. Perbaikannya hitung dari riwayat transisi, bukan kolom status.
TL;DR: Awalnya angka di dashboard admin nggak sinkron, header bilang 12 tapi tabel malah 15. Ternyata bukan cache error, tapi querynya salah pakai created_at padahal harusnya ngitung dari riwayat changed_at. Akhirnya querynya diganti join ke ticket_history biar hitungannya jujur sesuai kapan status beneran berubah.
#postgresql#dashboard#reporting - 09.34backend
Loncat Status, Email Ganda, dan Batas Transaksi
Satu tiket loncat dua status, warga dapat email dobel: akarnya dual-write. Perbaikannya peta transisi, 409, riwayat, dan outbox.
TL;DR: Awalnya tiket komplain bisa loncat status dan ngirim dobel email gara-gara dual-write bug. Ternyata ngirim email langsung di dalam transaksi itu rawan ghost email kalo rollback atau crash. Akhirnya dibenerin pake peta transisi yang nolak pake 409, riwayat append-only satu transaksi, dan outbox biar email kekirim eventual lewat worker.
#postgresql#http#outbox - 07.57database
Ganti Kosakata Status Tanpa Sekali Jalan: ENUM Tiga Langkah
Enam status baru, empat status lama. MODIFY + UPDATE + MODIFY bikin kosakata status ganti tanpa copy tabel dan tanpa baris invalid di tengah jalan.
TL;DR: Spec butuh enam status baru tapi DB masih pakai empat status Inggris lama jadi nggak bisa asal ganti kolom. MySQL cuma boleh nambah ENUM di akhir biar in-place, kalau diselip di tengah malah copy tabel dan data bisa geser. Makanya migrasinya dibikin tiga step expand-migrate-contract, down-nya lossy dan relasi sengaja nggak pakai foreign key biar soft delete aman.
#mysql#migration#schema - 11.21backend
Filter bidang tanpa menelan baris global
Nambah parameter ?bidang= di endpoint publik bukan cuma soal satu klausa WHERE. Baris global harus tetap tayang di semua scope.
TL;DR: Awalnya filter bidang cuma pakai WHERE biasa jadi konten global yang NULL malah kelewat nggak muncul. Akhirnya querynya dibenerin jadi ikut nampilin yang NULL sama ALL terus ditambah validasi 400 kalau bidangnya ngaco. Sekalian cache key ditambahin bidang dan teks intro pilar dipindah ke tabel settings biar gampang diatur.
#go#mysql#api - 10.47frontend
Pindah Route /wisata: 308, Menu Tak Tertimpa
Rename route publik itu tiga langkah sekaligus: pindah folder route, redirect 308, dan migrasi baris menu yang hormati editan admin.
TL;DR: Kukira mindahin route wisata ke pariwisata tinggal git mv doang, ternyata harus tiga hal bareng biar nggak berantakan. Di Nextjs dipasang redirect 308 wildcard jadi bookmark lama tetap nyambung tanpa ngubah method POST. Di database migrasi cuma geser data menu yang masih bawaan, yang udah diedit admin nggak ditimpa.
#nextjs#redirect#mysql - 21.37testing
Guard yang Bilang Tidak dan Jalan Pulang Migrasi
Commit test-only: pembuktian guard global via httptest dan jalur down migrasi di MySQL 5.7 beneran mundur lalu pulih.
TL;DR: Ternyata file down migration sama middleware penolak nggak pernah ditest beneran. Sekarang guard-nya diuji pakai table-driven test, yang ALL lolos 200 tapi bidang lain kena 403 kecuali konteks kosong yang sengaja fail-open. Terus jalur down juga dibuktiin lewat tes integrasi yang nurunin migrasi ke 56 sampai kolomnya hilang lalu naik lagi sampai balik.
#go#testing#mysql - 21.33backend
Satu Query Param, Tiga Lapis: Filter ?module= yang Aman
Nambah filter ?module= bukan cuma urusan WHERE: validasi 400 di handler, subquery parameterized, dan cache key per kombinasi filter.
TL;DR: Cachenya awalnya cuma mappoints:all jadi kalau filter module cuma ditempel di SQL, data bisa ketuker parah. Makanya dibikin tiga lapis pertahanan biar aman. Validasi dulu kalau modulnya ngaco langsung 400, query-nya pakai parameterized, dan cache key-nya dipisah sesuai filter.
#go#api#caching - 12.58backend
Save Tanpa Perubahan Kok 404? Kala RowsAffected Menipu
Simpan form tanpa perubahan kok dibalas 404? Ternyata RowsAffected MySQL menghitung baris berubah, bukan baris cocok. Fix: cek eksistensi saat nol.
TL;DR: QA nemu bug, pencet save tanpa ubah data malah 404 padahal datanya ada. Ternyata MySQL ngitung RowsAffected itu yang beneran berubah, bukan yang kecocok, jadi kalo nilainya sama hasilnya nol dan kekira nggak ketemu. Fix-nya sekarang kalo hasilnya nol dicek dulu pake SELECT biar tau beneran nggak ada atau cuma nggak ada yang berubah.
#mysql#go#debugging - 10.58backend
Jangan Percaya omitempty Saat Ekspos Kolom JSON-TEXT Publik
Kolom JSON-TEXT yang nullable tidak cukup ditutup omitempty: omitempty hanya kenal kekosongan Go, bukan NULL versi SQL. Ini cerita empat lapisan eksposnya.
TL;DR: Gue kira cukup tambah field attributes pakai omitempty, eh malah zonk karena kosong versi SQL dan Go beda. Ternyata data harus lewat empat lapis dan kuncinya di mapper yang ubah NULL, string kosong atau 'null' jadi nil. Frontend tinggal pakai ?? {} biar aman kalau fieldnya hilang.
#go#mysql#api