# 🔐 Sistem Hak Akses - BKD PD

## Overview
Sistem hak akses telah diimplementasikan dengan 5 role berbeda dengan scope akses yang berbeda-beda. Setiap role memiliki batasan akses berdasarkan DPC/DPD yang ditugaskan.

## 📋 Role System

### 1. **Admin Sistem** (`admin_sistem`)
- **Akses**: Semua akses **kecuali** User Management
- **Dapat**:
  - Mengelola semua data anggota
  - Mengelola semua kegiatan
  - Mengelola semua takwim
  - Mengelola mutasi dan penempatan
  - Mengelola rekomposisi
  - Mengelola statistik
  - Mengelola UPA dan aktivitas UPA
  - Mengelola yaumiyah
- **Tidak Dapat**:
  - Mengakses User Management

### 2. **Superadmin** (`superadmin`)
- **Akses**: Semua akses **termasuk** User Management
- **Dapat**:
  - Semua yang bisa dilakukan Admin Sistem
  - Mengelola User Management (create, edit, delete users)
  - Mengubah role user
  - Membuat user dengan role apapun termasuk superadmin

### 3. **Admin DPC** (`admin_dpc`)
- **Akses**: Terbatas ke DPC yang ditugaskan
- **Dapat**:
  - Data anggota di DPC nya sendiri
  - Kegiatan di DPC nya sendiri
  - Takwim di DPC nya sendiri
  - UPA di DPC nya sendiri
  - Statistik di DPC nya sendiri
  - Aktivitas UPA di DPC nya sendiri
  - Input/mengajukan mutasi untuk anggota di DPC nya
  - Input/mengajukan penempatan untuk anggota di DPC nya
- **Tidak Dapat**:
  - Mengakses data di DPC lain
  - Menyetujui mutasi (hanya bisa mengajukan)
  - Menyetujui penempatan (hanya bisa mengajukan)
  - Rekomposisi
  - User Management

### 4. **Admin DPD** (`admin_dpd`)
- **Akses**: Terbatas ke DPD yang ditugaskan
- **Dapat**:
  - Data anggota di DPD nya sendiri
  - Kegiatan di DPD nya sendiri
  - Takwim di DPD nya sendiri
  - UPA di DPD nya sendiri
  - Statistik di DPD nya sendiri
  - Aktivitas UPA di DPD nya sendiri
  - Menyetujui mutasi yang diajukan DPC yang dibawahnya
  - Menyetujui penempatan yang diajukan oleh DPC yang dibawahnya
  - Mengedit susunan penempatan
  - Rekomposisi
- **Tidak Dapat**:
  - Mengakses data di DPD lain
  - User Management
  - Input mutasi (hanya bisa menyetujui)
  - Input penempatan (hanya bisa menyetujui)

### 5. **Anggota** (`anggota`)
- **Akses**: Terbatas via mobile dan akses pribadi
- **Dapat**:
  - Akses via mobile (`/mobile`)
  - Scan kegiatan QR code via HP
  - Input penilaian takwim untuk tim takwim yang diamanahi atau tim nya sendiri
  - Mengisi yaumiyah sendiri
  - Input Aktivitas UPA untuk UPA nya sendiri
- **Tidak Dapat**:
  - Mengakses dashboard admin
  - Mengelola data anggota lain
  - Mengelola kegiatan
  - User Management

## 🗄️ Database Structure

### Users Table
```sql
- id
- name
- email
- password
- role (enum: 'admin_sistem', 'superadmin', 'admin_dpc', 'admin_dpd', 'anggota')
- is_active (boolean)
- dpc_id (nullable, foreign key ke tbl_dpc)
- dpd_id (nullable, foreign key ke tbl_dpd)
- anggota_id (nullable, foreign key ke tbl_anggota)
```

### Relasi User dengan Scope
- **Admin DPC**: Harus memiliki `dpc_id`, `dpd_id` akan otomatis di-set dari DPC
- **Admin DPD**: Harus memiliki `dpd_id`
- **Anggota**: Harus memiliki `anggota_id`, `dpc_id` dan `dpd_id` akan otomatis di-set dari anggota

## 🔧 Model Methods

### User Model

#### Role Checking Methods
```php
$user->isSuperAdmin()           // Check if superadmin
$user->isAdminSistem()          // Check if admin sistem
$user->isAdminDpc()             // Check if admin DPC
$user->isAdminDpd()             // Check if admin DPD
$user->isAnggota()              // Check if anggota
$user->hasFullSystemAccess()    // Check if admin sistem or superadmin
$user->canManageUsers()         // Check if can access user management
```

#### Scope Methods
```php
$user->getDpcScope()    // Get DPC scope (single ID or array of IDs)
$user->getDpdScope()    // Get DPD scope (single ID)
```

### HasScopeAccess Trait

#### Access Checking Methods
```php
canAccessDpc($dpcId)              // Check if user can access specific DPC
canAccessDpd($dpdId)              // Check if user can access specific DPD
applyScopeFilter($query)          // Apply scope filter to query
```

#### Permission Methods
```php
canManageUsers()                  // Can access user management
canApproveMutations()              // Can approve mutations (Admin DPD)
canApprovePlacements()            // Can approve placements (Admin DPD)
canEditPlacementComposition()     // Can edit placement composition (Admin DPD)
canDoRekomposisi()                // Can do rekomposisi (Admin DPD)
canCreateMutations()              // Can create mutations (Admin DPC)
canCreatePlacements()             // Can create placements (Admin DPC)
```

