# Master Blueprint Design Terpadu: Arsitektur Varian ERP (Produk, Supplies, & BOM Produksi)

**Tanggal Ditulis:** 2026-07-27  
**Status:** Single Source of Truth — Master Architectural Design  
**Repository Target:** `PT. INDOSAN / Multi-Module Variant Standardization`  

---

## 📌 1. Pengantar & Ruang Lingkup Arsitektur

Dokumen ini adalah **Satu-satunya Master Blueprint Design Terpadu** yang merangkum seluruh arsitektur standar produk bervarian pada ERP. Arsitektur dibagi menjadi 3 pilar utama:
1. **Pilar 1: Core Finished Goods (Produk Utama Bervarian)**
2. **Pilar 2: Operational Supplies (Bahan Penolong Bervarian)**
3. **Pilar 3: Multi-Variant BOM (Formula Manufaktur / Produksi Bervarian)**

---

## 🏛️ PILAR 1: Core Finished Goods (Produk Utama Bervarian)

### 1.1 Master Parent-Child Entity
- **Parent Master Table:** `produk`
  - Kolom Penting: `id`, `kode`, `nama`, `has_variants` (1/0), `variant_price_mode` ('GLOBAL'/'CUSTOM').
- **Child SKU Variant Table:** `var_product_variants`
  - Kolom Penting: `id`, `produk_id` (FK), `sku`, `variant_name`, `attribute_value_ids` (JSON), `price_adjustment`.
- **Master Atribut:** `var_attributes` (Warna, Ukuran) & `var_attribute_values` (Merah, XL).

### 1.2 Session Cart Key Transformation
- MENINGGALKAN ID numerik polos (`1625`) yang menyebabkan item overwrite.
- MENGGUNAKAN Format Unik Cart Key: `variant:{produk_id}:{variant_id}`  
  *(Contoh: `variant:1625:14` atau `variant:1625:1` untuk default/sentinel).*

### 1.3 Dual-Write Stock Locker & Sentinel Pattern
- Model Terpusat: `ComLockerStockDualWrite`
- **Aturan Sentinel Stok:** Jika produk non-varian, `variant_id` diisi otomatis dengan `1` (Sentinel Default) pada `stock_locker_variant` untuk mencegah null pointer / error `WHERE variant_id=0`.
- **Dual-Write Execution:** Every inventory write updates `stock_locker` (parent aggregate) and `stock_locker_variant` (child variant breakdown) concurrently.

### 1.4 Line Items Transaction
- Tabel `transaksi_data` membawa `produk_id` (ID Induk) + `variant_id` (ID Varian) + `variant_nama`.
- DILARANG MENGISI `produk_id = 0` (Ghost Row Fix).

---

## 📦 PILAR 2: Operational Supplies (Bahan Penolong Bervarian)

### 2.1 Master Supplies Entity
- **Parent Master Table:** `produk_supplies`
  - Kolom Penting: `id`, `kode`, `nama`, `satuan`, `has_variants`.
- **Child SKU Variant Table:** `var_supplies_variants`
  - Kolom Penting: `id`, `supplies_id` (FK), `sku`, `nama`, `combination_key`, `aktif`.
- **Master Atribut Supplies:** `var_supplies_attributes` & `var_supplies_variant_values`.

### 2.2 Supplies Stock Locker & Cart Key
- **Tabel Locker Stok:** `stock_locker_supplies_variant` (`supplies_id`, `variant_id`, `jenis`, `state`, `jumlah`, `cabang_id`, `gudang_id`).
- **Format Cart Key Supplies:** `supplies:{supplies_id}:{variant_id}`.
- **Model Handler:** `ComLockerStockSuppliesDualWrite` & `MdlSuppliesVarian`.

### 2.3 Modul Transaksi Target Penyetaraan Supplies
- `biaya` (Pembelian Supplies / Biaya Penolong)
- `distribusisupplies` (Transfer Stok Supplies Antar Gudang)
- `pembelian` (Purchase Order Supplies dari Vendor)
- `produksi` & `produksiproses` (Konsumsi Supplies sebagai Bahan Penolong Produksi)
- `opname` (Stock Opname Supplies)

---

## 🏭 PILAR 3: Multi-Variant BOM (Formula Manufaktur / Produksi Bervarian)

### 3.1 Pattern *Inherit-or-Override* (Formula Induk + Mode Override Varian)

Untuk mencegah pengguna meng-input ulang formula berulang kali saat 90% varian komposisinya sama:

