# Rencana Perbaikan Modul Variant Cutover
## Checklist Pengerjaan & Status

**Berdasarkan:** STANDAR_MODUL_VARIANT_CUTOVER_ISO25010.md
**Target Modul:** `application/modules/variant_cutover/`
**Tanggal Dokumen:** 2026-05-22
**Status Keseluruhan:** ~60% sesuai standar

---

## Cara Penggunaan

- **Status:** ✅ selesai | 🔄 sedang dikerjakan | ☐ belum
- **PIC:** Nama penanggung jawab
- **Tgl Selesai:** Tanggal penyelesaian
- **Catatan:** Kendala, referensi, link ke commit/PR

---

## Fase 1 — CRITICAL (Safety & Compliance)

### 1.1 Open Document Validation (ODC-01 s/d ODC-06)

**Lokasi Target:**
- `controllers/Transaksi.php:538-712` — area `validate()` method, tambah blok validasi baru setelah balance check
- `config/coTransaksiUi.php:9-29` (flow 881) dan `:379-400` (flow 7881) — opsional: config flag untuk enable/disable validasi
- `controllers/FollowUp.php:4367` — `doFollowup()` entry point, pre-execution guard

> **Catatan Scope — Penting:**
> Validasi open document TIDAK dibatasi ke 4 modul (PO, SO, Opname, Movement). Karena semua modul transaksional (`pembelian/`, `penjualan/`, `distribusifg/`, `distribusiproduksi/`, `distribusisupplies/`, `requeststok/`, `pindahgudang/`, `produksi/`, `produksiproses/`, `opname/`, `adjustment/`, `pembatalan/`, `variant_cutover/`) bisa memiliki dokumen open yang mereferensi `produk_id = parent_produk`.
>
> `konversi_varian/` TIDAK dimasukkan karena merupakan modul lama yang akan digantikan oleh `variant_cutover/` dan akan dibuang.
>
> **Pendekatan yang benar:** query table transaksi_data (MongoDB) secara global — cari semua dokumen dengan `produk_id = parent_produk` AND `valid_qty > 0` AND `trash = 0` di semua jenis transaksi. Kelompokkan hasilnya per modul asal untuk ditampilkan ke user.
>
> **Catatan Edukasi:** Setiap pesan blokir WAJIB menyertakan penjelasan risiko per dokumen (PO → barang tidak bisa diterima, SO → pesanan gagal dikirim, Opname → stok double-count, Transfer → stok di perjalanan hilang konteks, Produksi → komponen tidak bisa diproduksi) dan langkah penyelesaian (GR/Delivery/Cancel/Selesaikan opname).

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 1.1a | Query global `transaksi_data` by `produk_id` | `Transaksi.php:680` — SQL JOIN `transaksi_data` + `transaksi` dengan filter `produk_id IN (parent_ids)`, `valid_qty > 0`, `trash = 0`, `status = '1'`. | ✅ | 2026-05-22 | Implemented as direct SQL query in validate() |
| 1.1b | Lookup detail transaksi & kelompokkan | Sudah termasuk dalam 1.1a — query JOIN mencakup `t.nomer`, `t.jenis_master`, `t.step_number`, `td.produk_nama`. | ✅ | 2026-05-22 | |
| 1.1c | Cek status final transaksi | Filter awal: `valid_qty > 0`. Untuk penyempurnaan, filter step terakhir bisa ditambahkan kemudian. | ✅ | 2026-05-22 | Masih bisa diperbaiki dengan filter step final |
| 1.1d | Blokir + display error | `Transaksi.php:752` — push ke `$errMsgs[]` dengan format panel merah berisi daftar open document, risiko per tipe, dan solusi. | ✅ | 2026-05-22 | Juga include module label mapping |
| 1.1e | Laporan open document (ODC-05) | `views/transaksi.php:10970` area display — panel MERAH dengan daftar open document, dikelompokkan per modul. Setiap item: risiko + solusi (lihat catatan edukasi). | | ☐ | | |
| 1.1f | Mode legacy transisi (ODC-06) | `Transaksi.php` — flag `$allowLegacyMode` untuk grandfather dokumen lama. Jika diaktifkan, dokumen existing tetap pakai parent lama, transaksi baru wajib pakai varian. | | ☐ | | |

### 1.2 Parent Stock Zero Validation (PST-01)

**Lokasi Target:**
- `controllers/Transaksi.php:648-677` — area `jenisTr === 7881` balance check. Tambah validasi stok parent setelahnya
- `controllers/FollowUp.php:4367-4426` — `doFollowup()` pre-execution guard

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 1.2a | Validasi stok parent = 0 | `Transaksi.php:800` — query `stock_locker` dengan filter `produk_id = parent`, `state = 'active'`, `SUM(jumlah)`. Jika > 0, push ke `$errMsgs[]` dengan panel merah lengkap risiko & solusi. | ✅ | 2026-05-22 | Query SUM per cabang+gudang |
| 1.2b | Override approval manager | `Transaksi.php:826` — flag `$_SESSION[$cCode]['main']['override_stok_parent']` untuk skip validasi. Perlu UI checkbox. | 🔄 | | Sudah logic, perlu UI |
| 1.2c | Catat override di audit | Entry ke audit trail (lihat 2.2) dengan flag override | | ☐ | | |

