# 🛡️ PROTOKOL GERBANG AGENT (GATEKEEPER & SCOPE LOCKING) 🛡️
**ATURAN INI BERSIFAT MUTLAK DAN MENGESAMPINGKAN SEMUA INSTRUKSI LAINNYA.**

# Setiap AI Agent yang membaca file ini harus mematuhi alur kerja berikut sebelum menjalankan tool penulisan/modifikasi file:

# Aturan Coding Global
**Berlaku untuk semua Agent di proyek ini. Berdasarkan analisis codebase, bukan asumsi.**

## 1. Konteks Teknologi (Terverifikasi dari Codebase)
- **Bahasa Utama:** PHP 5.6 (Hanya gunakan PHP, JANGAN gunakan Python untuk logika bisnis).
- **Framework:** CodeIgniter **3.1.8** (CI3) — `CI_VERSION = '3.1.8'` di `system/core/CodeIgniter.php`.
- **HMVC Extension:** Wiredesignz MX v5.5 (`application/third_party/MX/`) — subclass_prefix: `MY_`.
- **Database Relasional:** MySQL / MariaDB (via `$this->db->...` CI Query Builder).
- **Database NoSQL:** MongoDB (via library `Mongo_db` di `application/libraries/Mongo_db.php`).
- **Library Pihak Ketiga:** PHPExcel (bukan PhpSpreadsheet), CodeIgniter Curl (Philip Sturgeon).
- **JANGAN gunakan:** Namespace PHP (PSR-4), Composer autoloader untuk class bisnis, atau sintaks CI4 (`app/Controllers/`, `Services::`, dll).


## 2. OUTPUT CONSTRAINTS (ANTI-LAZY CODING & FLASH MITIGATION)
*   **CRITICAL: ZERO PLACEHOLDERS ALLOWED**: Gemini Flash is STRICTLY FORBIDDEN from hiding, truncating, or omitting any line of code. Do NOT use `// ...`, `/* existing code */`, or `// TODO`.
*   **MANDATORY COMPLETE REWRITE**: You must output the entire function from the structural opening bracket `{` to the closing bracket `}`. If a file is under 300 lines, rewrite the WHOLE file.
*   **TOKEN PRE-ALLOCATION RULE**: Prioritize code generation over explanations. If you run out of tokens, stop exactly at a valid syntax boundary, do not rush by omitting inner logic.
*   **EXPLICIT CODE BOUNDARIES**: Every code output must be wrapped in markdown blocks AND started with a comment: `// START OF COMPLETE REPEATED LOGIC` and ended with `// END OF COMPLETE REPEATED LOGIC`.
### 2.1 Struktur HMVC Modul
```
application/
├── core/              # MY_Loader.php, MY_Router.php (extend MX)
├── config/            # config.php, database.php, routes.php
├── controllers/       # Controller non-modul
├── helpers/           # he_*_helper.php (custom helpers)
├── libraries/         # Library custom (Layout, Curl, Mongo_db, PHPExcel, dll)
├── models/
│   └── Coms/          # Model bisnis — prefix Com* (extends CI_Model)
├── modules/
│   └── [nama_modul]/
│       ├── config/    # coTransaksiCore.php, coTransaksiUi.php, coTransaksiLayout.php, coTransaksiValues.php
│       └── controllers/
│           ├── Modul_Controller.php   # Base controller modul (extends MX_Controller)
│           ├── _shoppingCart.php      # extends Modul_Controller
│           ├── _processSelect*.php    # extends Modul_Controller
│           ├── _selectorItem.php      # extends Modul_Controller
│           ├── Create.php             # extends Modul_Controller
│           ├── FollowUp.php           # extends Modul_Controller
│           └── ...
├── third_party/MX/    # Wiredesignz HMVC
└── views/
```

### 2.2 Controller Hierarchy
```
CI_Controller (system/core/Controller.php)
  └── MX_Controller (third_party/MX/Controller.php)
      └── Modul_Controller (modules/[modul]/controllers/Modul_Controller.php)
          └── _shoppingCart, _processSelect*, Create, FollowUp, dll
```

### 2.3 Konvensi Penamaan File Controller (per Modul)
| Prefix | Peran |
|--------|-------|
| `Modul_Controller.php` | Base controller — session validation, load 4 config |
| `_shoppingCart.php` | Cart management + stock locker hold/active |
| `_processSelect*.php` | Add/edit/remove item + hold stock |
| `_selectorItem.php` | Product/supplies picker modal |
| `_processPihak*.php` | Party (customer/supplier) selector |
| `Create.php` | Create transaction (draft) |
| `FollowUp.php` / `__FollowUp.php` | Approval / follow-up |
| `ActivityReport.php` | Transaction report |
| `Printing.php` | Print document |
| `Transaksi.php` | Transaction list |

