# Memahami *Shadow Verification* (Pengujian Bayangan)

Memindahkan logika bisnis krusial (seperti pemotongan stok dan uang) dari kode lama ke *Engine* baru ibarat **mengganti mesin pesawat saat sedang terbang**. 

Jika kita mencabut mesin lama dan memasang mesin baru secara langsung (*Hard Cut-Over*), dan ternyata mesin baru tersebut memiliki cacat, pesawat (bisnis Anda) akan jatuh (*crash*). 

Di sinilah **Shadow Verification** berperan. Kita memasang mesin baru di samping mesin lama, membiarkan mesin baru menyala, tapi baling-balingnya **belum dihubungkan** ke pesawat. Kita hanya mengukur: *"Apakah RPM mesin baru ini sama persis dengan mesin lama?"*

---

## 1. Perbandingan Alur Kerja (Visual)

Berikut adalah diagram perbandingan antara pendekatan berisiko vs pendekatan aman (Shadow).

```mermaid
graph TD
    classDef danger fill:#ffebee,stroke:#c62828,stroke-width:2px;
    classDef safe fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
    classDef neutral fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px;

    User(["User Klik 'Simpan'"]) --> Controller["Controller (FollowUp.php)"]
    
    subgraph SV ["Shadow Verification (Aman)"]
        Controller -->|1. Jalankan Normal| OldLogic["Logika Legacy"]:::neutral
        Controller -. "2. Jalankan Mode Simulasi" .-> NewEngine["Domain Engine Baru"]:::safe
    end
    
    OldLogic -->|Tulis dan Ubah Data| DB[(Database MySQL)]
    NewEngine -. "Hanya Kalkulasi (Dry Run)" .-> ResultNew["Output Baru: Sisa 5"]
    OldLogic --> ResultOld["Output Lama: Sisa 5"]
    
    ResultOld --> Komparator{"Apakah Sama?"}
    ResultNew --> Komparator
    
    Komparator -->|Ya Identik| Lanjut["Abaikan. Transaksi Sukses"]
    Komparator -->|Tidak Ada Selisih| Log["Catat ke File Log Server!"]:::danger
```

> [!NOTE]
> Perhatikan garis putus-putus pada *Domain Engine Baru*. Itu artinya *Engine* tersebut menghitung rumus-rumusnya, tapi **tidak diizinkan menyentuh/mengubah Database MySQL**.

---

## 2. Cara Kerja Secara Teknis (Urutan Kejadian)

Diagram sekuensial di bawah ini menunjukkan apa yang terjadi di dalam server dalam hitungan milidetik.

```mermaid
sequenceDiagram
    participant C as Controller (Legacy)
    participant E as ComLockerStock Engine
    participant D as Database MySQL
    participant L as Log Server

    C->>C: User beli 2 barang (Stok Awal 10)
    
    Note over C, D: LANGKAH 1: SISTEM LAMA BEKERJA
    C->>D: UPDATE stok = 8 (10 dikurangi 2)
    D-->>C: Berhasil
    
    Note over C, E: LANGKAH 2: SHADOW VERIFICATION BERJALAN
    C->>E: Simulasi: Tolong hitung, kalau stok awal 10, diminta 2, sisa berapa?
    E-->>C: Hasil Simulasi: Sisa 8
    
    Note over C, L: LANGKAH 3: KOMPARASI
    opt Jika Hasil Berbeda (Misal Engine menjawab 9)
        C->>L: ERROR: Controller=8, Engine=9. Tolong developer cek Engine!
    end
```

---

## 3. Kenapa Mencegah *Deadlock* Database?

Jika pada Langkah 2 di atas kita membiarkan *Engine* baru ikut-ikutan melakukan perintah `UPDATE` atau `FOR UPDATE` ke tabel yang sama secara bersamaan, maka:

1. Kode lama "memegang" data barang A.
2. *Engine* baru mencoba "merebut" data barang A untuk dikunci.
3. Database MySQL akan bingung karena satu program (*script PHP*) mencoba mengunci ganda data yang sama.
4. Terjadilah **Deadlock** (Sistem menggantung selamanya/Loading muter terus).

Oleh karena itu, khusus untuk operasi mutasi data, *Shadow Verification* hanya dijalankan sebatas **Kalkulasi Angka**, bukan Eksekusi *Query*.

Setelah 2 minggu berjalan dan tidak ada log error yang masuk ke Log Server (artinya mesin baru sudah 100% identik kepintarannya dengan mesin lama), barulah kita melakukan *Hard Cut-Over*: Logika lama dihapus, dan baling-baling mesin baru dihubungkan secara permanen ke *Database*.