```
                   ┌─────────────────────────────────────────┐
                   │    FORMULA INDUK (GLOBAL BOM)           │
                   │    variant_id = 0                       │
                   │    (Default untuk semua varian)        │
                   └────────────────────┬────────────────────┘
                                        │
                         ┌──────────────┴──────────────┐
                         ▼                             ▼
         ┌───────────────────────────────┐  ┌───────────────────────────────┐
         │ VARIAN A (Merah-S)            │  │ VARIAN B (Jumbo-XL)           │
         │ [ ] Override Formula = FALSE  │  │ [x] Override Formula = TRUE   │
         │ ➔ Auto Inherit Formula Induk  │  │ ➔ Menggunakan Formula Khusus  │
         └───────────────────────────────┘  └───────────────────────────────┘
```

### 3.2 Skema Tabel Database BOM Produksi Varian

#### 1. Tabel Master BOM (`produksi_bom`)
```sql
CREATE TABLE produksi_bom (
    id INT AUTO_INCREMENT PRIMARY KEY,
    produk_id INT NOT NULL,                     -- ID Produk Induk Finished Goods
    variant_id INT NOT NULL DEFAULT 0,          -- 0 = Formula Global/Induk, >0 = Formula Khusus Varian
    nama_formula VARCHAR(255) NOT NULL,
    deskripsi TEXT,
    is_active TINYINT(1) DEFAULT 1,
    dtime DATETIME DEFAULT CURRENT_TIMESTAMP,
    oleh_id INT DEFAULT 0,
    INDEX idx_produk_variant (produk_id, variant_id)
);
```

#### 2. Tabel Rincian Bahan BOM (`produksi_bom_detail`)
```sql
CREATE TABLE produksi_bom_detail (
    id INT AUTO_INCREMENT PRIMARY KEY,
    bom_id INT NOT NULL,                        -- FK ke produksi_bom.id
    item_type ENUM('produk', 'supplies') NOT NULL DEFAULT 'produk',
    item_id INT NOT NULL,                       -- ID Produk (Bahan Baku) atau Supplies (Bahan Penolong)
    item_variant_id INT NOT NULL DEFAULT 1,     -- ID Varian Bahan (Default 1 jika non-varian)
    qty DECIMAL(24,10) NOT NULL DEFAULT 1.0,    -- Jumlah kebutuhan per 1 unit FG
    satuan VARCHAR(32) NOT NULL,
    keterangan VARCHAR(255),
    INDEX idx_bom (bom_id)
);
```

### 3.3 Auto-Resolution Algorithm saat Membuat SPK Produksi
1. Sistem mengecek **Formula Khusus Varian**: `SELECT * FROM produksi_bom WHERE produk_id = $pid AND variant_id = $vid AND is_active = 1`.
2. Jika kosong (0 rows), sistem **Fallback ke Formula Induk Global**: `SELECT * FROM produksi_bom WHERE produk_id = $pid AND variant_id = 0 AND is_active = 1`.
3. Rincian bahan baku (Produk) dan bahan penolong (Supplies) langsung ter-populate ke SPK Produksi secara otomatis.

---

## 🗺️ 4. Roadmap & Tahapan Pengerjaan Koding (Task Splitting)

| Fase | Nama Task | Ruang Lingkup Koding | Target Modul | Status |
|:---:|:---|:---|:---|:---:|
| **Fase 1** | **Core Finished Goods Varian** | Dual-write `ComLockerStockDualWrite`, Cart Key `variant:PID:VID`, QTip ViewDetails, Catalog SKU search. | 10 Modul Inventory Core | 🟢 **SELESAI (100%)** |
| **Fase 2** | **Penyetaraan Varian Supplies** | Update handler `_processSelectSupplies.php` & dual-write `ComLockerStockSuppliesDualWrite`. | `biaya`, `distribusisupplies`, `pembelian`, `opname` | 🟡 **ROADMAP (TASK 1)** |
| **Fase 3** | **Produksi BOM Bervarian** | Skema `produksi_bom` & algorithm resolution *Inherit-or-Override* BOM. | `produksi`, `produksiproses` | 🟡 **ROADMAP (TASK 2)** |

---

## 🔗 Navigasi Berkas Terkait

- 📄 **[Master Global Checklist](master-global-checklist-variant.md)** (`docs/master-global-checklist-variant.md`)
- 💻 **[Dashboard UAT Interaktif HTML](panduan-uat-manual-user.html)** (`docs/panduan-uat-manual-user.html`)
- 📘 **[Peta Visual Varian Produk Utama (HTML)](arsitektur-database-variant-visual.html)** (`docs/arsitektur-database-variant-visual.html`)
- 📦 **[Peta Visual Varian Supplies (HTML)](arsitektur-supplies-variant-visual.html)** (`docs/arsitektur-supplies-variant-visual.html`)
- 🏭 **[Visual Simulator BOM Produksi (HTML)](blueprint-varians-supplies-dan-produksi-visual.html)** (`docs/blueprint-varians-supplies-dan-produksi-visual.html`)
