# Takeover Flow Step by Step

Dokumen ini menjelaskan flow `takeover` dari sisi frontend secara detail: endpoint yang dipakai, urutan request, payload yang wajib dan opsional, serta contoh request/response.

Untuk detail khusus file takeover, lihat [docs/takeover-file-api.md](./takeover-file-api.md).

## Ringkasan Singkat

`Takeover` adalah endpoint atomic untuk membuat satu paket data sekaligus:

1. `takeover_ac`
2. `duty_roster`
3. `reserve_ac`
4. `flight_inspection`
5. `before_flight_inspection`
6. `flight_prep_check`
7. `flight`

Artinya frontend cukup kirim **1 request create takeover**, backend akan membuat seluruh record terkait dalam satu transaksi.

## Endpoint Yang Tersedia

Ada 1 route create takeover yang menuju handler yang sama:

1. `POST /api/v1/takeovers/create`

Keduanya memakai permission:

`reserve_ac.create`

Route lain yang tersedia:

1. `GET /api/v1/takeovers/get-all`
2. `GET /api/v1/takeovers/get/:id`
3. `PATCH /api/v1/takeovers/update/:id`
4. `DELETE /api/v1/takeovers/delete/:id`

Untuk dokumentasi ini fokus utama ada pada flow `create takeover`.

## Step by Step Flow

### Step 1. Siapkan data master terlebih dahulu

Sebelum hit create takeover, frontend harus sudah punya:

1. `base_id`
2. `helicopter_id`
3. `duty_date`
4. daftar crew untuk roster
5. data inspeksi sebelum terbang
6. data persiapan flight

Kalau salah satu ID tidak valid atau tidak ditemukan, backend akan gagal.

### Step 2. Susun payload utama

Payload mengikuti format JSON:API sederhana:

```json
{
  "data": {
    "type": "takeover",
    "attributes": {
      ...
    }
  }
}
```

Field `type` menerima:

1. `takeover`
2. `takeover_create`

Frontend boleh kirim salah satu, tapi disarankan konsisten pakai `takeover_create` atau `takeover` sesuai standar proyek yang dipakai tim.

### Step 3. Kirim request create

Request create akan:

1. validasi JSON
2. validasi struktur payload
3. validasi UUID `base_id`
4. validasi UUID `helicopter_id`
5. validasi tanggal `duty_date`
6. membangun roster crew
7. membuat seluruh data dalam 1 transaksi
8. mengembalikan response takeover lengkap

Kalau satu sub-step gagal, seluruh transaksi gagal.

### Step 4. Terima response

Response sukses akan mengembalikan struktur `takeover` lengkap berisi:

1. `takeover_ac_id`
2. `duty_roster_id`
3. `flight_id`
4. `reserve_ac_id`
5. `flight_inspection_id`
6. `shift_start`
7. `shift_end`
8. `base`
9. `helicopter`
10. `roster_detail`
11. `inspection`
12. `flight`
13. `duty_roster`

Frontend sebaiknya memakai response ini sebagai sumber data final, bukan mengasumsikan data lokal sama persis dengan hasil backend.

## Request Detail

### Endpoint

`POST /api/v1/takeovers/create`

atau

`POST /api/v1/reserve-acs/takeovers/create`

### Headers

Gunakan header umum API proyek:

```http
Authorization: Bearer <token>
Content-Type: application/json
Accept: application/json
```

### Body

```json
{
  "data": {
    "type": "takeover",
    "attributes": {
      "base_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "duty_date": "2026-04-15",
      "notes": "Opsional catatan takeover",
      "shift_time": {
        "shift_start": "06:00",
        "shift_end": "18:00"
      },
      "roster_detail": {
        "pilot": [
          {
            "id": "018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d",
            "crew_type": "main",
            "flight_instructor": true,
            "line_checker": false,
            "supervisor": false,
            "examiner": false,
            "co_pilot": true,
            "shift_date": {
              "date_start": "2026-04-15",
              "date_end": "2026-04-15"
            },
            "shift_time": {
              "shift_start": "06:00",
              "shift_end": "14:00"
            }
          }
        ],
        "doctor": [
          {
            "id": "018f3a5c-7a6f-7c2a-8d4a-4b5b1f6c8e9d"
          }
        ],
        "rescuer": [],
        "helper": [],
        "other_person": [
          {
            "name": "Guest Person",
            "mobile_phone": "+43-1234",
            "email": "guest@example.com"
          }
        ]
      },
      "helicopter_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "inspection": {
        "inspection_date": "2026-04-15",
        "before": {
          "oil_engine_nr1_checked": true,
          "oil_engine_nr2_checked": false,
          "hydraulic_lh_checked": true,
          "hydraulic_rh_checked": true,
          "oil_transmission_mgb_checked": true,
          "oil_transmission_igb_checked": true,
          "oil_transmission_tgb_checked": true,
          "fuel_amount": 50.5,
          "fuel_unit": "LT",
          "fuel_added_amount": 10,
          "note": "Opsional note inspeksi sebelum terbang",
          "file_checklist": [
            {
              "helicopter_file_id": "019d7000-aaaa-7bbb-8ccc-111111111111",
              "is_done": true
            }
          ]
        },
        "prepare": {
          "notam_briefing": true,
          "weather_briefing": true,
          "operational_flight_plan": false,
          "file_checklist": [
            {
              "helicopter_file_id": "019d7000-bbbb-7ccc-8ddd-222222222222",
              "is_done": true
            }
          ]
        }
      }
    }
  }
}
```

