Penyelarasan Menu Baru Otomatis ke Seluruh Peran
Setiap kali ada halaman baru dibuat, sistem otomatis menyiapkan izin akses untuk seluruh peran tanpa perlu konfigurasi database manual yang melelahkan.
Setiap kali ada halaman baru dibuat, sistem otomatis menyiapkan izin akses untuk seluruh peran tanpa perlu konfigurasi database manual yang melelahkan.
Tantangan & Kebutuhan Pengguna
Dalam sistem RBAC berbasis matriks `Role × Feature`, menambah satu feature baru atau mengubah aksi yang didukung suatu feature (misalnya mencabut aksi `delete` dari suatu modul) sering kali menyisakan baris izin yatim atau tidak sinkron di database. Jika sebuah feature baru ditambahkan tanpa langsung menyiapkan baris `role_permissions` untuk seluruh role yang ada, tampilan matriks izin akan timpang dan role Super Admin bisa kehilangan akses ke fitur yang baru dibuat.
Perubahan pada definisi sebuah fitur harus secara atomik merambat ke seluruh role yang ada di sistem tanpa pernah meninggalkan matriks izin dalam keadaan setengah jadi.
Solusi & Cara Kerja
Pada `modules/dashboard/feature/feature.service.ts`, pembuatan dan pembaruan feature dibungkus di dalam `prisma.$transaction`. Ketika `createFeature()` dipanggil, sistem otomatis mem-provision baris `role_permissions` untuk setiap role di database: seluruh role standar diberi nilai `false` secara aman (*secure by default*), sedangkan role `Super Admin` otomatis diberi nilai `true` untuk semua `availableActions`. Ketika `updateFeature()` mengubah daftar aksi yang tersedia, sistem menghitung selisih himpunan aksi yang dicabut (`removed`) dan aksi yang baru ditambahkan (`added`), lalu menyelaraskan seluruh baris `role_permissions` dalam satu transaksi.
Detail & Hal yang Diperhatikan
- Proteksi Penghapusan Fitur Inti Sistem: Konstanta `SYSTEM_FEATURE_KEYS` melindungi modul bawaan (`user`, `role`, `feature`, `permission`, `audit`, `security`, dll.) agar tidak dapat dihapus oleh siapa pun dari antarmuka maupun Server Action.
- Constraint Unik & Cascade di Level PostgreSQL: Skema `RolePermission` menerapkan `@@unique([roleUuid, featureUuid])` dan `onDelete: Cascade` sehingga duplikasi baris mustahil terjadi dan penghapusan feature kustom otomatis membersihkan baris izinnya.
- Penggunaan UUIDv7 Berurutan Waktu: Seluruh tabel menggunakan `@id @default(uuid(7))` yang memiliki awalan timestamp milidetik sehingga penyisipan massal (`createMany`) pada indeks B-Tree PostgreSQL tetap terurut dan bebas fragmentasi.
Selain melalui UI dashboard, sinkronisasi deklaratif dari kode ke database dapat dijalankan kapan saja melalui perintah `npm run db:sync` (`scripts/sync-features.ts`).