# 🏔️ PT. Everest - ERP Web (Global Rules)

Spesifikasi bisnis, teknologi, dan kebijakan mutasi stok untuk aplikasi ERP Web PT. Everest.

---

## 1. Aturan Bisnis & Integrasi Stok
*   **Operasi Stock Locker:**
    *   Setiap kali menulis/mengubah persediaan produk dagangan, sistem menulis langsung ke loker persediaan utama (`stock_locker`) menggunakan model/komponen **`LockerStock`**.
*   **FIFO Average Engine:**
    *   Penilaian HPP persediaan menggunakan moving average FIFO yang dievaluasi saat status transaksi menjadi `approved`.

### 1.2 Validasi Cabang Transaksi Multi-Step
*   **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()`**.
*   **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()`).

---

## 2. Struktur Database Everest
*   **`transaksi`**: Menyimpan header transaksi.
*   **`transaksi_data`**: Menyimpan rincian item belanja.
*   **`transaksi_data_registry`**: Registrasi audit log status transaksi (Hold -> Request -> Approved -> Closed).

---

## 3. Aturan Keamanan & Kinerja Query (Sangat Krusial)

### 3.1 Keamanan (Anti-SQL Injection)
*   **Wajib Query Binding / Builder:** Semua eksekusi query database wajib menggunakan **Query Binding** (`$this->db->query($sql, $binds)`) atau **Query Builder** (`$this->db->...->get()`).
*   **Dilarang Interpolasi String:** Dilarang keras melakukan penggabungan string (concatenation) atau interpolasi parameter secara langsung ke dalam raw string SQL untuk menghindari celah keamanan SQL Injection.

### 3.2 Kinerja Query (Pencegahan "Kombinasi Maut")
*   **Anti-Fungsi pada Kolom WHERE (SARGability):** Dilarang membungkus kolom database menggunakan fungsi (seperti `BINARY()`, `LOWER()`, `DATE()`, dll.) di dalam klausa `WHERE` karena akan mematikan fungsi indeks (Full Table Scan). Jika membutuhkan pencarian case-sensitive, ubah collation kolom di struktur database menjadi binary (misal `utf8mb4_bin`).
*   **Anti-OR Lintas Tabel:** Hindari penggabungan kondisi `OR` yang mencakup kolom dari tabel-tabel yang berbeda di dalam satu query `JOIN`. Gunakan operator **`UNION`** untuk memisahkan pencarian ke dalam sub-query terindeks agar performa pencarian tetap instan.
*   **Konversi JOIN yang Tepat:** Gunakan `JOIN` biasa (INNER JOIN) jika klausa `WHERE` melakukan penyaringan wajib terhadap tabel kiri/kanan. Dilarang menggunakan `RIGHT JOIN` / `LEFT JOIN` yang dipaksa menjadi `INNER JOIN` karena akan membingungkan Query Optimizer MariaDB.
