# Sistem Absensi — Laravel 11 Project Setup

Setup proyek Laravel 11 untuk sistem absensi karyawan dengan auth API (Sanctum), role-based access (Spatie Permission), migrasi database lengkap, seeder, model, dan AuthController.

## Environment

| Item | Version |
|------|---------|
| PHP | 8.2.12 |
| Composer | 2.8.6 |
| Laravel | 11.x (fresh install) |
| Workspace | `d:\Laragon\www\absensi` |

---

## Proposed Changes

### 1. Install Laravel 11

```bash
composer create-project laravel/laravel . --prefer-dist
```

Kemudian install package tambahan:

```bash
composer require laravel/sanctum
composer require spatie/laravel-permission
```

Publish config Sanctum & Spatie Permission:

```bash
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
```

---

### 2. Database Migrations

#### [NEW] `create_users_table` (modify default)
Menambahkan kolom: `employee_id`, `phone`, `photo`, `status` ke migration users bawaan Laravel.

#### [NEW] `create_sites_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| name | string |
| address | text |
| latitude | decimal(10,7) |
| longitude | decimal(10,7) |
| radius_meter | integer (default: 100) |
| timestamps | - |

#### [NEW] `create_user_sites_table` (pivot)
| Column | Type |
|--------|------|
| id | bigIncrements |
| user_id | foreignId → users |
| site_id | foreignId → sites |
| is_primary | boolean (default: false) |
| timestamps | - |

#### [NEW] `create_schedules_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| user_id | foreignId → users |
| site_id | foreignId → sites |
| date | date |
| shift_start | time |
| shift_end | time |
| created_by | foreignId → users (nullable) |
| timestamps | - |

#### [NEW] `create_attendances_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| user_id | foreignId → users |
| site_id | foreignId → sites |
| type | enum: clock_in, clock_out |
| photo_path | string (nullable) |
| latitude | decimal(10,7) |
| longitude | decimal(10,7) |
| distance_from_site | decimal(8,2) |
| status | string (default: valid) |
| timestamp | timestamp |
| notes | text (nullable) |
| timestamps | - |

#### [NEW] `create_leave_requests_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| user_id | foreignId → users |
| type | enum: annual, sick, emergency |
| start_date | date |
| end_date | date |
| reason | text |
| status | enum: pending, approved, rejected (default: pending) |
| timestamps | - |

#### [NEW] `create_leave_approvals_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| leave_request_id | foreignId → leave_requests |
| approver_id | foreignId → users |
| level | tinyInteger (1 or 2) |
| status | enum: pending, approved, rejected (default: pending) |
| notes | text (nullable) |
| approved_at | timestamp (nullable) |
| timestamps | - |

#### [NEW] `create_exit_permits_table`
| Column | Type |
|--------|------|
| id | bigIncrements |
| user_id | foreignId → users |
| site_id | foreignId → sites |
| reason | text |
| status | enum: pending, approved, rejected (default: pending) |
| approved_by | foreignId → users (nullable) |
| approved_at | timestamp (nullable) |
| exit_at | timestamp (nullable) |
| return_at | timestamp (nullable) |
| timestamps | - |

---

### 3. Seeder — Roles & Permissions

#### [NEW] `database/seeders/RolePermissionSeeder.php`

**Roles (11):**
`super_admin`, `hr`, `hq`, `head_dev_hq`, `cinema_manager`, `head_dev_ops`, `head_dev_tech`, `supervisor`, `cinema_technical_support`, `crew_leader`, `crew`

**Permissions (6):**
`manage_employees`, `manage_schedules`, `approve_leave`, `approve_exit_permit`, `view_operational_dashboard`, `view_attendance_dashboard`

**Permission mapping:**

| Role | Permissions |
|------|------------|
| super_admin | ALL |
| hr | manage_employees, manage_schedules, approve_leave, view_attendance_dashboard |
| hq | view_operational_dashboard, view_attendance_dashboard |
| head_dev_hq | manage_employees, manage_schedules, view_operational_dashboard, view_attendance_dashboard |
| cinema_manager | manage_schedules, approve_leave, approve_exit_permit, view_operational_dashboard |
| head_dev_ops | manage_schedules, approve_leave, view_operational_dashboard |
| head_dev_tech | manage_schedules, approve_leave, view_operational_dashboard |
| supervisor | manage_schedules, approve_leave, approve_exit_permit |
| cinema_technical_support | view_attendance_dashboard |
| crew_leader | approve_exit_permit, view_attendance_dashboard |
| crew | *none* |

> [!IMPORTANT]
> Apakah mapping permission → role di atas sudah sesuai kebutuhan bisnis? Saya bisa menyesuaikan jika ada perubahan.

---

### 4. Eloquent Models

#### [MODIFY] `app/Models/User.php`
- `HasApiTokens` (Sanctum)
- `HasRoles` (Spatie)
- `hasMany(Attendance, Schedule, LeaveRequest, ExitPermit)`
- `belongsToMany(Site)` via `user_sites` pivot
- `leaveApprovals()` — approvals yg di-approve user ini

#### [NEW] `app/Models/Site.php`
- `belongsToMany(User)` via `user_sites`
- `hasMany(Attendance, Schedule, ExitPermit)`

#### [NEW] `app/Models/Schedule.php`
- `belongsTo(User, Site)`
- `belongsTo(User, 'created_by')` as `creator`

#### [NEW] `app/Models/Attendance.php`
- `belongsTo(User, Site)`

#### [NEW] `app/Models/LeaveRequest.php`
- `belongsTo(User)`
- `hasMany(LeaveApproval)`

#### [NEW] `app/Models/LeaveApproval.php`
- `belongsTo(LeaveRequest)`
- `belongsTo(User, 'approver_id')` as `approver`

#### [NEW] `app/Models/ExitPermit.php`
- `belongsTo(User, Site)`
- `belongsTo(User, 'approved_by')` as `approvedBy`

---

### 5. AuthController

#### [NEW] `app/Http/Controllers/Api/AuthController.php`

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/login` | POST | Login dengan email/password, return Sanctum token + user data + roles |
| `/api/logout` | POST | Revoke current token (auth:sanctum middleware) |
| `/api/me` | GET | Return authenticated user profile + roles + permissions |

#### [MODIFY] `routes/api.php`
Tambahkan routing untuk auth endpoints.

---

## Open Questions

> [!IMPORTANT]
> 1. **Permission mapping**: Apakah distribusi permission ke role pada tabel di atas sudah sesuai? Ini bisa diubah kapan saja di seeder.
> 2. **Database**: Apakah Anda menggunakan MySQL (via Laragon)? Saya akan set `.env` sesuai config Laragon default.
> 3. **Login field**: Login menggunakan `email` atau bisa juga menggunakan `employee_id`?

---

## Verification Plan

### Automated Tests
```bash
php artisan migrate --seed     # pastikan semua migration & seeder berjalan
php artisan route:list         # pastikan semua route terdaftar
```

### Manual Verification
- Test login via `POST /api/login` 
- Test logout via `POST /api/logout`
- Test me via `GET /api/me`
- Verifikasi roles & permissions terseed dengan benar di database
