# Flight Ops Locks and Helicopter Usage Sync

Dokumen ini menjelaskan alur data untuk `takeover`, `mission`, `flight_data`, `after_flight_inspection`, `fm_report`, dan `helicopter_usage`.

Tujuan utamanya:
- mencegah perubahan data pada fase yang sudah final
- menjaga `helicopter_usage` sebagai ringkasan yang dihitung dari data sumber
- membuat perilaku backend konsisten untuk frontend dan integrasi lain

## Ringkasan Aturan

1. Saat `after_flight_inspection` sudah dibuat:
   - `mission` untuk flight itu tidak boleh dibuat atau di-update lagi
   - `flight_data` baru tidak boleh dibuat lagi
   - `flight_data` yang sudah ada masih boleh diedit
2. Saat `fm_report` di-complete:
   - `flight_data` untuk flight itu terkunci
   - `fm_report` menjadi read-only
   - `helicopter_usage` baru dihitung ulang dari data sumber
3. Saat `GET /api/v1/fm-reports/get/:flight_id`:
   - backend tetap mengirim `helicopter_usage`
   - jika row belum ada di database, response tetap mengirim nilai `0`

## Alur Besar

Urutan normalnya:

1. `takeover` dibuat
2. `mission` dibuat
3. `flight_data` diisi dan masih bisa diubah
4. `after_flight_inspection` dibuat
5. `fm_report` draft otomatis tersedia
6. user melengkapi `fm_report`
7. `POST /api/v1/fm-reports/complete/:flight_id`
8. backend menghitung ulang `helicopter_usage`

## Detail Per Modul

### 1) Mission

Mission bisa dibuat dan di-update selama flight belum masuk fase after flight inspection.

Begitu `after_flight_inspection` sudah ada untuk flight tersebut:
- create mission ditolak
- update mission ditolak

Alasan bisnis:
- setelah after flight masuk, mission dianggap sudah masuk fase final
- mission tidak boleh berubah karena akan mempengaruhi rekonsiliasi data flight

Error yang biasanya muncul:
- `MISSION_AFTER_FLIGHT_LOCKED`

Referensi:
- lihat tabel `Mission` di [`docs/error-catalog.md`](./error-catalog.md)

### 2) Flight Data

`flight_data` adalah sumber utama untuk hitungan operasional seperti:
- landing count
- durasi flight
- hook release
- rotor brake cycle

#### Sebelum after flight inspection

- create flight data boleh
- update flight data boleh
- delete flight data boleh

#### Setelah after flight inspection dibuat

- create flight data baru ditolak
- update flight data yang sudah ada masih boleh
- delete flight data yang sudah ada ditolak

#### Setelah FM report di-complete

- update flight data ditolak
- delete flight data ditolak
- data dianggap final

Error yang biasanya muncul:
- `FLIGHT_DATA_CREATE_BLOCKED`
- `FLIGHT_DATA_AFTER_FLIGHT_LOCKED`
- `FLIGHT_DATA_LOCKED`

Referensi:
- lihat tabel `Flight Data` di [`docs/error-catalog.md`](./error-catalog.md)

### 3) After Flight Inspection

`after_flight_inspection` dipakai sebagai penanda bahwa flight sudah masuk fase akhir sebelum FM report di-complete.

Catatan penting:
- create / upsert after flight inspection tidak lagi memicu kalkulasi `helicopter_usage`
- after flight inspection hanya menyimpan hasil inspeksi
- kalkulasi usage dipindahkan ke langkah `fm_report complete`

### 4) FM Report

FM report dibuat sebagai draft setelah after flight inspection masuk ke flow.

#### Sebelum complete

- report masih bisa di-update
- engine metric masih bisa diisi / diubah
- `helicopter_usage` belum dihitung ulang oleh backend

#### Setelah complete

- report menjadi read-only
- update FM report ditolak
- `completed_at` dan `completed_by` disimpan
- backend memicu refresh `helicopter_usage`

Endpoint yang dipakai:
- `POST /api/v1/fm-reports/complete/:flight_id`

Error yang biasanya muncul:
- `FM_REPORT_LOCKED`
- `FM_REPORT_COMPLETE_FAILED`

Referensi:
- lihat tabel `FM Report` di [`docs/error-catalog.md`](./error-catalog.md)

### 5) Helicopter Usage

`helicopter_usage` sekarang diperlakukan sebagai summary record.

