# Dokumentasi Flow Ticketing System

## Daftar Isi
1. [Overview](#overview)
2. [Aktor dan Role](#aktor-dan-role)
3. [Status Tiket](#status-tiket)
4. [Priority Level](#priority-level)
5. [SLA (Service Level Agreement)](#sla-service-level-agreement)
6. [Flow Utama](#flow-utama)
7. [Detail Alur Setiap Tahap](#detail-alur-setiap-tahap)
8. [Routes dan Endpoints](#routes-dan-endpoints)
9. [Database Schema](#database-schema)
10. [Notifikasi](#notifikasi)
11. [Permissions Matrix](#permissions-matrix)

---

## Overview

Sistem Ticketing ini memungkinkan user untuk mengajukan permintaan bantuan IT (atau tim support lainnya), melacak status permintaan, dan memfasilitasi komunikasi antara requester dan support team.

### Komponen Utama:
- **Ticket**: Permintaan bantuan yang diajukan user
- **Category & Subcategory**: Pengelompokan jenis tiket
- **Support Team**: Tim yang menangani tiket
- **SLA**: Aturan waktu respons dan penyelesaian
- **Comments**: Diskusi terkait tiket
- **Attachments**: File pendukung
- **History**: Riwayat perubahan tiket

---

## Aktor dan Role

### 1. Requester (User Biasa)
- Membuat tiket baru
- Melihat tiket yang dibuat sendiri
- Menambahkan komentar public
- Upload attachment saat membuat tiket
- Menutup tiket yang sudah resolved
- Membuka kembali (reopen) tiket yang sudah closed/resolved
- Membatalkan tiket (hanya saat status `submitted`)

### 2. Agent (Anggota Support Team)
- Melihat semua tiket di tim-nya
- Meng-assign tiket ke diri sendiri atau agent lain
- Mengubah status tiket
- Mengubah priority tiket
- Menambahkan komentar (public/internal)
- Upload attachment
- Mengisi "How to Solve"

### 3. Supervisor (Ketua Tim Support)
- Semua hak Agent
- Reassign tiket yang sudah di-assign ke orang lain
- Membatalkan tiket
- Monitoring performa tim

---

## Status Tiket

### Daftar Status

| Status | Label | Deskripsi |
|--------|-------|-----------|
| `submitted` | Submitted | Tiket baru diajukan, belum di-assign |
| `assigned` | Assigned | Tiket sudah di-assign ke agent |
| `in_progress` | In Progress | Agent sedang mengerjakan tiket |
| `waiting_user` | Waiting for User | Menunggu respons/informasi dari requester |
| `waiting_vendor` | Waiting for Vendor | Menunggu vendor pihak ketiga |
| `resolved` | Resolved | Tiket sudah diselesaikan |
| `closed` | Closed | Tiket ditutup secara final |
| `reopened` | Reopened | Tiket dibuka kembali setelah resolved/closed |
| `cancelled` | Cancelled | Tiket dibatalkan |

### Diagram Transisi Status

```
                    ┌─────────────┐
                    │  SUBMITTED  │
                    └──────┬──────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            │            ▼
        ┌─────────┐        │      ┌───────────┐
        │CANCELLED│◄───────┼──────│  ASSIGNED │
        └─────────┘        │      └─────┬─────┘
              ▲            │            │
              │            │      ┌─────┴─────┐
              │            │      │           │
              │            │      ▼           ▼
              │            │ ┌────────────┐   │
              │            │ │IN_PROGRESS │◄──┘
              │            │ └─────┬──────┘
              │            │       │
              │      ┌─────┴─────┬─┴───────────────┐
              │      │           │                 │
              │      ▼           ▼                 │
              │ ┌────────────┐ ┌────────────────┐  │
              ├─│WAITING_USER│ │WAITING_VENDOR │──┤
              │ └─────┬──────┘ └───────┬────────┘  │
              │       │                │           │
              │       └───────┬────────┘           │
              │               │                    │
              │               ▼                    │
              │         ┌──────────┐               │
              └─────────│ RESOLVED │◄──────────────┘
                        └────┬─────┘
                             │
                    ┌────────┴────────┐
                    │                 │
                    ▼                 ▼
              ┌──────────┐      ┌──────────┐
              │  CLOSED  │      │ REOPENED │
              └─────┬────┘      └────┬─────┘
                    │                │
                    └────────┬───────┘
                             │
                             ▼
                       ┌──────────┐
                       │ ASSIGNED │ (loop back)
                       └──────────┘
```

### Transisi Status yang Diizinkan

| Dari Status | Ke Status yang Diizinkan |
|-------------|--------------------------|
| `submitted` | `assigned`, `cancelled` |
| `assigned` | `in_progress`, `waiting_user`, `waiting_vendor`, `resolved`, `cancelled` |
| `in_progress` | `waiting_user`, `waiting_vendor`, `resolved`, `cancelled` |
| `waiting_user` | `in_progress`, `resolved`, `cancelled` |
| `waiting_vendor` | `in_progress`, `resolved`, `cancelled` |
| `resolved` | `closed`, `reopened` |
| `closed` | `reopened` |
| `reopened` | `assigned`, `in_progress`, `cancelled` |
| `cancelled` | - (tidak bisa transisi) |

### Status Khusus

**Paused Status (SLA Timer Berhenti):**
- `waiting_user`
- `waiting_vendor`

**Open Status:**
- `submitted`, `assigned`, `in_progress`, `waiting_user`, `waiting_vendor`, `reopened`

**Completed Status:**
- `resolved`, `closed`, `cancelled`

---

## Priority Level

| Priority | Label | Deskripsi |
|----------|-------|-----------|
| `low` | Low | Tidak mendesak, bisa dikerjakan saat ada waktu |
| `medium` | Medium | Normal, dikerjakan sesuai urutan |
| `high` | High | Penting, perlu segera ditangani |
| `critical` | Critical | Sangat mendesak, dampak besar ke operasional |

Priority ditentukan otomatis dari subcategory yang dipilih (default priority), namun agent dapat mengubahnya.

---

## SLA (Service Level Agreement)

### Parameter SLA

| Parameter | Deskripsi |
|-----------|-----------|
| `first_response_minutes` | Waktu maksimal untuk respons pertama (dalam menit) |
| `resolve_minutes` | Waktu maksimal untuk menyelesaikan tiket (dalam menit) |
| `pause_on_waiting` | Apakah timer SLA berhenti saat status waiting |

### SLA Timer

1. **Mulai**: Saat tiket dibuat
2. **Pause**: Saat status berubah ke `waiting_user` atau `waiting_vendor`
3. **Resume**: Saat status keluar dari waiting
4. **Stop**: Saat tiket `resolved` atau `closed`

### Field SLA pada Tiket

| Field | Deskripsi |
|-------|-----------|
| `sla_id` | ID SLA yang digunakan |
| `first_response_due_at` | Deadline respons pertama |
| `resolve_due_at` | Deadline penyelesaian |
| `first_responded_at` | Waktu respons pertama (actual) |
| `resolved_at` | Waktu diselesaikan (actual) |
| `sla_paused_at` | Waktu SLA di-pause |
| `sla_pause_total_minutes` | Total waktu pause (menit) |
| `sla_first_breached` | Flag: respons pertama melewati deadline |
| `sla_resolve_breached` | Flag: penyelesaian melewati deadline |

---

## Flow Utama

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                              TICKETING FLOW                                  │
└─────────────────────────────────────────────────────────────────────────────┘

         REQUESTER                    SYSTEM                    SUPPORT TEAM
             │                           │                           │
             │  1. Buat Tiket            │                           │
             │  (pilih category,         │                           │
             │   subcategory, isi        │                           │
             │   detail, upload file)    │                           │
             │──────────────────────────►│                           │
             │                           │                           │
             │                           │  2. Generate Ticket No    │
             │                           │  3. Assign Support Team   │
             │                           │     (dari subcategory)    │
             │                           │  4. Calculate SLA         │
             │                           │  5. Set Status: SUBMITTED │
             │                           │  6. Send Notification     │
             │                           │──────────────────────────►│
             │                           │                           │
             │                           │                           │  7. View Tiket
             │                           │                           │  8. Assign ke diri
             │                           │◄──────────────────────────│     sendiri/agent
             │                           │                           │
             │                           │  9. Update Status:        │
             │                           │     ASSIGNED              │
             │                           │  10. Record First Response│
             │◄──────────────────────────│                           │
             │  Notifikasi tiket         │                           │
             │  di-assign                │                           │
             │                           │                           │
             │                           │                           │  11. Mulai kerjakan
             │                           │                           │      Status: IN_PROGRESS
             │                           │                           │
             │                           │◄─── Komunikasi via ───────│
             │◄──────────────────────────│     Comments              │
             │                           │                           │
             │  Reply comment            │                           │
             │──────────────────────────►│──────────────────────────►│
             │                           │                           │
             │                           │                           │  12. Jika butuh info:
             │                           │◄──────────────────────────│      Status: WAITING_USER
             │                           │      (SLA Timer Pause)    │
             │◄──────────────────────────│                           │
             │                           │                           │
             │  Beri informasi           │                           │
             │──────────────────────────►│──────────────────────────►│
             │                           │                           │
             │                           │                           │  13. Lanjut kerjakan
             │                           │      (SLA Timer Resume)   │      Status: IN_PROGRESS
             │                           │                           │
             │                           │                           │  14. Selesai:
             │                           │                           │      - Isi How to Solve
             │                           │                           │      - Status: RESOLVED
             │                           │◄──────────────────────────│
             │◄──────────────────────────│                           │
             │  Notifikasi resolved      │                           │
             │                           │                           │
             │  15. Review solusi        │                           │
             │  16. Tutup tiket          │                           │
             │      Status: CLOSED       │                           │
             │──────────────────────────►│──────────────────────────►│
             │                           │                           │
             │         ══════ SELESAI ══════                         │
             │                           │                           │
             │  ATAU jika tidak puas:    │                           │
             │  17. Reopen tiket         │                           │
             │      Status: REOPENED     │                           │
             │──────────────────────────►│──────────────────────────►│
             │                           │                           │
             │         (Kembali ke langkah 7)                        │
```

---

## Detail Alur Setiap Tahap

### 1. Pembuatan Tiket (Create Ticket)

**URL:** `/tickets/create`  
**Method:** GET (form) → POST (submit)

**Input yang diperlukan:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `subject` | Ya | Judul tiket |
| `description` | Ya | Deskripsi masalah |
| `id_ticket_category` | Ya | Kategori tiket |
| `id_ticket_subcategory` | Tidak | Subkategori tiket |
| `priority` | Ya | Prioritas tiket |
| `attachments[]` | Tidak | File lampiran (max 10MB per file) |

**Proses di Backend:**
```php
1. Validasi input
2. Ambil subcategory → dapat support_team_id dan default_sla_id
3. Jika tidak ada subcategory:
   - support_team_id = team pertama yang aktif
   - sla_id = SLA pertama yang aktif
4. Generate ticket_no: TIC/{running_number}/{MM}.{YY}
5. Create ticket dengan status: SUBMITTED
6. Hitung SLA deadline berdasarkan SLA config
7. Log history: CREATED
8. Simpan attachments
9. Kirim notifikasi ke semua anggota support team
```

**Output:**
- Redirect ke halaman detail tiket
- Notifikasi sukses dengan nomor tiket

---

### 2. Support Team Menerima Tiket

**URL:** `/tickets/team`  
**Method:** GET

**Akses:** Hanya anggota support team yang aktif

**Filter yang tersedia:**
- Status
- Priority
- Search (nomor tiket / judul)
- Date range

---

### 3. Assignment Tiket

**URL:** `/tickets/{id}/assign`  
**Method:** POST

**Input:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `id_employee_assignee` | Ya | ID employee yang akan di-assign |
| `reason` | Tidak | Alasan assignment/reassignment |

**Rules:**
- Anggota tim dapat assign tiket ke diri sendiri atau agent lain
- Hanya supervisor yang dapat reassign tiket yang sudah punya assignee
- Assignee harus anggota aktif dari support team tiket tersebut

**Proses:**
```php
1. Validasi assignee adalah anggota tim
2. Jika reassignment, validasi user adalah supervisor
3. Update status menjadi ASSIGNED (jika sebelumnya SUBMITTED)
4. Record first response time
5. Log history: ASSIGNED
6. Kirim notifikasi ke assignee dan requester
```

---

### 4. Perubahan Status

**URL:** `/tickets/{id}/status`  
**Method:** POST

**Input:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `status` | Ya | Status baru |
| `reason` | Tidak | Alasan perubahan |
| `message` | Tidak | Pesan tambahan (akan jadi comment) |

**Rules Permission:**
| User Role | Status yang Bisa Diubah |
|-----------|-------------------------|
| Assignee/Team Member | Semua transisi valid |
| Requester | Hanya `closed`, `reopened` |
| Supervisor | Semua termasuk `cancelled` |
| Requester (saat SUBMITTED) | Bisa `cancelled` |

**Proses:**
```php
1. Validasi transisi status valid
2. Handle SLA timer:
   - Jika masuk waiting → pause timer
   - Jika keluar waiting → resume timer
3. Jika RESOLVED:
   - Set resolved_at
   - Set solved_by, solved_at jika belum ada
4. Jika CLOSED:
   - Set closed_at
5. Log history: STATUS_CHANGED
6. Jika ada message → tambahkan sebagai comment
7. Kirim notifikasi
```

---

### 5. Komentar (Discussion)

**URL:** `/tickets/{id}/comment`  
**Method:** POST

**Input:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `comment` | Ya | Isi komentar |
| `visibility` | Ya | `public` atau `internal` |

**Visibility Rules:**
| Visibility | Siapa yang Bisa Lihat |
|------------|----------------------|
| `public` | Requester & Support Team |
| `internal` | Hanya Support Team |

**Note:** Requester hanya bisa menambah komentar `public` (dipaksa oleh sistem)

**Proses:**
```php
1. Validasi permission untuk comment
2. Jika requester, paksa visibility = public
3. Create comment
4. Jika support member dan first_responded_at kosong → record first response
5. Log history: COMMENT_ADDED
6. Kirim notifikasi:
   - Internal comment → ke team members
   - Public dari support → ke requester
   - Public dari requester → ke assignee/team
```

---

### 6. How to Solve (Dokumentasi Solusi)

**URL:** `/tickets/{id}/how-to-solve`  
**Method:** POST

**Input:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `root_cause` | Tidak | Penyebab masalah |
| `action_taken` | Tidak | Tindakan yang dilakukan |
| `solution_summary` | Tidak | Ringkasan solusi |

**Permission:** Hanya assignee atau supervisor

**Visibilitas untuk Requester:** Hanya saat tiket sudah RESOLVED atau CLOSED

**URL Solution Attachments:** `/tickets/{id}/solution-attachments`  
**Method:** POST

**Input:**
| Field | Required | Deskripsi |
|-------|----------|-----------|
| `attachments[]` | Ya | File lampiran solusi (max 5MB per file) |

---

### 7. Menutup Tiket (Close)

Requester dapat menutup tiket:
- Saat status sudah `resolved`
- Status berubah menjadi `closed`
- Field `closed_at` diset

---

### 8. Membuka Kembali Tiket (Reopen)

Requester dapat reopen tiket:
- Saat status `resolved` atau `closed`
- Status berubah menjadi `reopened`
- Tiket kembali ke cycle awal (assignment dst)

---

## Routes dan Endpoints

### User Ticketing Routes

| Method | URL | Controller Method | Deskripsi |
|--------|-----|-------------------|-----------|
| GET | `/tickets` | `index` | Daftar tiket milik user |
| GET | `/tickets/create` | `create` | Form buat tiket |
| POST | `/tickets` | `store` | Submit tiket baru |
| GET | `/tickets/assigned` | `assigned` | Tiket yang di-assign ke user |
| GET | `/tickets/team` | `team` | Semua tiket tim (supervisor/agent) |
| GET | `/tickets/{id}` | `show` | Detail tiket |
| POST | `/tickets/{id}/comment` | `addComment` | Tambah komentar |
| POST | `/tickets/{id}/assign` | `assign` | Assign tiket |
| POST | `/tickets/{id}/status` | `changeStatus` | Ubah status |
| POST | `/tickets/{id}/how-to-solve` | `saveHowToSolve` | Simpan solusi |
| POST | `/tickets/{id}/solution-attachments` | `uploadSolutionAttachments` | Upload file solusi |
| DELETE | `/tickets/{id}/solution-attachment/{attachmentId}` | `deleteSolutionAttachment` | Hapus file solusi |

---

## Database Schema

### Tabel Utama

#### `t_tickets`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `ticket_no` | varchar | Nomor tiket (TIC/1/02.26) |
| `title` | varchar | Judul tiket |
| `description` | text | Deskripsi masalah |
| `category_id` | bigint | FK ke ref_ticket_categories |
| `subcategory_id` | bigint | FK ke ref_ticket_subcategories |
| `support_team_id` | bigint | FK ke ref_support_teams |
| `id_employee_requester` | bigint | FK ke m_employees (pembuat) |
| `id_branch` | bigint | FK ke branch |
| `location_detail` | varchar | Detail lokasi |
| `priority` | enum | low/medium/high/critical |
| `status` | enum | Status tiket |
| `id_employee_assignee` | bigint | FK ke m_employees (assignee) |
| `sla_id` | bigint | FK ke ref_ticket_slas |
| `first_response_due_at` | datetime | Deadline respons pertama |
| `resolve_due_at` | datetime | Deadline penyelesaian |
| `first_responded_at` | datetime | Waktu respons pertama |
| `resolved_at` | datetime | Waktu resolved |
| `closed_at` | datetime | Waktu closed |
| `sla_first_breached` | boolean | SLA response breach flag |
| `sla_resolve_breached` | boolean | SLA resolve breach flag |
| `sla_paused_at` | datetime | Waktu SLA di-pause |
| `sla_pause_total_minutes` | int | Total waktu pause |
| `root_cause` | text | Penyebab (How to Solve) |
| `action_taken` | text | Tindakan (How to Solve) |
| `solution_summary` | text | Ringkasan (How to Solve) |
| `solved_by` | bigint | FK ke m_employees |
| `solved_at` | datetime | Waktu diselesaikan |

### Tabel Referensi

#### `ref_ticket_categories`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `name` | varchar | Nama kategori |
| `is_active` | boolean | Status aktif |

#### `ref_ticket_subcategories`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `category_id` | bigint | FK ke categories |
| `name` | varchar | Nama subkategori |
| `default_priority` | enum | Priority default |
| `default_sla_id` | bigint | FK ke SLA |
| `support_team_id` | bigint | FK ke support teams |
| `is_active` | boolean | Status aktif |

#### `ref_support_teams`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `name` | varchar | Nama tim |
| `description` | text | Deskripsi |
| `is_active` | boolean | Status aktif |

#### `ref_support_team_members`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `team_id` | bigint | FK ke support teams |
| `id_employee` | bigint | FK ke m_employees |
| `role` | enum | supervisor/agent |
| `is_active` | boolean | Status aktif |

#### `ref_ticket_slas`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `name` | varchar | Nama SLA |
| `first_response_minutes` | int | Target respons (menit) |
| `resolve_minutes` | int | Target selesai (menit) |
| `pause_on_waiting` | boolean | Pause saat waiting |
| `is_active` | boolean | Status aktif |

### Tabel Transaksi

#### `t_ticket_comments`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `ticket_id` | bigint | FK ke t_tickets |
| `id_employee` | bigint | FK ke m_employees |
| `visibility` | enum | public/internal |
| `comment` | text | Isi komentar |

#### `t_ticket_attachments`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `ticket_id` | bigint | FK ke t_tickets |
| `uploaded_by_employee` | bigint | FK ke m_employees |
| `real_name` | varchar | Nama file asli |
| `stored_name` | varchar | Nama file tersimpan |
| `file_path` | varchar | Path file |
| `mime_type` | varchar | MIME type |
| `size` | bigint | Ukuran file (bytes) |
| `attachment_type` | enum | ticket/solution |

#### `t_ticket_history`
| Column | Type | Deskripsi |
|--------|------|-----------|
| `id` | bigint | Primary key |
| `ticket_id` | bigint | FK ke t_tickets |
| `event_type` | enum | Tipe event |
| `from_value` | varchar | Nilai sebelum |
| `to_value` | varchar | Nilai sesudah |
| `actor_employee_id` | bigint | FK ke m_employees |
| `content` | text | Deskripsi event |
| `meta` | json | Data tambahan |

---

## Notifikasi

### Jenis Notifikasi

| Event | Penerima | Deskripsi |
|-------|----------|-----------|
| Tiket Dibuat | Semua anggota tim | Tiket baru masuk ke tim |
| Tiket Di-assign | Assignee + Requester | Tiket sudah ditangani |
| Status Berubah | Requester + Assignee | Progress tiket |
| Komentar Public dari Support | Requester | Ada balasan dari IT |
| Komentar Public dari Requester | Assignee / Tim (jika unassigned) | Ada balasan dari user |
| Komentar Internal | Anggota tim (kecuali pembuat) | Diskusi internal |
| How to Solve Updated | Requester (jika resolved/closed) | Dokumentasi solusi tersedia |

---

## Permissions Matrix

### Aksi vs Role

| Aksi | Requester | Agent | Supervisor |
|------|-----------|-------|------------|
| Buat tiket | ✅ | ✅ | ✅ |
| Lihat tiket sendiri | ✅ | ✅ | ✅ |
| Lihat tiket tim | ❌ | ✅ | ✅ |
| Assign tiket | ❌ | ✅ | ✅ |
| Reassign tiket | ❌ | ❌ | ✅ |
| Ubah status | ❌* | ✅ | ✅ |
| Ubah priority | ❌ | ✅ | ✅ |
| Comment public | ✅ | ✅ | ✅ |
| Comment internal | ❌ | ✅ | ✅ |
| Close tiket | ✅** | ✅ | ✅ |
| Reopen tiket | ✅** | ✅ | ✅ |
| Cancel tiket | ✅*** | ❌ | ✅ |
| Update How to Solve | ❌ | ✅**** | ✅ |
| View How to Solve | ✅***** | ✅ | ✅ |

**Keterangan:**
- \* Requester hanya bisa close/reopen
- \** Hanya pada tiket resolved/closed
- \*** Hanya pada status submitted
- \**** Hanya assignee tiket tersebut
- \***** Hanya saat tiket resolved/closed

---

## Routing Tiket ke Support Team

Tiket di-routing ke support team berdasarkan **subcategory** yang dipilih saat membuat tiket:

```
User pilih Category → Subcategory → support_team_id diambil dari subcategory
```

**Konfigurasi routing** dilakukan di admin panel dengan mengatur `support_team_id` pada setiap subcategory di tabel `ref_ticket_subcategories`.

Contoh:
| Subcategory | Support Team |
|-------------|--------------|
| Password Reset | IT Teams |
| Network Issue | IT Teams |
| HR Request | HR Teams |
| Payroll Issue | Finance Teams |

---

## File Terkait

| File | Deskripsi |
|------|-----------|
| `app/Http/Controllers/User/TicketController.php` | Controller utama ticketing |
| `app/Services/Ticketing/TicketService.php` | Business logic ticketing |
| `app/Services/Ticketing/SlaService.php` | Logic SLA timer |
| `app/Models/Ticketing/Ticket.php` | Model tiket |
| `app/Models/Ticketing/TicketComment.php` | Model komentar |
| `app/Models/Ticketing/TicketHistory.php` | Model history |
| `app/Models/Ticketing/TicketAttachment.php` | Model attachment |
| `app/Models/Ticketing/SupportTeam.php` | Model support team |
| `app/Models/Ticketing/SupportTeamMember.php` | Model anggota tim |
| `app/Enums/TicketStatus.php` | Enum status tiket |
| `app/Enums/TicketPriority.php` | Enum priority |
| `app/Notifications/TicketNotification.php` | Notifikasi tiket |
| `resources/js/Pages/User/Ticket/` | Vue components |

---

*Dokumentasi ini dibuat berdasarkan kode yang ada di repository. Update sesuai perubahan fitur.*
