12 KiB
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.
Ringkasan Singkat
Takeover adalah endpoint atomic untuk membuat satu paket data sekaligus:
takeover_acduty_rosterreserve_acflight_inspectionbefore_flight_inspectionflight_prep_checkflight
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:
POST /api/v1/takeovers/create
Keduanya memakai permission:
reserve_ac.create
Route lain yang tersedia:
GET /api/v1/takeovers/get-allGET /api/v1/takeovers/get/:idPATCH /api/v1/takeovers/update/:idDELETE /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:
base_idhelicopter_idduty_date- daftar crew untuk roster
- data inspeksi sebelum terbang
- 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:
{
"data": {
"type": "takeover",
"attributes": {
...
}
}
}
Field type menerima:
takeovertakeover_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:
- validasi JSON
- validasi struktur payload
- validasi UUID
base_id - validasi UUID
helicopter_id - validasi tanggal
duty_date - membangun roster crew
- membuat seluruh data dalam 1 transaksi
- mengembalikan response takeover lengkap
Kalau satu sub-step gagal, seluruh transaksi gagal.
Step 4. Terima response
Response sukses akan mengembalikan struktur takeover lengkap berisi:
takeover_ac_idduty_roster_idflight_idreserve_ac_idflight_inspection_idshift_startshift_endbasehelicopterroster_detailinspectionflightduty_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:
Authorization: Bearer <token>
Content-Type: application/json
Accept: application/json
Body
{
"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:
takeovertakeover_create
data.attributes.base_id
Wajib. UUID base yang dipakai untuk takeover.
Backend akan memvalidasi:
- format UUID
- 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:
{
"shift_start": "06:00",
"shift_end": "18:00"
}
Keterangan:
shift_startadalah waktu mulai tugas.shift_endadalah 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:
pilotdoctorrescuerhelperother_person
data.attributes.helicopter_id
Wajib. UUID helicopter yang dipakai pada takeover.
Backend akan memvalidasi:
- format UUID
- 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:
oil_engine_nr1_checkedoil_engine_nr2_checkedhydraulic_lh_checkedhydraulic_rh_checkedoil_transmission_mgb_checkedoil_transmission_igb_checkedoil_transmission_tgb_checkedfuel_amountfuel_unitfuel_added_amountnotefile_checklist
inspection.before.fuel_unit
Jika dikirim, nilai yang diterima backend adalah:
LTKGPOUND
Kalau nilainya tidak valid, request akan gagal.
inspection.before.file_checklist
Array opsional.
Setiap item harus punya:
helicopter_file_idis_done
inspection.prepare
Wajib sebagai objek, tetapi field di dalamnya opsional.
Field opsional:
notam_briefingweather_briefingoperational_flight_planfile_checklist
inspection.prepare.file_checklist
Array opsional.
Setiap item harus punya:
helicopter_file_idis_done
Detail Roster
roster_detail.pilot
Array pilot. Setiap item dapat berisi:
id- UUID crewcrew_type- biasanyamainatauadditionalflight_instructor- booleanline_checker- booleansupervisor- booleanexaminer- booleanco_pilot- booleanshift_date- opsionalshift_time- opsional
roster_detail.doctor
Array crew doctor.
Setiap item:
id- UUID crewshift_date- opsionalshift_time- opsional
roster_detail.rescuer
Array crew rescuer.
Setiap item:
id- UUID crewshift_date- opsionalshift_time- opsional
roster_detail.helper
Array crew helper.
Setiap item:
id- UUID crewshift_date- opsionalshift_time- opsional
roster_detail.other_person
Array orang tambahan yang bukan crew terdaftar.
Setiap item:
namemobile_phoneemail
Field Optional Yang Perlu Diperhatikan Frontend
Ini yang paling penting supaya frontend tidak bingung:
Optional level 1
notes
Optional level 2 di inspection.before
- Semua checkbox
*_checked fuel_amountfuel_unitfuel_added_amountnotefile_checklist
Optional level 2 di inspection.prepare
notam_briefingweather_briefingoperational_flight_planfile_checklist
Optional level 2 di roster detail
shift_dateshift_time
Field yang tetap harus dianggap wajib oleh frontend
Walaupun beberapa field di struct tidak pakai validate:"required", frontend sebaiknya tetap menyiapkan:
base_idduty_dateroster_detailhelicopter_idinspectioninspection.inspection_date
Alasannya:
- backend memakai data itu untuk membangun transaksi
- frontend akan lebih stabil jika payload selalu lengkap
- respons error dari backend akan lebih mudah dihindari
Contoh Request Minimal Yang Aman
Kalau ingin payload ringkas tetapi masih aman, gunakan pola berikut:
{
"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:
- Ini minimal secara struktur.
- Secara bisnis, frontend biasanya tetap perlu mengisi roster dan checklist sesuai kebutuhan operasional.
Response Sukses
HTTP status:
201 Created
Contoh bentuk response:
{
"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:
- JSON tidak valid
- create gagal di service
- UUID tidak bisa diproses
- data referensi tidak ditemukan
422 Unprocessable Entity
Biasanya terjadi karena:
typesalah- field wajib tidak ada
- format UUID salah
- tanggal bukan format
YYYY-MM-DD fuel_unittidak valid- roster detail tidak valid
Saran Implementasi Frontend
- Selalu kirim payload lengkap dari form state.
- Jangan kirim field boolean sebagai string.
- Pastikan UUID sudah tervalidasi sebelum submit.
- Validasi tanggal di frontend dengan format
YYYY-MM-DD. - Jika user tidak isi field opsional, lebih baik field itu diomit daripada dikirim string kosong.
- Setelah request sukses, gunakan response backend untuk refresh state halaman.
Catatan Penting
takeoverini bersifat atomic.- Jika satu bagian gagal, semua data batal dibuat.
notesadalah satu-satunya field tingkat atas yang jelas opsional.- Banyak field di nested object yang secara schema terlihat opsional, tetapi secara flow bisnis tetap perlu diisi agar hasilnya masuk akal.