Alur Hak Akses & Peran
Kontrol akses dibangun dari Spatie Laravel Permission + Filament Shield.
Tiga lapis penjagaan
User::canAccessPanel() hanya memeriksa satu hal: user punya minimal satu role. User tanpa role sama sekali tidak bisa masuk /admin walaupun akunnya valid.
Lima peran bawaan
Dibuat oleh RolePermissionSeeder.
Matriks izin bawaan
| Model / Fitur | super_admin | admin | petugas | dokter |
|---|---|---|---|---|
| User | ✅ semua | 👁️ + Create + Update | ❌ | ❌ |
| Role (Peran User) | ✅ semua | 👁️ baca | ❌ | ❌ |
| Setting (Pengaturan) | ✅ semua | 👁️ + Update | ❌ | ❌ |
| Patient | ✅ semua | ✅ CRUD penuh | 👁️ + Create + Update | 👁️ baca |
| Doctor | ✅ semua | ✅ CRUD penuh | 👁️ baca | 👁️ baca |
| Polyclinic | ✅ semua | ✅ CRUD penuh | 👁️ baca | 👁️ baca |
| DoctorSchedule | ✅ semua | ✅ CRUD penuh | 👁️ + Create + Update | 👁️ baca |
| Appointment | ✅ semua | ✅ CRUD penuh | 👁️ + Create + Update | 👁️ + Update |
| Billing | ✅ semua | ✅ CRUD penuh | 👁️ + Create + Update | 👁️ baca |
| Package | ✅ semua | ✅ CRUD penuh | ❌ | ❌ |
| TokenPrice | ✅ semua | ✅ CRUD penuh | ❌ | ❌ |
| Contact | ✅ semua | 👁️ + Update + Delete | 👁️ + Update | 👁️ baca |
| ChatLabel | ✅ semua | ✅ CRUD penuh | 👁️ + Create + Update (tanpa hapus) | ❌ |
| WhatsappBusinessAccount | ✅ semua | ✅ CRUD penuh | ❌ | ❌ |
| BookingRequest | ✅ semua | 👁️ baca saja | 👁️ baca saja | ❌ |
Draft booking dibuat oleh alur pembayaran dan hanya boleh berubah lewat callback Duitku atau sapuan terjadwal. Izin tulisnya tidak pernah dibuat sama sekali — jadi kalau penjagaan hardcoded di resource suatu saat dilepas, tidak ada izin yang menunggu untuk membuka pengeditan.
petugas bisa melihat BookingRequest tapi dokter tidakPetugas adalah satu-satunya peran non-admin dengan Create:Appointment — dialah yang menjadwalkan manual. Ia harus bisa menemukan draft berstatus Failed (uang masuk, janji temu tak terbit). Dokter tidak diberi karena isinya nominal dan status pembayaran, bukan data klinis.
Akun bawaan seeder
| Peran | Password | |
|---|---|---|
superadmin@gmail.com | super_admin | password |
admin@gmail.com | admin | password |
dokter@gmail.com | dokter | password |
petugas@gmail.com | petugas | password |
pasien@gmail.com | pasien | password |
Akun-akun ini hanya untuk pengembangan. Wajib diganti atau dihapus sebelum go-live.
Penamaan izin
Shield membangun nama izin dengan pola {Aksi}:{Model}:
Untuk halaman (bukan resource), polanya View:{NamaPage} — contoh View:ChatRoomsPage.
Halaman kustom & permission-nya
Semua halaman kustom mewarisi ComingSoonPage, yang menambahkan penjagaan Shield.
Permission key di-cache per kelas halaman supaya tidak mengulang lookup di setiap render.
| Halaman | Permission |
|---|---|
| Chat Rooms | View:ChatRoomsPage |
| SIMRS Sync | View:SimrsSync |
| Antrian Loket | View:QueueBoardPage |
| Dashboard Antrian | View:QueueDashboardPage |
| API & SDK | View:ApiSdkPage |
shouldRegisterNavigation() memanggil canAccess(). Jadi menu yang tidak muncul selalu berarti izinnya belum diberikan ke peran user tersebut — bukan bug tampilan.
Impersonasi (masuk sebagai user lain)
Fitur dari paket filament-impersonate, diatur di config/panel-access.php.
| Env | Fungsi | Default |
|---|---|---|
FILAMENT_IMPERSONATOR_ROLES | Peran yang boleh impersonate | super_admin,admin |
FILAMENT_IMPERSONATION_BLOCKED_ROLES | Peran yang tidak boleh jadi target | super_admin |
Nilainya dipisah koma. Kalau kosong/tidak valid, sistem jatuh ke default.
Penjagaan tambahan di resource
Beberapa resource punya aturan di luar sistem izin standar:
| Resource | Aturan |
|---|---|
| User | Peran admin (yang bukan super_admin) tidak melihat user ber-role super_admin di daftar |
| BookingRequest | Baca-saja, dijaga di level resource sekaligus tidak punya izin tulis |
| WhatsappBusinessAccount | Penghapusan ditutup di level resource — bahkan super_admin tidak bisa. Diganti tombol aktif/nonaktif |
| Contact | Tombol hapus dilepas dari panel kontak |
| Chat Rooms | Non-admin hanya melihat percakapan yang di-assign kepadanya di tab Assigned |
| ChatLabel | petugas boleh membuat dan mengubah label (label bersifat global, dan dialah yang menangani chat sehari-hari), tetapi menghapus label milik tim tetap urusan admin |
Middleware CheckRole
Middleware sederhana untuk rute non-Filament:
Route::middleware('role:admin,petugas')->group(...);
Menolak dengan 403 kalau user tidak punya salah satu peran yang disebut. Berbeda dari sistem izin Shield yang berbasis permission.
Mengelola peran di UI
Menu Pengaturan → Peran User (plugin Shield) menampilkan seluruh permission dalam kotak centang, dikelompokkan per resource/halaman/widget.
Permission untuk resource atau halaman baru tidak otomatis muncul di peran yang sudah ada. Generate ulang permission Shield, lalu centang manual di peran yang membutuhkannya.