### 2.4 Konfigurasi Modul (4 Config Wajib)
| File | Isi |
|------|-----|
| `coTransaksiCore.php` | Gateway mapping, component (Com*) registration, FIFO |
| `coTransaksiUi.php` | Step definitions, UI labels, form fields |
| `coTransaksiLayout.php` | Table columns, layout rendering |
| `coTransaksiValues.php` | Value mapping, calculation rules |

## 3. Aturan Coding

### 3.1 Keamanan
- Semua query database WAJIB menggunakan **Query Binding** (`$this->db->query($sql, $binds)`) atau **Query Builder** (`$this->db->where()->get()`).
- JANGAN gunakan query mentah (raw string) tanpa binding.
- **Pengecualian yang ada:** Beberapa `UPDATE transaksi SET indexing_*` di modul `produksi` menggunakan raw string untuk JSON blob — ini technical debt, JANGAN ditiru di kode baru.

### 3.2 Model Pattern
- Model bisnis prefix `Com*` extends `CI_Model`, berlokasi di `application/models/Coms/`.
- Load dengan: `$this->load->model("Coms/ComLockerStockDualWrite");` lalu `$dw = new ComLockerStockDualWrite();`
- Dual-write stock locker **WAJIB** lewat `ComLockerStockDualWrite` — bukan tulis manual ke 2 tabel.

### 3.3 Helper Pattern
- Custom helper prefix `he_` di `application/helpers/`.
- Load dengan: `$this->load->helper("he_url");`
- Helper pairs di `application/helpers/Pairs/` — format `he_cek_*_helper.php`, `he_pair_*_helper.php`.
- Penamaan file WAJIB berakhiran `_helper.php` (konvensi CI3).

### 3.4 Transaksi Database
- Selalu gunakan `$this->db->trans_start()` dan `$this->db->trans_complete()` untuk wrapping operasi multi-query.
- JANGAN manual `BEGIN`/`COMMIT`/`ROLLBACK`.

### 3.5 Komentar & Komunikasi
- Komentar kode berbahasa Indonesia pada logika yang kompleks.
- Langsung ke kode — jangan penjelasan teori panjang.
- Jika instruksi kurang jelas atau berpotensi merusak struktur database, tanyakan dulu sebelum menulis kode.

### 3.6 PHP 5.6 Compatibility (JANGAN Gunakan)
- JANGAN gunakan: `...` spread operator, null coalescing `??`, anonymous classes, return type declarations, scalar type hints, `match` expression, named arguments.
- Gunakan: `isset($x) ? $x : $default` (bukan `$x ?? $default`).
- Gunakan: `array()` syntax (bukan `[]` short array — meskipun beberapa kode baru sudah pakai, tetap pakai `array()` untuk konsistensi).
- Gunakan: `function($x) { ... }` untuk closure (bukan arrow function `fn($x) => ...`).

- jangan pernah menawarkan perbaikan, tanpa diminta. nanti saya akan menginstruksikan perbaikan apa yang harus di lakukan

### 3.7 Konsistensi Data Sesi (`main_elements`) saat Transisi Modul
- Saat membuat atau memodifikasi transisi antar-langkah/modul transaksi di file `FollowUp.php` (atau controller sejenis), Agent **WAJIB** memastikan array `main_elements` ikut disalin dari sesi lama (`$oldCode`) ke sesi baru (`$cCode`). Hal ini penting agar elemen formulir bawaan (seperti pilihan gudang default) tidak hilang.
- Gunakan penulisan aman yang kompatibel dengan PHP 5.6:
  `"main_elements" => isset($_SESSION[$oldCode]['main_elements']) ? $_SESSION[$oldCode]['main_elements'] : array(),`

