Blog
Catatan teknis seputar web development, DevOps, dan integrasi AI.
502 artikel
- 08.57frontend
Sidebar Admin Per-Modul: Ilusi Aman di UI, Sejati di API
Menyembunyikan menu di sidebar admin bukan otorisasi. Pengalaman membangun halaman konten per-modul dengan sidebar ter-scope bidang.
TL;DR: Awalnya ngira cukup sembunyiin menu sidebar biar aman, ternyata itu cuma kosmetik doang. Soalnya cek di layout Nextjs bisa basi dan gampang dibobol lewat manipulasi URL manual. Akhirnya solusinya dobel lapis, frontend cuma buat UX, backend pakai NarrowModules yang balikin list kosong biar nggak bocorin info.
#nextjs#react#go - 08.11devops
Upload Gambar ke Komentar Plane Saat MCP Tidak Bisa Upload
MCP Plane nggak punya aksi upload file dan SSRF guard memang menolak URL privat. Jalan keluarnya turun satu level: FileAsset plus S3Storage dari dalam container.
TL;DR: Mau nempelin screenshot ke komentar Plane ternyata ribet karena di UI gak ada tombol upload dan MCP server juga gak support upload file. Nyoba akalin pake URL lokal malah ke-blok SSRF guard, pake API key internal juga ditolak. Akhirnya solusinya turun level ke container, copy file ke plane-api, bikin FileAsset dan update komentar pake tag img biar muncul.
#plane#mcp#docker - 08.07testing
E2E Modul Admin: Menguji Guard Role dan Bidang Lewat UI
Tiga spec Playwright buat area admin: login via UI beneran, CRUD sampai hapus permanen dengan verifikasi API, dan guard role/bidang yang diuji di level server.
TL;DR: Gue kira redirect frontend buat blokir editor dari menu Pengguna, ternyata gampang dibobol kalau backend gak ikut ngejaga. Jadi tes e2e nya ngecek dua lapis, menu yang ngilang di UI dan server yang wajib ngasih 403 kalau dipaksa bikin user. Ada trik login pakai exact biar gak salah klik, isi Tiptap lewat ProseMirror, sama cek hapus data langsung via API.
#playwright#e2e#testing - 08.06backend
Satu Baris yang Terlupa: Mapper DTO yang Menghancurkan Frontend
Field Status ada di entitas tapi hilang di mapper: API membalas string kosong, halaman edit crash. Satu baris plus regresi test menutupnya.
TL;DR: Bug muncul karena field status lupa dipetakan di dto announcement jadi frontend dapet string kosong dan crash pas baca badge. Di backend ditambahin mapping yang hilang plus test regresi, di frontend dibikin helper toFormStatus yang cuma izinin published dan scheduled sisanya jadi draft. Sekalian navigasi diganti dari window location ke router push dan refresh biar toast nggak hilang.
#golang#react#typescript - 07.30database
Kosmetik yang Memaksa Rombak Kontrak Data
Minta huruf kecil kelihatan sepele; padahal nilai enum dibandingkan literal di enforcement scope, jadi DDL, baris, konstanta, spec, dan map label pindah bareng.
TL;DR: Kirain cuma ganti huruf kapital jadi kecil, ternyata ribet karena casing itu ngaruh ke izin akses. Jadinya harus migrasi bareng-bareng di database, backend sampai frontend biar nggak error dan user kekunci. Pengecualian cuma ALL yang tetap kapital karena itu buat superadmin.
#mysql#go#migration - 07.28frontend
Saat PARIWISATA Teriak di Tengah Dropdown yang Seharusnya Rapi
Nilai enum UPPERCASE bocor ke empat titik render admin; cukup satu formatter jadi pintu tunggal display, fallback ?? tetap jadi pedang dua mata.
TL;DR: Dropdown bidang nampilin huruf kapital semua padahal data di DB emang sengaja disimpan uppercase. Ternyata ada empat titik yang kelupaan pakai formatter formatBidang jadi masih ngasih nilai mentah. Fix-nya simpel tinggal colok formatter itu biar label jadi Title Case tapi value tetap uppercase biar nggak error validasi.
#typescript#react - 07.26testing
Ketika Tabel Migrasi Berbohong di Test Integrasi Bidang
Suite hijau padahal skema test DB basi: schema_migrations cuma catat file migrasi, volume Docker lama diam-diam bawa skema lama.
TL;DR: Test ijo semua tapi gue curiga kolom bidang belum kebawa di DB beneran. Ternyata volume MySQL lama masih kepake, migrate ngeliat versi 58 jadi skip padahal skema basi. Sekarang tiap test dibersihin total pake down --volumes biar migrasi jalan dari nol dan hasilnya beneran valid.
#go#mysql#testing - 06.25backend
Set Bidang User Lain: Aksi Istimewa, Bukan Field Biasa
Hanya superadmin boleh menentukan bidang user lain; default ALL bikin 19 user lama lolos migrasi tanpa terkunci.
TL;DR: Nambah kolom bidang ke users sih gampang, yang ribet tuh nentuin siapa boleh atur scope orang lain. Akhirnya diputus cuma superadmin yang boleh set bidang lewat resolveBidang, kalau admin/editor maksa kirim bakal kena 403 tapi kalau nggak kirim tetap bisa edit field lain. Default-nya dibikin ALL biar 19 user lama nggak kekunci pas deploy dan semua aman terkunci test.
#go#mysql#security - 06.25backend
Scope Pengumuman: Menulis Nilai vs Mengubah Baris
Dua fungsi otorisasi pengumuman per bidang: resolveBidang untuk nilai baru, canManage untuk baris eksisting, NULL sebagai global.
TL;DR: Dulu semua admin bebas ubah pengumuman apa aja, sekarang dibatasi per bidang biar nggak tabrakan. Dibuat dua fungsi misah, resolveBidang buat nentuin boleh nulis ke bidang apa dan canManage buat ngecek boleh ngedit baris punya siapa. Konten global ditandai NULL bukan ALL, cuma admin ALL yang bisa ngatur, dan ceknya dipasang sebelum data keubah.
#go#mysql#security