## Penjelasan Field

### `data`

Container utama request.

### `data.type`

Nilai yang diterima:

1. `takeover`
2. `takeover_create`

### `data.attributes.base_id`

Wajib. UUID base yang dipakai untuk takeover.

Backend akan memvalidasi:

1. format UUID
2. base harus ada di database

### `data.attributes.duty_date`

Wajib. Format tanggal harus `YYYY-MM-DD`.

Contoh:

`2026-04-15`

### `data.attributes.notes`

Opsional.

Gunakan untuk catatan tambahan takeover. Jika tidak ada, field ini boleh tidak dikirim atau dikirim `null`.

### `data.attributes.shift_time`

Secara schema tidak diberi `validate:"required"`, tetapi secara proses bisnis ini dianggap bagian penting dari takeover.

Format:

```json
{
  "shift_start": "06:00",
  "shift_end": "18:00"
}
```

Keterangan:

1. `shift_start` adalah waktu mulai tugas.
2. `shift_end` adalah waktu selesai tugas.

Jika frontend ingin aman, selalu kirim kedua field ini.

### `data.attributes.roster_detail`

Wajib secara bisnis. Berisi daftar crew yang akan masuk ke `duty_roster`.

Strukturnya terdiri dari:

1. `pilot`
2. `doctor`
3. `rescuer`
4. `helper`
5. `other_person`

### `data.attributes.helicopter_id`

Wajib. UUID helicopter yang dipakai pada takeover.

Backend akan memvalidasi:

1. format UUID
2. helicopter harus ada di database

### `data.attributes.inspection`

Wajib. Ini adalah paket inspeksi takeover.

#### `inspection.inspection_date`

Wajib. Format `YYYY-MM-DD`.

#### `inspection.before`

Wajib sebagai objek, tetapi isi field di dalamnya sebagian besar opsional.

Field opsional:

1. `oil_engine_nr1_checked`
2. `oil_engine_nr2_checked`
3. `hydraulic_lh_checked`
4. `hydraulic_rh_checked`
5. `oil_transmission_mgb_checked`
6. `oil_transmission_igb_checked`
7. `oil_transmission_tgb_checked`
8. `fuel_amount`
9. `fuel_unit`
10. `fuel_added_amount`
11. `note`
12. `file_checklist`

#### `inspection.before.fuel_unit`

Jika dikirim, nilai yang diterima backend adalah:

1. `LT`
2. `KG`
3. `POUND`

Kalau nilainya tidak valid, request akan gagal.

#### `inspection.before.file_checklist`

Array opsional.

Setiap item harus punya:

1. `helicopter_file_id`
2. `is_done`

#### `inspection.prepare`

Wajib sebagai objek, tetapi field di dalamnya opsional.

Field opsional:

1. `notam_briefing`
2. `weather_briefing`
3. `operational_flight_plan`
4. `file_checklist`

#### `inspection.prepare.file_checklist`

Array opsional.

Setiap item harus punya:

1. `helicopter_file_id`
2. `is_done`

## Detail Roster

### `roster_detail.pilot`

Array pilot. Setiap item dapat berisi:

1. `id` - UUID crew
2. `crew_type` - biasanya `main` atau `additional`
3. `flight_instructor` - boolean
4. `line_checker` - boolean
5. `supervisor` - boolean
6. `examiner` - boolean
7. `co_pilot` - boolean
8. `shift_date` - opsional
9. `shift_time` - opsional

### `roster_detail.doctor`

Array crew doctor.

Setiap item:

1. `id` - UUID crew
2. `shift_date` - opsional
3. `shift_time` - opsional

### `roster_detail.rescuer`

Array crew rescuer.

Setiap item:

1. `id` - UUID crew
2. `shift_date` - opsional
3. `shift_time` - opsional

### `roster_detail.helper`

