# DOJ Rank System Documentation

## Overview
Sistem rank di DOJ mendukung **multiple ranks** untuk setiap user. Seorang user bisa memiliki lebih dari satu rank sekaligus.

## Rank Hierarchy (Highest to Lowest)

1. **admin** - Full system access, dapat mengelola website
2. **moderator** - Moderasi konten dan user management  
3. **Attorney General** - Kepala Departemen Kehakiman
4. **Chief Justice** - Kepala Pengadilan
5. **Head Office** - Kepala Kantor
6. **District Judge** - Hakim Distrik
7. **Magistrate Judge** - Hakim Magistrat
8. **Administrative Judge** - Hakim Administratif
9. **State Attorney III** - State Attorney (Senior)
10. **State Attorney II** - State Attorney (Menengah)
11. **State Attorney I** - State Attorney (Junior)
12. **Paralegals** - Asisten Legal
13. **Office** - Petugas Administrasi
14. **USMS** - U.S. Marshals Service

## Database Structure

### Column: `ranks`
- **Type:** JSON
- **Nullable:** Yes
- **Storage:** Array of rank strings
- **Example:** `["admin", "Chief Of Justice"]`

## User Model Methods

### `hasRank(string $rank): bool`
Check apakah user memiliki rank tertentu:
```php
if (Auth::user()->hasRank('admin')) {
    // User is admin
}
```

### `hasAnyRank(array $ranks): bool`
Check apakah user memiliki salah satu dari ranks yang disebutkan:
```php
if (Auth::user()->hasAnyRank(['admin', 'moderator'])) {
    // User is either admin or moderator
}
```

### `getHighestRank(): ?string`
Mendapatkan rank tertinggi user berdasarkan hierarchy:
```php
$highestRank = Auth::user()->getHighestRank();
// Returns: "admin" if user has ["admin", "Clerks"]
```

### `getRanksString(): string`
Mendapatkan semua ranks sebagai string:
```php
$ranksDisplay = Auth::user()->getRanksString();
// Returns: "admin, Chief Of Justice"
```

## Usage Examples

### Assign Single Rank
```php
$user = User::find(1);
$user->ranks = ['Clerks'];
$user->save();
```

### Assign Multiple Ranks
```php
$user = User::find(1);
$user->ranks = ['admin', 'Attorney General'];
$user->save();
```

### Via SQL
```sql
-- Single rank
UPDATE users_doj SET ranks = JSON_ARRAY('Clerks') WHERE id = 1;

-- Multiple ranks
UPDATE users_doj SET ranks = JSON_ARRAY('admin', 'Chief Of Justice') WHERE id = 1;
```

### Check Rank in Controller
```php
public function someMethod()
{
    if (!Auth::user()->hasRank('admin')) {
        abort(403, 'Admin access required');
    }
    
    // Admin only code here
}
```

### Blade Template
```blade
@if(Auth::user()->hasRank('admin'))
    <button>Admin Panel</button>
@endif

@if(Auth::user()->hasAnyRank(['admin', 'moderator']))
    <button>Manage Users</button>
@endif
```

## Middleware Example

Create middleware for rank-based access:

```php
// app/Http/Middleware/CheckRank.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckRank
{
    public function handle(Request $request, Closure $next, ...$ranks)
    {
        if (!auth()->check()) {
            return redirect()->route('login');
        }

        if (!auth()->user()->hasAnyRank($ranks)) {
            abort(403, 'Insufficient rank privileges');
        }

        return $next($request);
    }
}
```

Register in `app/Http/Kernel.php`:
```php
protected $middlewareAliases = [
    // ...
    'rank' => \App\Http\Middleware\CheckRank::class,
];
```

Usage in routes:
```php
Route::get('/admin', function () {
    // Only admin
})->middleware('rank:admin');

Route::get('/manage', function () {
    // Admin or moderator
})->middleware('rank:admin,moderator');
```

## Display Examples

### Dashboard Display
```blade
<div class="info-row">
    <span class="info-label">Rank(s):</span>
    <span class="info-value">
        @if(Auth::user()->ranks && count(Auth::user()->ranks) > 0)
            @foreach(Auth::user()->ranks as $rank)
                <span class="rank-badge">{{ $rank }}</span>
            @endforeach
        @else
            <span>No Rank Assigned</span>
        @endif
    </span>
</div>
```

### Highest Rank Display
```blade
<div class="user-card">
    <h3>{{ Auth::user()->name }}</h3>
    <p class="rank">{{ Auth::user()->getHighestRank() ?? 'No Rank' }}</p>
</div>
```

## Current Users & Ranks

| Username | Name | Ranks |
|----------|------|-------|
| creature.sjefh | Creature Sjefh | admin, Attorney General |
| pollyana.kalux | Pollyana G. Kalux | admin, Chief Justice |
| hanara.zhaovelle | Hanara E. Zhaovelle | moderator, Head Office |
| nash.brandford | Nash Brandford | State Attorney III |
| kresna.mcgill | Kresna McGill | State Attorney II |
| jun.yun | Jun Yun | State Attorney I |
| ariell.ethelbert | Ariell Ethelbert | District Judge |
| shin.langor | Shin Langor | Magistrate Judge |
| kaito.kazuto | Kaito Kazuto | Administrative Judge |
| rhenald | Rhenald | admin, USMS |

## Best Practices

1. **Always use helper methods** - Jangan langsung akses `$user->ranks` array
2. **Validate ranks** - Pastikan rank ada dalam `User::RANKS` sebelum assign
3. **Use middleware** - Untuk route protection berdasarkan rank
4. **Consistent naming** - Gunakan nama rank persis seperti di `User::RANKS`
5. **Multiple ranks** - Gunakan untuk user yang memiliki dual roles

## Migration

Migration file: `2026_01_14_124539_add_ranks_to_users_doj_table.php`

```php
Schema::table('users_doj', function (Blueprint $table) {
    $table->json('ranks')->nullable()->after('status');
});
```

## Future Enhancements

- [ ] Rank-based permissions system
- [ ] Rank history tracking
- [ ] Rank expiration dates
- [ ] Automatic rank assignment based on criteria
- [ ] Rank badges/icons
- [ ] Rank-based dashboard widgets

---

**Created:** 2026-01-14  
**Last Updated:** 2026-01-14
