init push
This commit is contained in:
165
docs/mcf-flow.md
Normal file
165
docs/mcf-flow.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user