### 3.8 Validasi Awal Proses (Early Validation Pattern)
- Agent **WAJIB** menempatkan pemeriksaan validitas data/state di bagian awal fungsi transaksi (fail-fast) sebelum menjalankan query penulisan database, transaksi DB (`$this->db->trans_start()`), atau pembentukan struktur accounting.
- **Daftar Validasi yang Disarankan di Awal Proses:**
  1. **Validasi Sesi & Parameter URL:** Periksa kecocokan `bookingNumber`, `stepCode`, serta segmen-segmen URL transaksi di session.
  2. **Validasi Indikasi Transaksi Ganda (Locker Check):** Lakukan query lock pada `MdlLockerTransaksi` (state='hold', jumlah='1', oleh_id=my_id()) untuk memvalidasi bahwa lock aktif masih dipegang oleh user sebelum proses berjalan.
  3. **Validasi Relasi Transaksi Induk:** Periksa apakah transaksi induk/referensi (seperti SO atau Request) tidak dalam status reject/cancel (`trash_4 = 1`).
  4. **Validasi Qty Valid (Item State Check):** Periksa apakah barang-barang dalam transaksi masih memiliki jumlah yang valid (`valid_qty > 0`) dan belum diproses oleh alur otorisasi paralel lain.

### 3.9 Pola Sesi Mobile / Tablet Scanner (Session Stability Pattern)
Berlaku untuk **semua modul transaksi** yang memiliki akses via perangkat mobile/tablet scanner (fungsi `followupDariHp()` atau sejenisnya).

#### 3.9.1 Larangan Penggunaan `<iframe>` untuk Inisiasi Sesi Scanner
- **DILARANG** menggunakan tag `<iframe>` tersembunyi untuk memanggil `createSimpleSessionLogin`, `forceMobile`, atau endpoint sesi lainnya dari halaman yang diakses tablet.
- **Alasan:** Browser Apple Safari (iOS/iPadOS) menerapkan ITP (*Intelligent Tracking Prevention*) yang **memblokir cookie PHP (`PHPSESSID`) di dalam iframe** sebagai third-party context, sehingga sesi tidak terbentuk dengan benar.
- **Solusi WAJIB:** Gunakan redirect langsung (`location.href`) di jendela utama dengan pola redirect berantai:
  ```
  followupDariHp (ismob=1)
      ↓ redirect (bukan iframe)
  createSimpleSessionLogin  ← hanya jika $_SESSION['login'] belum ada
      ↓ via parameter goto
  forceMobile               ← hanya jika forceMobile belum diset
      ↓ via parameter goto
  followupPrePreview        ← tujuan akhir, sesi transaksi dibangun dari DB
  ```

#### 3.9.2 Implementasi Redirect Berantai di `followupDariHp()`
Pola standar yang **WAJIB** diikuti di semua modul yang memiliki fungsi `followupDariHp()`:
```php
if ($ismob == 1) {
    $finalUrl = MODUL_PATH . "FollowUp/followupPrePreview/$trjenis/$transaksiID_reference/$stepNum/$stepNumCurrent?ismob=1";

    if (!isset($_SESSION['login'])) {
        // Langkah 1: buat sesi login dulu
        $gotoAfterForceMobile = base_url() . "auth/Login/forceMobile?forceMobile=1&goto=" . urlencode($finalUrl);
        $data = array('id' => '555', 'nama_login' => 'John Doe', 'jenis' => 'scaner',
                      'cabang_id' => my_cabang_id(), 'gudang_id' => my_gudang_id());
        $queryString = http_build_query($data);
        $CreateSessionLogin = base_url() . "auth/Login/createSimpleSessionLogin?" . $queryString . "&goto=" . urlencode($gotoAfterForceMobile);
        echo "<script>location.href='" . $CreateSessionLogin . "';</script>";
    }
    elseif (!isset($_SESSION['login']['forceMobile']) || $_SESSION['login']['forceMobile'] != 1) {
        // Langkah 2: aktifkan mode mobile
        $forceMobileUrl = base_url() . "auth/Login/forceMobile?forceMobile=1&goto=" . urlencode($finalUrl);
        echo "<script>location.href='" . $forceMobileUrl . "';</script>";
    }
    else {
        // Langkah 3: semua siap, langsung ke tujuan akhir
        echo "<script>location.href='" . $finalUrl . "';</script>";
    }
}
```

#### 3.9.3 Dukungan Parameter `goto` di `auth/Login`
- Fungsi `forceMobile()` dan `createSimpleSessionLogin()` di `application/modules/auth/controllers/Login.php` **WAJIB** mendukung parameter `goto`.
- Jika `$_GET['goto']` ada dan tidak kosong, lakukan `header("Location: ...")` dan `exit()` setelah menyelesaikan tugasnya.
- Ini sudah diimplementasikan — **JANGAN dihapus atau diubah tanpa pertimbangan**.