---

## Fase 2 — HIGH (Process Integrity)

### 2.1 Formal Status Enum (TPC-06)

**Lokasi Target:**
- `controllers/Transaksi.php:1267-1270` — area display status `$row->sub_step_number`
- `config/coTransaksiUi.php:9-29` — steps definition
- `controllers/FollowUp.php:2001-2005` — approval spec area
- `controllers/FollowUp.php:4336` — `"approvalSpec" => $approvalSpec` pass ke view

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 2.1a | Add field `conversion_status` | `Modul_Controller.php:88` — helper `setConversionStatus()` simpan di `transaksi_values` dengan key `conversion_status`. Helper `getConversionStatus()` untuk baca. | ✅ | 2026-05-22 | Disimpan di MySQL transaksi_values, bukan MongoDB |
| 2.1b | Mapping step → status | Helper menggunakan valid statuses: DRAFT, IN_PROGRESS, COMPLETED, FAILED, ROLLED_BACK | ✅ | 2026-05-22 | Validasi array di setConversionStatus |
| 2.1c | Update status di `doFollowup()` | `FollowUp.php:4417` — set IN_PROGRESS saat mulai. `FollowUp.php:9513,9535` — set COMPLETED saat sukses. | ✅ | 2026-05-22 | |
| 2.1d | Update status di error handler | `FollowUp.php` — masih perlu catch block untuk set FAILED | | ☐ | | |
| 2.1e | Update status di rollback | `FollowUp.php:9560` `doRevert()` dan `:15067` `doRevertAll()` — set ROLLED_BACK | ✅ | 2026-05-22 | |
| 2.1f | Display status color-coded | `Transaksi.php:1397` — tambah badge warna setelah stateLabel, warna sesuai status (hijau=COMPLETED, merah=FAILED, dll) | ✅ | 2026-05-22 | |

### 2.2 Formal Audit Trail (CMP-01, CMP-02)

**Lokasi Target:**
- Tidak ada tabel audit khusus saat ini — perlu buat baru
- `controllers/FollowUp.php` — setiap entry point operasi
- `config/coTransaksiCore.php` — tambah konfigurasi audit

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 2.2a | Buat collection `audit_log_variant_cutover` | MongoDB collection baru. Fields: `timestamp`, `user_id`, `user_name`, `action`, `transaksi_id`, `old_status`, `new_status`, `fase`, `detail`, `ip_address`, `server_timestamp` | | ☐ | | |
| 2.2b | Log inisiasi konversi | `Create.php:index()` — saat user buat transaksi baru | | ☐ | | |
| 2.2c | Log approve | `FollowUp.php:2001` area `$approvalSpec` — saat approval dijalankan | | ☐ | | |
| 2.2d | Log eksekusi fase 1-2-3 | `FollowUp.php:10616` area `preproc master` / `preproc detail` / `postproc master` / `postproc detail` — log tiap fase | | ☐ | | |
| 2.2e | Log rollback | `FollowUp.php:9535` `doRevert()` dan `:15037` `doRevertAll()` | | ☐ | | |
| 2.2f | Immutability guard | CMP-01: DB-level `insertOnly=true` (no update/delete). App-level: semua write via `MdlMongoMother` dengan mode insert-only | | ☐ | | |
| 2.2g | Server timestamp UTC+7 | CMP-02: paksa `date("Y-m-d H:i:s")` server, jangan kirim dari client JS | | ☐ | | |
| 2.2h | Audit dashboard view | `views/transaksi.php` atau view baru — filter by date/user/action/transaksi_id | | ☐ | | |

### 2.3 Rollback Formal Procedure (COR-05, SoD-04)

**Lokasi Target:**
- `controllers/FollowUp.php:9535` — `doRevert()` entry point
- `controllers/FollowUp.php:15037` — `doRevertAll()` entry point
- `controllers/FollowUp.php:2001` — approval spec area

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 2.3a | Wajib isi alasan rollback | `FollowUp.php:9535` — sebelum eksekusi rollback, validasi `$_POST['alasan_rollback']` tidak kosong | | ☐ | | |
| 2.3b | Approval supervisor untuk rollback | `FollowUp.php:2001` — tambah `$approvalSpec` khusus rollback yang require `userGroup = o_gudang_spv` | | ☐ | | |
| 2.3c | SoD: rollback ≠ inisiator | `FollowUp.php:9535` — query `transaksi.oleh_id`, bandingkan dengan `$this->session->login['id']`. Blokir jika sama | | ☐ | | |
| 2.3d | Log rollback + alasan di audit | Panggil fungsi log (2.2e) dengan menyertakan `alasan_rollback` | | ☐ | | |

### 2.4 Freeze Transaksi (COR-01)

