Files
fm_be/docs/takeover-step-by-step.md
2026-07-16 22:16:45 +07:00

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:

  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:

{
  "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:

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:

  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:

{
  "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:

{
  "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:

{
  "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.