#### 3.9.4 Penanganan Sesi Habis (Session Expired) untuk Scanner
- Fungsi `gotoLogin()` di `application/helpers/he_misc_helper.php` **WAJIB** mendeteksi request dari scanner sebelum melakukan redirect ke halaman login biasa.
- Deteksi scanner menggunakan 4 kondisi (OR):
  1. `$_GET['ismob'] == 1`
  2. `HTTP_REFERER` mengandung string `followupDariHp`
  3. `HTTP_REFERER` mengandung string `followupPreviewMobile`
  4. `$_SESSION['login']['jenis'] == 'scaner'`
- Jika terdeteksi sebagai scanner: **tampilkan halaman HTML "Sesi Habis"** dengan tombol "Mulai Ulang Sesi" — **BUKAN redirect ke form login umum**.
- Halaman sesi habis **TIDAK BOLEH** memiliki countdown otomatis — user yang mengontrol kapan menekan tombol.
- Saat tombol ditekan, alur kembali ke `followupDariHp()` dan redirect berantai (3.9.2) akan membangun ulang sesi dari database secara otomatis.

#### 3.9.5 Modul yang Terdampak
Rule ini berlaku untuk **semua** modul berikut yang memiliki fungsi `followupDariHp()` atau akses scanner sejenis:
- `distribusifg`, `distribusifg_non_paket`, `distribusifgproject`
- `distribusijasa`, `distribusisupplies`, `distribusisuppliesproject`
- `penerimaan`, `penerimaanprojek`
- `inputstok`, `inputstokunit`
- Semua modul lain yang menambahkan akses scanner di masa depan

### 3.10 Pola Pengunci Transaksi Ganda (Locker Transaksi)
Berlaku untuk memastikan transaksi penting tidak diproses secara paralel oleh pengguna lain di sesi lain (concurrency control).

#### 3.10.1 Preservasi Lock Transaksi Saat Login Baru
- Locker transaksi (`state = 'hold'`, `jumlah = '1'`) **TIDAK BOLEH** dilepas otomatis jika user yang memiliki lock tersebut melakukan login baru di browser/perangkat lain (karena ID user masih sama).
- Pemanggilan `$lls->normalisasiStok()` saat login manual diatur agar default-nya tidak membersihkan hold locker transaksi (`$lls->normalisasiStok(false)`).

#### 3.10.2 Pelepasan Lock Transaksi Secara Sadar (Logout)
- Ketika user secara sadar menekan tombol Logout, seluruh hold locker transaksi milik user tersebut **WAJIB** segera dilepas/dibersihkan.
- Di dalam controller `Login::authLogout()`, panggil `$lls->normalisasiStok(true)` agar lock transaksi yang menggantung langsung dihapus dari database.
- Pembersihan berkala melalui scheduler/cron job otomatis tetap memanggil `normalisasiStok(true)` untuk membersihkan lock dari petugas yang benar-benar tidak aktif.

#### 3.10.3 Mekanisme Ambil Alih Transaksi (Petugas Idle)
- Jika transaksi sedang dikunci oleh user lain, sistem **WAJIB** memblokir akses dan menampilkan halaman interaktif **"Transaksi Terkunci"** dengan informasi petugas aktif (Nama, ID, IP Address, Perangkat, dan Waktu Terakhir Aktif).
- **Syarat Ambil Alih**: Jika petugas aktif terdeteksi tidak aktif (idle) selama **minimal 5 menit**, tampilkan tombol **"Ambil Alih Transaksi (Petugas Idle)"** dengan parameter URL `?forceRetakeLock=1`.
- Jika diklik, sistem melepaskan lock petugas lama (`jumlah = 0` via library `ComLockerTransaksi`) dan melakukan redirect bersih agar user baru dapat memproses transaksi tersebut.
- Jika kurang dari 5 menit, tombol ambil alih wajib di-disable untuk menjaga pekerjaan petugas pertama.

### 3.11 Pola Penyimpanan Draf Transaksi Global (Global Transaction Draft Pattern)
Berlaku untuk seluruh modul transaksi multi-langkah yang memerlukan penyimpanan input sementara pengguna secara berkala (auto-save).

#### 3.11.1 Sentralisasi Penyimpanan Draf (NoSQL MongoDB)
- Penyimpanan draf belanja/transaksi sementara wajib menggunakan MongoDB (bukan tabel relational MySQL transaksional) untuk menghindari beban performa server dan menjaga skema dinamis.
- Endpoint penyimpanan draf diletakkan pada level base controller (`Modul_Controller::saveDraftAjax()`) agar dapat diwarisi dan diakses secara AJAX oleh seluruh sub-controller modul (`_shoppingCart`, `Create`, dll).

