579 lines
12 KiB
Markdown
579 lines
12 KiB
Markdown
# 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.
|