Array crew helper.

Setiap item:

1. `id` - UUID crew
2. `shift_date` - opsional
3. `shift_time` - opsional

### `roster_detail.other_person`

Array orang tambahan yang bukan crew terdaftar.

Setiap item:

1. `name`
2. `mobile_phone`
3. `email`

## Field Optional Yang Perlu Diperhatikan Frontend

Ini yang paling penting supaya frontend tidak bingung:

### Optional level 1

1. `notes`

### Optional level 2 di `inspection.before`

1. Semua checkbox `*_checked`
2. `fuel_amount`
3. `fuel_unit`
4. `fuel_added_amount`
5. `note`
6. `file_checklist`

### Optional level 2 di `inspection.prepare`

1. `notam_briefing`
2. `weather_briefing`
3. `operational_flight_plan`
4. `file_checklist`

### Optional level 2 di roster detail

1. `shift_date`
2. `shift_time`

### Field yang tetap harus dianggap wajib oleh frontend

Walaupun beberapa field di struct tidak pakai `validate:"required"`, frontend sebaiknya tetap menyiapkan:

1. `base_id`
2. `duty_date`
3. `roster_detail`
4. `helicopter_id`
5. `inspection`
6. `inspection.inspection_date`

Alasannya:

1. backend memakai data itu untuk membangun transaksi
2. frontend akan lebih stabil jika payload selalu lengkap
3. respons error dari backend akan lebih mudah dihindari

## Contoh Request Minimal Yang Aman

Kalau ingin payload ringkas tetapi masih aman, gunakan pola berikut:

```json
{
  "data": {
    "type": "takeover",
    "attributes": {
      "base_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "duty_date": "2026-04-15",
      "shift_time": {
        "shift_start": "06:00",
        "shift_end": "18:00"
      },
      "roster_detail": {
        "pilot": [],
        "doctor": [],
        "rescuer": [],
        "helper": [],
        "other_person": []
      },
      "helicopter_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "inspection": {
        "inspection_date": "2026-04-15",
        "before": {},
        "prepare": {}
      }
    }
  }
}
```

Catatan:

1. Ini minimal secara struktur.
2. Secara bisnis, frontend biasanya tetap perlu mengisi roster dan checklist sesuai kebutuhan operasional.

## Response Sukses

HTTP status:

`201 Created`

Contoh bentuk response:

```json
{
  "data": {
    "type": "takeover",
    "attributes": {
      "takeover_ac_id": "019d8000-aaaa-7bbb-8ccc-333333333333",
      "duty_roster_id": "019d8000-bbbb-7ccc-8ddd-444444444444",
      "flight_id": "019d8000-cccc-7ddd-8eee-555555555555",
      "reserve_ac_id": "019d8000-dddd-7eee-8fff-666666666666",
      "flight_inspection_id": "019d8000-eeee-7fff-9000-777777777777",
      "shift_start": "06:00",
      "shift_end": "18:00",
      "base_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "duty_date": "2026-04-15",
      "helicopter_id": "019d6771-5fb5-7337-837f-bc5ed85181a1",
      "notes": "Opsional catatan takeover",
      "roster_detail": {
        "pilot": [],
        "doctor": [],
        "rescuer": [],
        "helper": [],
        "other_person": []
      },
      "inspection": {},
      "flight": {},
      "duty_roster": {}
    }
  }
}
```

## Error Yang Umum

### 400 Bad Request

Biasanya terjadi karena:

1. JSON tidak valid
2. create gagal di service
3. UUID tidak bisa diproses
4. data referensi tidak ditemukan

### 422 Unprocessable Entity

Biasanya terjadi karena:

1. `type` salah
2. field wajib tidak ada
3. format UUID salah
4. tanggal bukan format `YYYY-MM-DD`
5. `fuel_unit` tidak valid
6. roster detail tidak valid

## Saran Implementasi Frontend

1. Selalu kirim payload lengkap dari form state.
2. Jangan kirim field boolean sebagai string.
3. Pastikan UUID sudah tervalidasi sebelum submit.
4. Validasi tanggal di frontend dengan format `YYYY-MM-DD`.
5. Jika user tidak isi field opsional, lebih baik field itu diomit daripada dikirim string kosong.
6. Setelah request sukses, gunakan response backend untuk refresh state halaman.

## Catatan Penting

1. `takeover` ini bersifat atomic.
2. Jika satu bagian gagal, semua data batal dibuat.
3. `notes` adalah satu-satunya field tingkat atas yang jelas opsional.
4. Banyak field di nested object yang secara schema terlihat opsional, tetapi secara flow bisnis tetap perlu diisi agar hasilnya masuk akal.