#### 3.11.2 Hak Akses & Keamanan Draf (Draft Authorization Check)
- Draf yang disimpan wajib mencantumkan key pemilik draf (`user_id` dan `session_code`).
- Pemulihan (*Restore*) dan Penghapusan (*Delete*) draf hanya diperbolehkan jika pemilik draf adalah pengguna aktif yang sedang login (`user_id === my_id()`). Pengguna lain dilarang keras memulihkan draf milik pengguna lain demi keamanan transaksi.
- Jika terjadi pengambilalihan kunci transaksi resmi (*Retake Lock*) oleh Supervisor setelah petugas pertama idle minimal 5 menit, kepemilikan draf dipindahkan ke Supervisor aktif dan tindakan tersebut dicatat dalam log audit MongoDB secara rinci.

#### 3.11.3 Pembersihan Draf Usang (Cleanup Policy)
- Draf bersifat sementara. Scheduler / Cron job otomatis berhak melakukan pembersihan (*cleanup*) draf yang terdeteksi usang (berumur lebih dari 24 jam tanpa aktivitas perubahan status) demi efisiensi kapasitas database.

---

### 3.12 Aturan Pengelolaan Sesi & Cookie CI3 (Session & Cookie Management Rules)
1. **Penghapusan Cookie Session (`authLogout`):**
   - Saat menghapus cookie cadangan (seperti `uprop`, `uid`, `pwd`), **Wajib** menggunakan waktu lampau `time() - 3600`, tentukan path `'/'`, dan hilangkan dari superglobal `$_COOKIE`:
     ```php
     setcookie("uprop", "", time() - 3600, "/");
     unset($_COOKIE['uprop']);
     ```
   - *Jangan pernah* menggunakan `setcookie("uprop", NULL, time())` tanpa path, karena cookie akan tetap ada di browser dan menyebabkan *zombie session*.

2. **Validasi di Depan (*Upfront Validation*) pada Cookie Restoration (`auth/Login/index`):**
   - Sebelum membangkitkan session dari cookie `uprop` dan melakukan `redirect(base_url())`, **Wajib** memvalidasi keberadaan `id` user dan status keaktifan user di database.
   - Jika cookie rusak atau user sudah dinonaktifkan/logout, langsung musnahkan cookie di depan dan tampilkan form login biasa (jangan di-redirect ke `base_url()` / pilih cabang).

3. **Strict Guard pada Constructor Controller:**
   - Semua controller utama (termasuk controller pilih cabang seperti `Welcome.php`) wajib mengecek `$this->session->login['id']` pada `__construct()`. Jika ID kosong, langsung alihkan pengguna ke `gotoLogin()`.

---

### 3.13 Validasi Ketersediaan Saldo Riil terhadap Locker (Anti-Overselling & Race-Condition)
1. **Kewajiban Validasi Logika Saldo/Stok:**
   - Setiap kali Agent membuat atau memodifikasi modul yang menambahkan barang ke keranjang/draf transaksi (proses *checkout*, *booking*, dsb), **WAJIB** hukumnya menyertakan *Early Validation* untuk memeriksa ketersediaan saldo fisik.
   - Rumus logika validasi yang wajib diterapkan sebelum *query insert/update* ke keranjang/transaksi adalah:
     ```
     Kuantitas yang Direquest <= (Saldo Riil - Total Saldo Locker Aktif di DB)
     ```
   - **Tujuan:** Mencegah terjadinya *overselling* (stok minus) di mana sistem mengizinkan *user* untuk mereservasi atau menjual barang yang secara riil sudah habis karena sedang di-*hold* (dikunci) oleh transaksi atau pengguna lain.
   - Jika validasi gagal (kuantitas *request* melebihi saldo efektif), sistem **WAJIB** menolak eksekusi dan mengembalikan pesan *error* kepada pengguna (contoh: "Stok tidak mencukupi, sebagian stok sedang di-hold transaksi lain").
   - Aturan ini berlaku universal di semua entitas kuantitatif aplikasi (stok persediaan, saldo rekening koran, limit, dll).
2. **Transaksi Biaya Berpajak:**
   - Seluruh transaksi biaya yang mengenakan pajak **WAJIB** memiliki pihak / *supplier* yang terdaftar secara sah.

---

### 3.14 Aturan Parameterisasi Model & Service (ISO/IEC 25010 & ISO 27001)
1. **Strict No-Global-State di Models/Services:**
   - Dilarang keras mengakses variabel superglobal HTTP (`$_SESSION`, `$_POST`, `$_GET`, `$_REQUEST`, `$_COOKIE`) secara langsung di dalam berkas `Model` (`application/models/Coms/` atau `Mdls/`).