## 🛣️ Route Protection

### User Management
```php
Route::middleware(['role:superadmin'])->group(function () {
    // Hanya superadmin yang bisa akses
});
```

### Contoh Penggunaan di Controller
```php
use App\Traits\HasScopeAccess;

class AnggotaController extends Controller
{
    use HasScopeAccess;

    public function index()
    {
        $query = Anggota::query();
        
        // Apply scope filter based on user role
        $query = $this->applyScopeFilter($query, 'dpc_id', 'dpd_id');
        
        $anggotas = $query->paginate(10);
        return view('anggota.index', compact('anggotas'));
    }
}
```

## 📝 Migration

Migration telah dibuat untuk:
1. Update role enum dari `['superadmin', 'admin', 'user']` menjadi `['admin_sistem', 'superadmin', 'admin_dpc', 'admin_dpd', 'anggota']`
2. Migrasi data existing:
   - `admin` → `admin_sistem`
   - `superadmin` → `superadmin` (tetap)
   - `user` → `anggota`
3. Tambah kolom `dpc_id`, `dpd_id`, `anggota_id` di users table

## 🔄 Data Migration

Saat migration berjalan:
- User dengan role `admin` akan otomatis menjadi `admin_sistem`
- User dengan role `user` akan otomatis menjadi `anggota`
- User dengan role `superadmin` tetap `superadmin`

## 🎯 User Management

### Create User
Saat membuat user dengan role:
- **Admin DPC**: Wajib pilih DPC, DPD akan otomatis terisi
- **Admin DPD**: Wajib pilih DPD
- **Anggota**: Wajib pilih Anggota, DPC dan DPD akan otomatis terisi
- **Admin Sistem / Superadmin**: Tidak perlu DPC/DPD/Anggota

### Edit User
Saat edit user, scope (DPC/DPD/Anggota) hanya tampil dan required jika role memerlukannya.

## 🔒 Security Features

1. **Role-based Access Control (RBAC)**: Setiap route dilindungi dengan middleware role
2. **Scope Filtering**: Data otomatis di-filter berdasarkan scope user
3. **Permission Checking**: Helper methods untuk check permission sebelum action
4. **Data Isolation**: Admin DPC/DPD hanya bisa akses data di scope mereka

## 📱 Mobile Access

Role **Anggota** hanya bisa akses via:
- `/mobile` routes
- Mobile interface untuk:
  - Scan QR code kegiatan
  - Input penilaian takwim
  - Mengisi yaumiyah
  - Input aktivitas UPA

## 🔍 Implementation Examples

### Contoh: Filter Data Berdasarkan Scope
```php
// Di Controller
public function index()
{
    $user = auth()->user();
    
    if ($user->hasFullSystemAccess()) {
        // Admin Sistem & Superadmin: bisa akses semua
        $anggotas = Anggota::paginate(10);
    } elseif ($user->isAdminDpc()) {
        // Admin DPC: hanya DPC nya
        $anggotas = Anggota::where('dpc_id', $user->dpc_id)->paginate(10);
    } elseif ($user->isAdminDpd()) {
        // Admin DPD: semua di bawah DPD nya
        $dpcIds = Dpc::where('dpd_id', $user->dpd_id)->pluck('dpc_id');
        $anggotas = Anggota::whereIn('dpc_id', $dpcIds)
                          ->orWhere('dpd_id', $user->dpd_id)
                          ->paginate(10);
    } else {
        abort(403);
    }
    
    return view('anggota.index', compact('anggotas'));
}
```

### Contoh: Check Permission Sebelum Action
```php
public function approveMutation(Mutasi $mutasi)
{
    if (!$this->canApproveMutations()) {
        abort(403, 'Tidak memiliki izin untuk menyetujui mutasi.');
    }
    
    // Check scope
    if (!$this->canAccessDpc($mutasi->struktur_ke)) {
        abort(403, 'Tidak dapat mengakses mutasi di DPC ini.');
    }
    
    $mutasi->update(['status' => 'disetujui']);
    
    return redirect()->back()->with('success', 'Mutasi berhasil disetujui.');
}
```

## 📊 Access Matrix

| Feature | Superadmin | Admin Sistem | Admin DPC | Admin DPD | Anggota |
|---------|-----------|--------------|-----------|-----------|---------|
| User Management | ✅ | ❌ | ❌ | ❌ | ❌ |
| Semua Data | ✅ | ✅ | ❌ | ❌ | ❌ |
| Data DPC | ✅ | ✅ | ✅ (sendiri) | ✅ (bawahnya) | ❌ |
| Data DPD | ✅ | ✅ | ❌ | ✅ (sendiri) | ❌ |
| Buat Mutasi | ✅ | ✅ | ✅ | ❌ | ❌ |
| Setujui Mutasi | ✅ | ✅ | ❌ | ✅ | ❌ |
| Buat Penempatan | ✅ | ✅ | ✅ | ❌ | ❌ |
| Setujui Penempatan | ✅ | ✅ | ❌ | ✅ | ❌ |
| Rekomposisi | ✅ | ✅ | ❌ | ✅ | ❌ |
| Mobile Access | ❌ | ❌ | ❌ | ❌ | ✅ |

## 🚀 Next Steps

1. Update semua controller untuk menggunakan scope filtering
2. Update views untuk hide/show menu berdasarkan role
3. Implement permission checking di setiap action
4. Update mobile routes untuk role anggota
5. Add unit tests untuk permission checking