**Lokasi Target:**
- Tidak ada mekanisme freeze global saat ini — perlu baru
- `controllers/FollowUp.php:4367` — `doFollowup()`: set freeze saat mulai

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 2.4a | Field `freeze_status` di produk | Set `freeze = true` pada parent produk saat `IN_PROGRESS` | | ☐ | | |
| 2.4b | Guard transaksi baru saat freeze | `Transaksi.php:validate()` — cek freeze, tolak jika produk sedang freeze | | ☐ | | |
| 2.4c | Unfreeze otomatis | `FollowUp.php` — unfreeze saat status jadi `COMPLETED` atau `ROLLED_BACK` | | ☐ | | |

---

## Fase 3 — MEDIUM (Reliability & UX)

### 3.1 Lock Release on Failure (PST-07)

**Lokasi Target:**
- `controllers/FollowUp.php:10616-10697` — rollback preproc master
- `controllers/FollowUp.php:10697-10793` — rollback preproc detail
- `controllers/FollowUp.php:10793-10889` — rollback postproc master
- `controllers/FollowUp.php:10889-11123` — rollback postproc detail

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 3.1a | Audit tiap code path rollback | Review 4 rollback region apakah semua stock lock dilepas | | ☐ | | |
| 3.1b | Tambah `finally` cleanup | `FollowUp.php:doFollowup()` — try-catch-finally, di `finally` lepas lock apapun statusnya | | ☐ | | |

### 3.2 Timeout Auto-Rollback (TPC-07)

**Lokasi Target:**
- `controllers/FollowUp.php:4367` — `doFollowup()`: track start time

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 3.2a | Track session start | `FollowUp.php:4367` — simpan `$_SESSION['conversion_start'] = time()` | | ☐ | | |
| 3.2b | Cek timeout di setiap action | `FollowUp.php` — sebelum eksekusi, cek jika `time() - start > 1800` (30 menit) | | ☐ | | |
| 3.2c | Auto-rollback + notifikasi | Jika timeout, panggil rollback dengan system user, notifikasi user | | ☐ | | |

### 3.3 Systematic Rejection (QU-04)

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 3.3a | Tolak konversi tanpa audit trail | Guard di `doFollowup()`: jika audit_log kosong untuk transaksi ini, tolak | | ☐ | | |
| 3.3b | Tolak rollback tanpa approval | Guard di `doRevert()`: jika tidak ada approval spec untuk rollback, tolak | | ☐ | | |

### 3.4 Error Logging (MT-02)

| Sub | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:---:|------|---------------|:---:|:------:|:-------:|---------|
| 3.4a | Standardized error handler | Buat wrapper try-catch di `doFollowup()` yang catat file, baris, timestamp, stack trace, fase gagal | | ☐ | | |

---

## Fase 4 — LOW (Optimization & Testing)

| No | Item | Detail Lokasi | PIC | Status | Selesai | Catatan |
|:--:|------|---------------|:---:|:------:|:-------:|---------|
| 4.1 | Automated test suite | Test critical path: validasi open doc, stok parent, konversi sukses, rollback, SoD | | ☐ | | |
| 4.2 | Performance: batch 50+ varian < 10 detik | `FollowUp.php:10616` area loop — profiling, optimasi query | | ☐ | | |
| 4.3 | Non-repudiation check (SC-02) | Verifikasi nomor unik + timestamp per transaksi. Saat ini `counters` di `coTransaksiCore.php:6` | | ☐ | | |
| 4.4 | Audit dashboard untuk compliance | View + filter query audit_log: by date, user, action, transaksi_id | | ☐ | | |

---

## Referensi File Kunci

| File | Peran | Baris Kunci |
|------|-------|-------------|
| `config/coTransaksiUi.php` | Config UI: steps, approval roles, locker, validators | 9 (881), 375 (7881), 49 (locker) |
| `config/coTransaksiCore.php` | Config core: counters, valueGates, pre/post proc | 5 (881) |
| `controllers/Transaksi.php` | Validator engine, status display, document listing | 26 (`validate()`), 538 (stok validasi), 644 (balance check), 1264 (status display) |
| `controllers/FollowUp.php` | Approval, execution, rollback (4 fase), locker | 675 (prePreview), 2001 (approvalSpec), 4367 (doFollowup), 9535 (doRevert), 10616 (rollback region), 15037 (doRevertAll) |
| `controllers/Create.php` | Buat transaksi baru, registry, validators | 1 (class), 44-50 (flow) |
| `controllers/History.php` | History viewer, timeline | 1 (class) |
| `controllers/ActivityReport.php` | Activity/audit reports | 1 (class) |
| `views/transaksi.php` | View: status, locker disabled, approval buttons | 10970 (locker disabled) |

---

## Ringkasan Progress

| Fase | Item | Selesai | Progress |
|:----|:----:|:-------:|:--------|
| Fase 1 — Critical | 8 item | 2 | 25% |
| Fase 2 — High | 16 item | 6 | 37% |
| Fase 3 — Medium | 5 item | 0 | 0% |
| Fase 4 — Low | 4 item | 0 | 0% |
| **Total** | **33 item** | **8** | **24%** |