2. **Explicit Parameter Passing (DTO / Structured Array):**
   - Seluruh data transaksi wajib dikirim secara **eksplisit** melalui parameter fungsi oleh Controller (contoh: `createSalesOrder(array $orderHeader, array $orderItems, $jenisTr)`).
3. **Universal Reusability & Pure Testability:**
   - Model/Domain Service harus bersifat murni (*pure domain logic*) sehingga dapat diuji via CLI, dipanggil oleh Background Queue Worker, maupun REST API tanpa ketergantungan pada sesi web browser.

---

### 3.15 Validasi Cabang Transaksi Multi-Step
1. **Pola Pengamanan Cabang:** Untuk mencegah terjadinya *race condition* atau pemrosesan data cabang yang salah akibat penggunaan multi-tab browser, setiap transaksi multi-step wajib divalidasi keaktifan cabangnya menggunakan helper **`validate_cabang_transaksi()`**.
2. **Perilaku Penolakan:** Jika ID cabang transaksi (dalam session `$cCode`) terdeteksi berbeda dengan ID login cabang user (`my_cabang_id()`), transaksi akan ditolak menggunakan SweetAlert merah, dihentikan (`die()`), dan dialihkan langsung kembali ke halaman dashboard utama (`base_url()`).

---

### 3.16 Aturan Keselamatan Frontend (Iframe `#result` Navigation Pattern)
Berlaku untuk semua modul yang menggunakan arsitektur iframe `#result` sebagai transport layer antar-aksi:

#### 3.16.1 URL Query Separator Wajib Smart-Detect (`?` vs `&`)
Pada template HTML dengan placeholder `{jenisTr}`, URL yang terbentuk bisa saja sudah mengandung query string dari CI3 routing (contoh: `582?gr=cGVuanVhbGFu`). Menambahkan parameter tambahan dengan tanda `?` secara hardcode menyebabkan URL menjadi rusak (`582?gr=cGVuanVhbGFu?description=...`), mengakibatkan silent failure penyimpanan data.
**Pola WAJIB:**
```javascript
// WAJIB — pola yang benar
var baseUrl = '{base}{modul}/Transaksi/validate/{jenisTr}';
var sep = (baseUrl.indexOf('?') !== -1 ? '&' : '?');
var extra = (val !== undefined && val !== '' ? sep + 'key=' + encodeURIComponent(val) : '');
document.getElementById('result').src = baseUrl + extra;

// DILARANG — pola yang salah (hardcoded '?')
var extra = '?key=' + encodeURIComponent(val); // RENTAN URL GANDA '?'
document.getElementById('result').src = baseUrl + extra;
```

#### 3.16.2 Pola Penyimpanan Catatan/Note via Validate (iPad/Safari-Safe)
Di Safari iOS/iPadOS, event `onblur` pada `<textarea>` tidak selalu ter-trigger sebelum `click` pada tombol submit. Gunakan **Three-Layer Note Save Pattern**:
- **Layer 1:** Textarea wajib memiliki ID dan name eksplisit (`id="main_description_input" name="description"`).
- **Layer 2:** Tombol submit (`btnProcess`) WAJIB membawa nilai catatan langsung di URL validate:
  ```javascript
  var dVal = document.getElementById('main_description_input') ? document.getElementById('main_description_input').value : '';
  var baseUrl = '{base}{modul}/Transaksi/validate/{jenisTr}';
  var sep = (baseUrl.indexOf('?') !== -1 ? '&' : '?');
  var extra = (dVal !== '' ? sep + 'description=' + encodeURIComponent(dVal) : '');
  document.getElementById('result').src = baseUrl + extra;
  ```
- **Layer 3:** PHP `Transaksi::validate()` WAJIB membaca `$_REQUEST['description']` di awal sebelum proses bisnis dimulai.

---

### 3.17 Format Standar UI/UX Kolom Tabel Kas & Pembayaran
Semua tampilan tabel yang berkaitan dengan arus kas wajib menyajikan kolom informasi sebagai berikut:
1. **Penerimaan Kas:**
   - **Dibuat oleh:** Penagihan (nama invoicing)
   - **Dibayar oleh:** Nama konsumen
   - **Diterima oleh:** Nama kasir
2. **Pembayaran Hutang:**
   - **Dibuat oleh:** Nama pembelian
   - **Diserahkan oleh:** Nama kasir
   - **Diterima oleh:** Nama supplier / vendor

