Sidebar Empat Grup: Navigasi Ikut Izin, Bukan Jenis Konten
Sidebar admin KotaPortal dipecah jadi empat grup berdasarkan izin: milik sendiri untuk tulis, lintas bidang untuk baca, grup sementara untuk backend belum siap.
Ringkasan
Panel admin KotaPortal kini memecah sidebar jadi empat grup yang nunjukkin izin baca atau tulis tiap bidang, tanpa ubah logika auth. Item dikelompokin otomatis dari satu peta kemampuan, plus pill bidang dan banner yang sebut pemilik konten. Navigasi cuma petunjuk, gerbangnya tetap di server, dan semua lolos uji.
Tab Modules di panel admin KotaPortal membuka sidebar yang sama sejak awal proyek: lima bidang dalam satu daftar datar. Wisata, Ekonomi Kreatif, Olahraga, Budaya, Kepemudaan berdiri sejajar tanpa tanda mana yang boleh ditulis oleh staf yang sedang masuk. Brief klien pada 10 Oktober lalu menegaskan aturan yang berlawanan dengan tampilan itu: setiap bidang harus dapat membaca seluruh konten, tetapi hanya menulis di lingkupnya sendiri. Daftar datar bukan sekadar tampilan yang kurang rapi. Ia menutupi dua hak akses yang berbeda dalam satu tumpukan menu.
Perubahan pada 16 Oktober (commit 60dbe36) sama sekali tidak menyentuh rute, endpoint, maupun logika autentikasi. Yang berubah hanya cara navigasi disusun: sidebar dipecah menjadi empat grup, dan tiap grup membawa makna izin yang bisa dibaca pengguna sebelum menekan tautan apa pun.
Empat Grup dengan Makna Izin
Grup pertama, Bidang Anda, berisi module milik bidang pengguna. Tidak ada penanda khusus di dalamnya, karena ketiadaan penanda berarti berhak menulis. Grup kedua memuat delapan fungsi yang backend-nya belum ter-scope, dan diberi label Fungsi — Lintas (Sementara): status transisi yang dipertegas di depan pengguna, bukan tautan yang disembunyikan. Begitu pengerjaan slice 2 selesai, fungsi tersebut pindah ke Bidang Anda.
Grup ketiga, Lintas Bidang — Baca, berisi konten milik bidang lain dengan status tertutup secara default dan ikon mata sebagai penanda baca-saja. Grup keempat hanya berfungsi untuk Semua Bidang. Dua detail komunikasi menyertai keempat grup itu: pill identitas bidang di sidebar desktop dan di header mobile, serta banner read-only yang kini menyebut pemilik konten, "Mode baca — konten ini milik bidang Olahraga", alih-alih frasa "data bidang lain" yang tidak menjelaskan apa-apa.
Satu Peta Kemampuan, Bukan Empat Daftar
Keempat grup tersebut tidak ditulis sebagai empat daftar statis. Item NavItem memperoleh penanda readOnly, lalu fungsi buildNavGroups mengelompokkannya berdasarkan satu peta kemampuan: BIDANG_MODULE_SLUGS dari modul RBAC menentukan module yang menjadi milik bidang pengguna, dan seluruh modul lain jatuh ke grup baca. Prinsipnya sesuai cara kerja React, yang menampilkan JSX berbeda sesuai kondisi [4]; yang diperlukan hanya satu kondisi yang benar sebagai sumbernya.
// Slug menu konten ke users.bidang pemiliknya, khusus copy banner.
// Terpisah dari MODULE_TO_SLUG: arah dan kebutuhan berbeda,
// ini label bidang, bukan slug.
export const SLUG_TO_BIDANG: Record<string, string> = {
wisata: "pariwisata",
"ekonomi-kreatif": "ekraf",
olahraga: "olahraga",
budaya: "budaya",
kepemudaan: "kepemudaan",
};
Peta kedua ini murni untuk komunikasi: nilai di dalamnya dipakai menulis nama bidang pemilik pada banner read-only. Nama peta sendiri menyebut slug karena ia memetakan arah yang berbeda dari MODULE_TO_SLUG, yaitu label, bukan rute.
Pemisahan ini juga membuat navigasi lebih ramah pembaca layar. MDN menyebut nav sebagai landmark yang mengidentifikasi kelompok besar tautan, dan bila sebuah halaman memuat lebih dari satu landmark navigasi, masing-masing perlu label unik [2]. Grup dengan nama yang berbeda memberi struktur itu secara gratis. Di sisi mobile, drawer dibuka lebih dulu sebelum asersi menu diuji, sementara pill desktop tetap ter-attach dengan display: none di mobile sehingga dibuat helper terpisah alih-alih penggabungan .or().
Mengapa Navigasi Tidak Boleh Menjadi Gerbang
Ada satu jebakan yang tidak diselesaikan oleh tampilan mana pun. Panduan autentikasi Next.js memperingatkan bahwa layout tidak di-render ulang saat pengguna berpindah halaman, sehingga pemeriksaan sesi di layout tidak berjalan pada setiap perubahan rute; pemeriksaan sebaiknya dilakukan di dekat sumber data [1]. OWASP tegas: pemeriksaan sisi klien tidak boleh menjadi penentu, karena logika klien mudah dilewati, dan izin harus divalidasi pada setiap permintaan [3]. Navigasi yang rapi hanyalah petunjuk; gerbangnya tetap di server, dan pada kasus ini gerbang itu sudah ada berkat aturan baca lintas terbuka dengan tulis 403.
Yang membuat keempat grup itu bisa dipercaya adalah bukti ujiannya. Sebelum uji jalur menu dimulai, login admin sempat diulang dalam loop karena batas 10 percobaan per menit per kombinasi IP dan surel membuat run beruntun bisa gagal. Hasil akhirnya: lint tanpa error, build lolos, 206 unit test lulus, uji menu modul 8/8 di chromium dan mobile, serta suite admin 43/46 dengan tiga kegagalan mobile yang terklasifikasi sebagai pra-eksisting.
Sisa keputusan menutup perubahan ini dengan prinsip yang sama: status sengaja dibiarkan terlihat. Grup Sementara mencegah pengguna bertanya-tanya mengapa sebagian menu mendadak hilang, dan mencegah tim menghapus tautan yang hanya sedang menunggu backend selesai. Navigasi yang jujur soal apa yang belum siap lebih berguna daripada menu yang bersih namun menyesatkan.
Sumber: