# DOJ Criminal Cases API

Dokumentasi penggunaan API Criminal Cases pada aplikasi DOJ.

## Base URL

| Environment | URL |
|-------------|-----|
| Local | `http://localhost:8001/api` |
| Production | `https://doj.satumimpirp.id/api` |

## Authentication

Semua endpoint memerlukan API Key. Kirim melalui salah satu cara berikut:

```
Header: X-API-Key: <your-api-key>
Query:  ?api_key=<your-api-key>
```

Prioritas: header `X-API-Key` digunakan terlebih dahulu jika keduanya disertakan.

**Response jika unauthorized (401):**

```json
{
  "success": false,
  "message": "Unauthorized. API key tidak valid atau tidak disertakan."
}
```

---

## Endpoints

### 1. Create Criminal Case

```
POST /api/criminal-cases
```

Membuat record criminal case baru. `application_no` di-generate otomatis.

#### Request Body

| Field | Type | Required | Validasi |
|-------|------|----------|----------|
| `cid_no` | string | ✅ | Max 100 karakter |
| `accused_name` | string | ✅ | Max 255 karakter |
| `accused_plea` | string | ✅ | Max 100 karakter |
| `bail_amount` | numeric | ❌ | Min 0, nullable |
| `bail_status` | string | ✅ | `paid` \| `not paid` \| `refund` |
| `decision` | string | ❌ | Max 1000 karakter |
| `status` | string | ✅ | Lihat [Status Values](#status-values) |
| `judge_name` | string | ❌ | Max 255 karakter |
| `prosecutor_name` | string | ❌ | Max 255 karakter |
| `public_defender_name` | string | ❌ | Max 255 karakter |
| `date_of_hearing` | string | ❌ | Format: `YYYY-MM-DD` |
| `usms_input` | string | ❌ | Penanda input dari USMS |

#### Contoh Request

```bash
curl -X POST http://localhost:8001/api/criminal-cases \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -d '{
    "cid_no": "2071",
    "accused_name": "Jay Jamal",
    "accused_plea": "not guilty",
    "bail_amount": 5000,
    "bail_status": "paid",
    "decision": "5.9 Narcotics Dealing",
    "status": "active",
    "judge_name": "",
    "prosecutor_name": "",
    "usms_input": "prison-record-123"
  }'
```

#### Response 201 (Success)

```json
{
  "success": true,
  "message": "Criminal case berhasil dibuat.",
  "data": {
    "id": 146,
    "application_no": "CT-CR-2026-0080",
    "cid_no": "2071",
    "accused_name": "Jay Jamal",
    "accused_plea": "not guilty",
    "bail_amount": "5000.00",
    "bail_status": "paid",
    "decision": "5.9 Narcotics Dealing",
    "status": "active",
    "judge_name": "",
    "prosecutor_name": "",
    "public_defender_name": null,
    "date_of_hearing": null,
    "usms_input": "prison-record-123",
    "user_id": null,
    "created_at": "2026-05-28T10:00:00.000000Z",
    "updated_at": "2026-05-28T10:00:00.000000Z"
  }
}
```

#### Response 422 (Validation Error)

```json
{
  "success": false,
  "message": "Validasi gagal.",
  "errors": {
    "cid_no": ["The cid no field is required."],
    "status": ["The selected status is invalid."]
  }
}
```

---

### 2. List Criminal Cases

```
GET /api/criminal-cases
```

Mengambil daftar criminal cases. Hasil diurutkan berdasarkan `created_at` descending (terbaru di atas).

#### Query Parameters (Optional)

| Parameter | Behavior | Contoh |
|-----------|----------|--------|
| `cid_no` | Partial match, case-insensitive | `?cid_no=2071` |
| `accused_name` | Partial match, case-insensitive | `?accused_name=jay` |
| `status` | Exact match (invalid value diabaikan) | `?status=active` |

#### Contoh Request

```bash
# Semua data
curl http://localhost:8001/api/criminal-cases \
  -H "X-API-Key: your-api-key"

# Filter by CID
curl "http://localhost:8001/api/criminal-cases?cid_no=2071" \
  -H "X-API-Key: your-api-key"

# Filter by status
curl "http://localhost:8001/api/criminal-cases?status=arraignment" \
  -H "X-API-Key: your-api-key"

# Kombinasi filter
curl "http://localhost:8001/api/criminal-cases?accused_name=jay&status=active" \
  -H "X-API-Key: your-api-key"
```

#### Response 200

```json
{
  "success": true,
  "message": "Ditemukan 78 data.",
  "data": [
    {
      "id": 145,
      "application_no": "CT-CR-2026-0079",
      "cid_no": "2071",
      "accused_name": "Jay Jamal",
      "judge_name": "Peach Elstone",
      "prosecutor_name": "Nathan Xand",
      "public_defender_name": "Creature Sjefh",
      "date_of_hearing": "2026-05-26T17:00:00.000000Z",
      "accused_plea": "guilty",
      "bail_amount": null,
      "bail_status": "not paid",
      "decision": "5.9 Narcotics Dealing...",
      "status": "arraignment",
      "usms_input": null,
      "user_id": 79,
      "created_at": "2026-05-27T07:54:01.000000Z",
      "updated_at": "2026-05-27T07:55:35.000000Z"
    }
  ]
}
```

#### Response 200 (Empty)

```json
{
  "success": true,
  "message": "Ditemukan 0 data.",
  "data": []
}
```

---

### 3. Show Single Criminal Case

```
GET /api/criminal-cases/{id}
```

Mengambil detail satu criminal case. Parameter `{id}` bisa berupa:
- **Numeric ID** (primary key) — contoh: `/api/criminal-cases/145`
- **CID Number** — contoh: `/api/criminal-cases/2071`

Lookup priority: numeric ID dulu, fallback ke cid_no.

#### Contoh Request

```bash
# By numeric ID
curl http://localhost:8001/api/criminal-cases/145 \
  -H "X-API-Key: your-api-key"

# By CID number
curl http://localhost:8001/api/criminal-cases/2071 \
  -H "X-API-Key: your-api-key"
```

#### Response 200 (Found)

```json
{
  "success": true,
  "message": "success",
  "data": {
    "id": 145,
    "application_no": "CT-CR-2026-0079",
    "cid_no": "2071",
    "accused_name": "Jay Jamal",
    "judge_name": "Peach Elstone",
    "prosecutor_name": "Nathan Xand",
    "public_defender_name": "Creature Sjefh",
    "date_of_hearing": "2026-05-26T17:00:00.000000Z",
    "accused_plea": "guilty",
    "bail_amount": null,
    "bail_status": "not paid",
    "decision": "5.9 Narcotics Dealing...",
    "status": "arraignment",
    "usms_input": null,
    "user_id": 79,
    "created_at": "2026-05-27T07:54:01.000000Z",
    "updated_at": "2026-05-27T07:55:35.000000Z"
  }
}
```

#### Response 404 (Not Found)

```json
{
  "success": false,
  "message": "Data tidak ditemukan.",
  "data": null
}
```

---

### 4. Update Criminal Case

```
POST /api/criminal-cases/{id}/update
```

Memperbarui data criminal case yang sudah ada. Sama seperti `GET /{id}`, parameter `{id}` bisa berupa **Numeric ID** atau **CID Number**.

#### Request Body (Partial Update)
Semua field bersifat opsional (`sometimes`). Hanya kirim field yang ingin diubah.

| Field | Type | Validasi |
|-------|------|----------|
| `cid_no` | string | Max 100 karakter |
| `accused_name` | string | Max 255 karakter |
| `accused_plea` | string | Max 100 karakter |
| `bail_amount` | numeric | Min 0, nullable |
| `bail_status` | string | `paid` \| `not paid` \| `refund` |
| `decision` | string | Max 1000 karakter |
| `status` | string | Lihat [Status Values](#status-values) |
| `judge_name` | string | Max 255 karakter |
| `prosecutor_name` | string | Max 255 karakter |
| `public_defender_name` | string | Max 255 karakter |
| `date_of_hearing` | string | Format: `YYYY-MM-DD` |

#### Contoh Request

```bash
curl -X POST http://localhost:8001/api/criminal-cases/2071/update \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -d '{
    "status": "closed",
    "decision": "10 Years Imprisonment",
    "bail_status": "refund"
  }'
```

#### Response 200 (Success)

```json
{
  "success": true,
  "message": "Criminal case berhasil diperbarui.",
  "data": {
    "id": 145,
    "application_no": "CT-CR-2026-0079",
    "cid_no": "2071",
    "accused_name": "Jay Jamal",
    "status": "closed",
    "decision": "10 Years Imprisonment",
    "bail_status": "refund",
    ...
  }
}
```

---

## Status Values

Nilai valid untuk field `status`:

| Status | Keterangan |
|--------|------------|
| `active` | Kasus aktif |
| `closed` | Kasus ditutup |
| `arraignment` | Tahap arraignment |
| `trial` | Tahap persidangan |
| `sentence` | Tahap penjatuhan hukuman |
| `search warrant` | Surat perintah penggeledahan |
| `arrest warrant` | Surat perintah penangkapan |
| `withdrawn` | Tuntutan dicabut |

---

## Application Number

Format: `CT-CR-{YEAR}-{XXXX}`

- `{YEAR}` — Tahun saat ini (4 digit), contoh: `2026`
- `{XXXX}` — Nomor urut 4 digit, zero-padded, sequential per tahun

Contoh: `CT-CR-2026-0001`, `CT-CR-2026-0079`

Nomor di-generate otomatis saat `POST /api/criminal-cases`. Tidak perlu dikirim dalam request body.

---

## Data Fields

| Field | Type | Keterangan |
|-------|------|------------|
| `id` | integer | Primary key, auto-increment |
| `application_no` | string | Nomor perkara (auto-generated) |
| `cid_no` | string | CID case number |
| `accused_name` | string | Nama terdakwa |
| `judge_name` | string/null | Nama hakim |
| `prosecutor_name` | string/null | Nama jaksa penuntut |
| `public_defender_name` | string/null | Nama pembela umum |
| `date_of_hearing` | datetime/null | Tanggal sidang |
| `accused_plea` | string | Plea terdakwa (guilty/not guilty/no contest) |
| `bail_amount` | decimal/null | Jumlah bail ($) |
| `bail_status` | string | Status bail (paid/not paid/refund) |
| `decision` | string/null | Putusan/charges |
| `status` | string | Status kasus |
| `usms_input` | string/null | Penanda input dari USMS |
| `user_id` | integer/null | ID user yang membuat |
| `created_at` | datetime | Waktu dibuat |
| `updated_at` | datetime | Waktu terakhir diupdate |

---

## Error Responses

| HTTP Status | Kondisi | Response |
|-------------|---------|----------|
| 200 | Success (GET) | `{"success": true, "message": "...", "data": ...}` |
| 201 | Created (POST) | `{"success": true, "message": "...", "data": {...}}` |
| 401 | Unauthorized | `{"success": false, "message": "Unauthorized..."}` |
| 404 | Not Found | `{"success": false, "message": "Data tidak ditemukan.", "data": null}` |
| 422 | Validation Error | `{"success": false, "message": "Validasi gagal.", "errors": {...}}` |

---

## Integrasi dengan USMS

USMS menggunakan `DojCriminalCaseService` untuk berkomunikasi dengan API ini.

### Environment Variables (USMS)

```env
DOJ_API_URL=http://localhost:8001/api
DOJ_API_KEY=your-api-key
```

### Environment Variables (DOJ)

```env
DOJ_API_KEY=your-api-key
```

Kedua sisi harus menggunakan API key yang sama.

### Alur Data

```
Officer USMS input tahanan → UserPrison::create()
                           → DojCriminalCaseService::store()
                           → POST /api/criminal-cases
                           → CriminalCase created di DOJ
```

Kegagalan API tidak menggagalkan penyimpanan lokal di USMS (fire-and-forget pattern).