---

### 3.18 Kinerja Database & Optimasi Query (SARGability & Indexing)
1. **Anti-Fungsi pada Kolom WHERE (SARGability):**
   - Dilarang membungkus kolom database menggunakan fungsi (seperti `BINARY()`, `LOWER()`, `DATE()`, dll.) di dalam klausa `WHERE` karena mematikan fungsi indeks (Full Table Scan).
   - Jika butuh pencarian case-sensitive, sesuaikan *collation* kolom tabel (misal `utf8mb4_bin`).
2. **Anti-OR Lintas Tabel:**
   - Hindari penggabungan kondisi `OR` yang mencakup kolom dari tabel berbeda dalam satu kueri `JOIN`. Gunakan operator **`UNION`** untuk memisahkan pencarian ke sub-query terindeks.
3. **Klausul Indexing MySQL (Equality vs Inequality):**
   - **Equality (`=`):** Operator optimal (`ref`/`const`). Mendukung kelanjutan pembacaan kolom composite index berikutnya.
   - **Inequality (`!=`, `<>`, `>`, `<`, `NOT IN`):** Memutus rantai composite index atau memicu full table scan.
     - Ubah `!=` menjadi `IN (...)` jika variasi data sedikit.
     - Ubah `NOT IN` menjadi `LEFT JOIN ... WHERE tabel2.id IS NULL`.
   - **Klausul `WHERE IN`:** Tidak memutus rantai composite index (tetap jaga jumlah item di dalam `IN` agar tidak mencapai ribuan).
   - **Aturan Posisi Range:** Kolom yang menggunakan operator range (`>`, `<`, `>=`, `<=`) wajib diletakkan di **urutan paling akhir** pada composite index.
   - **Validasi Kinerja:** Selalu uji kueri menggunakan perintah `EXPLAIN` (pastikan tipe bukan `ALL` dan `key` bukan `NULL`).

---

### 3.19 Presisi Finansial & Pencegahan Bug Floating-Point (MariaDB & PHP 5.6)
1. **Tingkat Database (MariaDB 10):**
   - Seluruh kolom yang menyimpan nilai uang, harga, DPP, PPN, dan tagihan wajib bertipe **`DECIMAL(15,2)`** (bukan `FLOAT` atau `DOUBLE`) untuk mencegah pembulatan biner tak presisi (`29999.9999999990`).
2. **Tingkat Aplikasi (PHP 5.6):**
   - Dilarang menggunakan operator matematika dasar (`+`, `-`, `*`, `/`) untuk angka finansial.
   - **WAJIB** menggunakan fungsi **BC Math** (`bcadd()`, `bcsub()`, `bcmul()`, `bcdiv()`, `bccomp()`) dengan parameter presisi desimal:
     ```php
     $total_tagihan = bcadd($dpp, $ppn, 2);
     ```
3. **Tampilan Frontend:**
   - Gunakan `number_format($tagihan, 0, ',', '.')` untuk memformat tampilan Rupiah ke user.

---

### 3.20 Protokol Caching Redis Terpusat (Centralized Caching)
1. **Konfigurasi:** Terpusat di `application/config/redis.php` (timeout maksimal 1.5 detik).
2. **Zero-Config Prefixing:** Prefix cache otomatis berbasis `[ENVIRONMENT]:[NAMA_DATABASE]:` untuk isolasi multi-aplikasi.
3. **Proteksi Server Demo:** Jika domain diawali `demo.mayagrahakencana.com`, status `ENVIRONMENT` dipaksa menjadi `development`.
4. **Graceful Degradation (Failover):** Wajib menyertakan driver cadangan `dummy`:
   ```php
   $this->load->driver('cache', array('adapter' => 'redis', 'backup' => 'dummy'));
   ```
5. **Standar Penamaan Key:**
   - Status hapus: `deleter_status_[MdlName]_[ID]`
   - Status locker: `locker_status_[MdlName]_[ID]`
   - Master data: `lookup_all_[MdlName]`
   - Data user: `[nama_data]_[USER_ID]`
6. **Kebijakan Invalidasi:** Setiap operasi mutasi (Create, Update, Delete) wajib menghapus key cache terkait via `$this->cache->delete($key)`.

---