Karakteristiknya:
- dihitung dari data sumber
- bukan angka yang diisi manual untuk flow normal
- tetap bisa di-maintain manual lewat CRUD admin/backfill kalau diperlukan

#### Sumber data kalkulasi

- `total_landing` = sum `flight_data.landing_count`
- `total_airframe_hours` = sum durasi flight
- `total_airframe_cycles` = count flight data
- `total_hook_release` = sum `flight_data.hook_releases`
- `total_rotor_brake_cycle` = sum `flight_data.rotor_brake_cycle`
- `total_flight_report` = count report yang punya helicopter terkait
- metric engine diambil dari field FM report dan dijumlahkan

#### Kapan dihitung

Kalkulasi ulang dilakukan saat:
- `fm_report` di-complete

Kalkulasi tidak dilakukan lagi saat:
- create / update after flight inspection
- create / update / delete flight data
- draft FM report di-upsert

## Response `GET FM Report`

Endpoint:
- `GET /api/v1/fm-reports/get/:flight_id`

Response akan selalu mengirim field `helicopter_usage`.

Perilaku response:
- jika row `helicopter_usage` ada di database, isi nilainya dari row tersebut
- jika row belum ada, backend tetap mengirim object `helicopter_usage` dengan semua angka `0`

Contoh bentuk response:

```json
{
  "data": {
    "type": "fm_report",
    "id": "report-id",
    "attributes": {
      "flight_id": "flight-id",
      "completed_at": null,
      "helicopter_usage": {
        "type": "helicopter_usage",
        "id": "",
        "attributes": {
          "helicopter_id": "helicopter-id",
          "total_landing": 0,
          "total_airframe_hours": 0,
          "total_airframe_cycles": 0,
          "total_engine_1_hours": 0,
          "total_engine_1_gpc_ng_n1": 0,
          "total_engine_1_ptc_nf_n2": 0,
          "total_engine_1_ccc": 0,
          "total_engine_2_hours": 0,
          "total_engine_2_gpc_ng_n1": 0,
          "total_engine_2_ptc_nf_n2": 0,
          "total_engine_2_ccc": 0,
          "total_flight_report": 0,
          "total_hook_release": 0,
          "total_rotor_brake_cycle": 0
        }
      }
    }
  }
}
```

## Status yang Perlu Diingat

### Masih editable

- mission sebelum after flight inspection ada
- flight data sebelum FM report di-complete
- FM report sebelum complete

### Sudah locked

- mission setelah after flight inspection ada
- flight data setelah FM report di-complete
- FM report setelah complete

## Dampak ke Frontend

Frontend sebaiknya mengikuti aturan ini:

1. Jika after flight inspection sudah ada:
   - sembunyikan atau disable aksi create mission
   - sembunyikan atau disable aksi create flight data baru
2. Jika FM report sudah complete:
   - disable semua edit flight data
   - disable edit FM report
3. Saat menampilkan FM report:
   - selalu render section helicopter usage
   - jika angka semua `0`, itu berarti belum ada summary yang terhitung atau belum ada data sumber yang selesai

## Error yang Relevan

Lihat katalog lengkap di:
- [`docs/error-catalog.md`](./error-catalog.md)

Error yang paling sering dipakai di alur ini:
- `MISSION_AFTER_FLIGHT_LOCKED`
- `FLIGHT_DATA_CREATE_BLOCKED`
- `FLIGHT_DATA_AFTER_FLIGHT_LOCKED`
- `FLIGHT_DATA_LOCKED`
- `FM_REPORT_LOCKED`

## Catatan Implementasi

- `after_flight_inspection` tidak lagi memicu refresh `helicopter_usage`
- `flight_data` tidak lagi memicu refresh `helicopter_usage`
- refresh `helicopter_usage` hanya terjadi saat `fm_report` di-complete
- `GET FM Report` tetap aman walau row `helicopter_usage` belum ada

## Referensi Endpoint

- `POST /api/v1/mission/create`
- `PATCH /api/v1/mission/update/{flight_id}`
- `POST /api/v1/flight-data/create`
- `PATCH /api/v1/flight-data/update/{id}`
- `DELETE /api/v1/flight-data/delete/{id}`
- `POST /api/v1/after-flight-inspection/create`
- `PATCH /api/v1/after-flight-inspection/update`
- `POST /api/v1/fm-reports/complete/{flight_id}`
- `GET /api/v1/fm-reports/get/{flight_id}`
