# Panduan MCF (Maintenance Check Flight): Cara Pakai & Apa yang Terjadi > Dokumen ini menjelaskan **cara mengelola MCF** sebuah helikopter — mengaktifkan, mengisi/edit draft, menandatangani (sign), membatalkan tanda tangan, dan membatalkan MCF — beserta **apa yang terjadi** di status helikopter, halaman fleet, dan log. > > Semua endpoint berawalan `/api/v1` dan butuh login. MCF adalah **entity per-helikopter** dengan lifecycle draft → signed. --- ## 1. Konsep singkat **MCF** = penerbangan uji (check flight) yang wajib dilakukan setelah perawatan tertentu. Selama helikopter "sedang MCF", statusnya `mcf` di fleet. Tiga pemain endpoint: | Endpoint | Tugasnya | |---|---| | **`set`** | Yes/No + **tempat kerja draft** (buat, isi, edit data check-flight) | | **`sign`** | **finalize** (tandatangani hasil) / **unsign** (balik ke draft) | | **`get` / `get-by-helicopter`** | baca satu MCF / daftar (log, termasuk yang cancelled & signed) | > **Tidak ada** endpoint `create`/`delete`/`unassign` lagi — semuanya lewat `set` & `sign`. --- ## 2. Status (state) sebuah MCF | State | Artinya | `completed_at` | `cancelled_at` | Status heli | |---|---|---|---|---| | **Draft** | Dibuat/diisi, belum ditandatangani | kosong | kosong | `mcf` | | **Signed – passed** | Sudah tanda tangan, hasil **lulus** | terisi | kosong | **clear** (keluar MCF) | | **Signed – failed** | Sudah tanda tangan, hasil **gagal** | terisi | kosong | `mcf` (perlu re-flight) | | **Cancelled** | Draft di-set No ("tidak jadi", tak pernah sign) | kosong | terisi | **lepas** (fleet placeholder) | **Aturan penting:** - **1 MCF terbuka (draft) per helikopter.** `set active:true` saat draft sudah ada → **meng-update** draft itu, bukan bikin baru. - **Cancelled hanya untuk draft** (yang belum pernah di-sign). MCF yang sudah signed = **event nyata**, tidak bisa di-cancel. - MCF yang cancelled/signed **tetap tersimpan** di list (`get-by-helicopter`) sebagai **log/history**. --- ## 3. Flow lengkap (langkah + apa yang terjadi) ### Langkah 1 — Aktifkan / isi / edit draft `POST /mcf/set/{helicopter_id}` ```json { "data": { "type": "mcf_set", "attributes": { "active": true, "flight_id": "019d6774-98e8-7fba-9ef4-3795c0da8a13", "af_hours": "1245.3", "landing_count": 3, "date": "2026-06-17", "result": "passed", "notes": "MCF setelah pekerjaan engine mount" } } } ``` **Apa yang terjadi:** - Belum ada draft → **buat draft baru** → **201**. - Sudah ada draft terbuka → **update draft itu** dengan data yang dikirim → **200**. - Semua field data **opsional** — boleh isi sebagian dulu, lengkapi bertahap dengan `set` lagi. - Helikopter masuk **status `mcf`**. Di fleet, object `mcf` muncul (`sign: false`, `af_hours`/`landing_count` pre-fill dari total pesawat kalau belum diisi). > `active` boleh diomit → dianggap `true`. ### Langkah 2 — Finalize (tanda tangan) `POST /mcf/sign/{id}` ```json { "data": { "type": "mcf_sign", "attributes": { "sign": true, "af_hours": "1245.3", "landing_count": 3, "utc_time": "2026-06-17T08:30:00Z", "date": "2026-06-17", "result": "passed" } } } ``` **Apa yang terjadi:** - **Wajib lengkap**: `af_hours`, `landing_count`, `utc_time`, `date`, `result` (else **422**, pointer ke field yang kurang). - MCF jadi **signed/completed** (`completed_at` + `completed_by` terisi). - `result: passed` → **status MCF clear** (helikopter keluar dari MCF). - `result: failed` → helikopter **tetap `mcf`** (perlu re-flight — buat MCF baru lewat `set active:true`). ### Langkah 3 — Batal tanda tangan (unsign) `POST /mcf/sign/{id}` dengan `{ "sign": false }` **Apa yang terjadi:** - MCF yang signed **balik jadi draft** (`completed_at` dikosongkan) — **datanya tetap**. - Bisa di-edit lagi lewat `set`, lalu di-`sign` ulang. ### Langkah 4 — Nonaktifkan / batal (set No) `POST /mcf/set/{helicopter_id}` dengan `{ "active": false }` **Apa yang terjadi:** - Draft (belum sign) → ditandai **`cancelled`** ("tidak jadi") → **status MCF lepas** → fleet balik **placeholder**. Record **tetap di list** sebagai log cancelled. - **Sudah signed → BUKAN batal** (event nyata). MCF dibiarkan; response mengembalikan MCF signed itu apa adanya. Di fleet **datanya tetap muncul** (lihat §5): untuk `passed` helikopter sudah **keluar status MCF** ("active no") tapi data MCF sebelumnya **tetap tampil**; untuk `failed` helikopter tetap `mcf`. - Tidak ada MCF sama sekali → **no-op** (idempotent, sudah "No"). --- ## 4. Contoh alur khas ``` set {active:true, af_hours, result, ...} → draft dibuat (201) set {active:true, ...revisi...} → draft di-update (200) sign {sign:true, ...lengkap...} → signed (passed=clear / failed=tetap) ── kalau salah ── sign {sign:false} → balik draft (data tetap) → edit → sign lagi ── kalau tidak jadi ── set {active:false} → cancelled (lepas status, tetap jadi log) ``` --- ## 5. Efek ke Fleet Status Object `mcf` di response fleet (`GET /api/v1/fleet-status/...`) selalu mencerminkan **MCF terbaru** helikopter. Field **`active`** = apakah helikopter **sedang dalam MCF** (draft, atau signed-failed yang perlu re-flight); `false` kalau cleared/cancelled/tidak ada. | Kondisi MCF terbaru | `active` | Object `mcf` di fleet | |---|---|---| | Tidak ada / cancelled | `false` | **placeholder** — `id: ""`, `sign: false`, `af_hours`/`landing_count` dari total pesawat | | Draft (belum sign) | `true` | id draft, `sign: false`, data pre-fill dari pesawat kalau kosong | | Signed – passed | `false` | id, `sign: true`, snapshot MCF + `signed_by` (data tetap tampil walau status sudah clear) | | Signed – failed | `true` | id, `sign: true`, snapshot + `signed_by` (masih MCF, perlu re-flight) | Urutan status di fleet & hold list: **MCF → AOG → Booked → Available** (paling kritikal dulu). --- ## 6. Ringkasan endpoint | Method | Path | Fungsi | |---|---|---| | `POST` | `/api/v1/mcf/set/{helicopter_id}` | activate/edit draft (`active:true`) · cancel (`active:false`) | | `POST` | `/api/v1/mcf/sign/{id}` | finalize (`sign:true`) · unsign (`sign:false`) | | `GET` | `/api/v1/mcf/get/{id}` | baca satu MCF | | `GET` | `/api/v1/mcf/get-by-helicopter/{helicopter_id}` | daftar MCF helikopter (log) | **Permission:** `mcf.create` (untuk `set`), `mcf.complete` (untuk `sign`), `mcf.read` (untuk `get`). --- ## 7. Kode error umum | Kode | Kapan | |---|---| | `MCF_INVALID_UUID` | `helicopter_id` / `id` bukan UUID valid (422) | | `MCF_INVALID_JSON` | body JSON rusak (400) | | `INVALID_DATA_TYPE` | tipe field salah (mis. `flight_id` dikirim angka) (422) | | `MCF_INVALID_PAYLOAD` | field check-flight kurang/salah saat `sign:true` (422, pointer ke field) | | `MCF_NOT_FOUND` | MCF id tidak ada (404) | > **Catatan:** relasi MCF ke penerbangan lewat `flight_id` (opsional). Lihat juga [aog-mcf-nsr-flow.md](aog-mcf-nsr-flow.md) untuk gambaran status helikopter secara keseluruhan (AOG/MCF/NSR).