### 3.21 Analisis Konteks Visual & Screenshot (Visual Context Rules)
Saat user menyertakan gambar atau tangkapan layar (screenshot folder, terminal, error UI, dokumen):
1. **Proaktif OCR Mental:** Baca teks, nama file, tanggal, angka, dan pesan error di gambar secara teliti tanpa menunggu instruksi manual.
2. **Korelasi & Silang-Validasi:** Hubungkan detail visual tersebut dengan kode dan log permasalahan.
3. **Skeptis Terhadap Input Fisik:** Periksa kemungkinan ketidaksesuaian berkas/input fisik sebelum menyalahkan logika kode.
4. **Soroti Temuan Visual:** Laporkan anomali visual di awal tanggapan.

---

### 3.22 Protokol Debat Kritis & Anti-Yes-Man (Critical Review Mode)
1. **Prinsip Skeptis & Devil's Advocate:**
   - Jangan langsung menyetujui ide atau rencana teknis tanpa menguji kelemahannya.
   - Uji potensi celah: *concurrency race conditions*, kegagalan performa, celah keamanan, dan beban database.
2. **Struktur Evaluasi:**
   - Sajikan: **Trade-off & Risiko**, **Alternatif Pendekatan**, dan **Kritik Logika/Celah**.
3. **Komunikasi Lugas & Pembuktian:**
   - Kritik disampaikan secara objektif dan lugas tanpa basa-basi pujian.
   - Setiap argumen teknis harus berbasis pembuktian logis atau dokumentasi resmi.

---

### 3.23 Protokol Sinkronisasi Dokumentasi Otomatis (Doc-Sync Protocol)
Setiap kali melakukan modifikasi atau penambahan fitur pada modul `application/modules/[nama_modul]/`:
1. **Sinkronisasi Dokumentasi Terpusat:**
   - Perbarui berkas modul terkait di `W:\GLOBAL_AGENT\clients\everest\erp_web\modules/[nama_modul].md`.
   - Daftarkan kode `jenisTr` baru ke `kamus_transaksi.md` dan seksi `jenisTr` berkas modul.
   - Daftarkan komponen bisnis baru (`components`) dan mutasi akuntansi jika ada perubahan.
2. **Laporan Sinkronisasi:** Laporkan berkas dokumentasi yang diperbarui di akhir respons.

---

## 4. Protokol Pembaruan Aturan & Blueprint (Rule Evolution Protocol)
- Jika Agent mendeteksi adanya pola bug sistemik atau ketidaklengkapan aturan yang berpotensi terjadi di modul lain, Agent **WAJIB** mengusulkan draf penambahan/perbaikan aturan baru pada `AGENTS.md` atau dokumen blueprint terkait (seperti `distribusi.md`) kepada Developer.
- Agent **DILARANG** memperbarui aturan atau blueprint secara otomatis tanpa persetujuan eksplisit dari Developer. Langkah pembaruan berkas aturan hanya boleh dieksekusi setelah Developer memberikan konfirmasi persetujuan ("setuju" atau sejenisnya).

---

## 5. Referensi Pustaka Aturan Terpusat (`W:\GLOBAL_AGENT\`)
Agent terhubung langsung ke basis pengetahuan dan spesifikasi arsitektur terpusat di `W:\GLOBAL_AGENT\`:
- **Peta Arsitektur Everest:** [peta_arsitektur.md](file:///W:/GLOBAL_AGENT/clients/everest/erp_web/peta_arsitektur.md)
- **Kamus Transaksi (jenisTr):** [kamus_transaksi.md](file:///W:/GLOBAL_AGENT/clients/everest/erp_web/kamus_transaksi.md)
- **Daftar Model & Komponen:** [daftar_model.md](file:///W:/GLOBAL_AGENT/clients/everest/erp_web/daftar_model.md)
- **Daftar Helper & Library:** [daftar_helper_library.md](file:///W:/GLOBAL_AGENT/clients/everest/erp_web/daftar_helper_library.md)
- **Spesifikasi Modul ERP Everest:** [modules](file:///W:/GLOBAL_AGENT/clients/everest/erp_web/modules/)
- **Aturan Global Bersama:** [global_rules.md](file:///W:/GLOBAL_AGENT/global_rules.md)
- **Standar Pemrograman PHP 5.6:** [php.md](file:///W:/GLOBAL_AGENT/language_rules/php.md)
- **SOP Solusi Floating Point:** [fix_floating_number.md](file:///W:/GLOBAL_AGENT/fix_floating_number.md)
- **Rencana & Skema Traceability 360:** [TRACEABLE_IMPLEMENTATION_PLAN.md](file:///W:/GLOBAL_AGENT/TRACEABLE_IMPLEMENTATION_PLAN.md)