# 📊 BAGAN WORKFLOW RABBITMQ: ASYNCHRONOUS STOCK OPNAME

Dokumen ini memetakan **seluruh alur kerja (End-to-End Workflow)** proses Stock Opname dari formulir web hingga penjurnalan akuntansi dan kartu stok melalui infrastruktur RabbitMQ.

---

## 1. Bagan Alur Sistem (Architecture Flowchart)

```mermaid
flowchart TD
    subgraph ZonaWeb ["1. ZONA WEB (User Interface - Respon < 1 Detik)"]
        U["Staf Gudang / User"] -->|"1. Submit Otorisasi Opname"| W["Web Controller: FollowUp.php"]
        W -->|"2. Simpan Header & Detail"| ST["Tabel Staging / Draft (so_headers_staging)"]
        W -->|"3. Catat Status Awal 'PUBLISHED'"| SH1["Tabel Shadow (rabbit_publish_shadow)"]
        W -->|"4. Kirim Pesan AMQP Persistent"| PUB["Library: Rabbitmq_publisher"]
        PUB -->|"5. Publish ke Exchange"| EX["Exchange: everest.jobs.x"]
        W -.->|"6. Respon Sukses Instan ke Layar"| U
    end

    subgraph ZonaBroker ["2. ZONA BROKER RABBITMQ (Buffer & Isolasi Beban)"]
        EX -->|"Routing Key: job.process"| Q["Queue: everest.jobs.q\n(Prefetch Count = 1)"]
        Q -.->|"Jika Error / Reject (NACK)"| DLX["DLX: everest.jobs.dlx"]
        DLX --> DLQ["DLQ: everest.jobs.failed.dlq\n(Penyelamat Data Macet)"]
    end

    subgraph ZonaWorker ["3. ZONA WORKER DAEMON (Eksekusi Latar Belakang)"]
        Q -->|"7. Tarik 1 Dokumen (Prefetch=1)"| WRK["Worker Daemon (Worker start everest)"]
        WRK -->|"8. Update Status 'PROCESSING'"| SH2["Tabel Shadow (rabbit_publish_shadow)"]
        WRK -->|"9. Eksekusi CLI Core"| CLI["CLI Controller:\nopname/Cli/process_journal"]
    end

    subgraph ZonaCore ["4. ZONA CORE DATABASE & AKUNTANSI"]
        CLI -->|"10. Baca Nilai Selisih Debet/Kredit"| TV["transaksi_values"]
        CLI -->|"11. Hapus Entri Sisa Sampah Lama"| CLN["Pembersihan Nota Duplikat"]
        CLI -->|"12. DB Transaction (Posting GL Summary)"| JUR["Tabel jurnal (GL Balance WIB)\n• Debet/Kredit Persediaan (1010030030)\n• Kredit Laba Selisih (7010150)\n• Debet Rugi Selisih (7020020)"]
        JUR -->|"13. Return JSON: {status:'success', code:200}"| CLI
    end

    subgraph ZonaAck ["5. ZONA FINALISASI & AUDIT"]
        CLI -->|"14. Kirim Output Sukses"| WRK
        WRK -->|"15. Update Status 'COMPLETED' + Response JSON"| SH3["Tabel Shadow (rabbit_publish_shadow)"]
        WRK -->|"16. Kirim Explicit Sinyal ACK"| Q
    end
```

---

## 2. Bagan Diagram Urutan Waktu (Sequence Diagram)

```mermaid
sequenceDiagram
    autonumber
    actor Staf as Staf Gudang
    participant Web as FollowUp.php
    participant Shadow as rabbit_publish_shadow
    participant Rabbit as everest.jobs.q (RabbitMQ)
    participant Worker as Worker start everest
    participant CLI as opname/Cli/process_journal
    participant DB as MySQL (jurnal, transaksi)
    participant DLQ as everest.jobs.failed.dlq

    Staf->>Web: Klik 'Submit Otorisasi 2' (Stock Opname)
    activate Web
    Web->>Shadow: Insert row baru (publish_status = 'PUBLISHED', worker_status = 'PENDING')
    Shadow-->>Web: Return shadow_id (#4)
    Web->>Rabbit: Publish pesan Persistent (transaksi_id, shadow_id, nota)
    Web-->>Staf: Respon Sukses (< 1 detik: "Dokumen berhasil disimpan dan diproses")
    deactivate Web

    Note over Staf: Staf tidak perlu menunggu posting ribuan item

    Rabbit->>Worker: Dispatch 1 pesan (Prefetch = 1)
    activate Worker
    Worker->>Shadow: Update worker_status = 'PROCESSING'
    Worker->>CLI: Eksekusi CLI: /opt/remi/php56/.../php index.php opname/Cli/process_journal 940795
    activate CLI
    
    CLI->>DB: Ambil nilai selisih fisik vs sistem dari transaksi_values
    CLI->>DB: Bersihkan baris sampah lama untuk nomer_nota yang sama
    CLI->>DB: trans_start() -> Tulis GL Summary ke tabel jurnal (WIB) -> trans_complete()
    CLI-->>Worker: Return JSON: {"status":"success","code":200,"message":"..."}
    deactivate CLI

    alt Eksekusi Sukses (code = 200)
        Worker->>Shadow: Update worker_status = 'COMPLETED', worker_at = NOW(), simpan response JSON
        Worker->>Rabbit: basic_ack (pesan resmi selesai dan dihapus dari antrean)
    else Eksekusi Gagal / Timeout
        Worker->>Shadow: Update worker_status = 'FAILED', simpan error output
        Worker->>Rabbit: basic_nack (requeue = false)
        Rabbit->>DLQ: Pesan dialihkan ke Dead Letter Queue (DLQ) agar tidak hilang
    end
    deactivate Worker
```

---

## 3. Penjelasan 2 Zona Pemisahan Beban (*Load Decoupling*)

### Zona 1: Web Interaktif (Respon Kilat)
- **Tujuan:** Pengguna tidak mengalami *browser hang*, *gateway timeout 504*, atau *white screen* saat dokumen opname berisi ribuan item.
- **Tindakan:** Cukup simpan status draf/staging dan terbitkan tiket pekerjaan ke RabbitMQ. Selesai dalam $< 1$ detik.

### Zona 2: Worker Mandiri (Pemrosesan Aman)
- **Tujuan:** Database tidak terkunci (*deadlock*) dan kalkulasi akuntansi berjalan stabil.
- **Tindakan:** Worker mengambil dokumen satu per satu (`Prefetch = 1`), menjalankan transaksi database atomik, menghitung pembukuan GL, dan memperbarui tabel pemantauan `rabbit_publish_shadow`.

---

## 4. Lokasi Berkas Terkait di Server

| Komponen | Lokasi Berkas |
| :--- | :--- |
| **Bagan & Dokumentasi Ini** | `z:\everest_29agus\application\modules\opname\WORKFLOW_RABBITMQ.md` |
| **Blueprint Universal** | `z:\rabbit_server\blueprint.md` |
| **Controller Web Submit** | `z:\everest_29agus\application\modules\opname\controllers\FollowUp.php` |
| **Library Publisher** | `z:\everest_29agus\application\libraries\Rabbitmq_publisher.php` |
| **Daemon Worker Engine** | `z:\rabbit_server\application\controllers\Worker.php` |
| **Controller CLI Eksekusi** | `z:\everest_29agus\application\modules\opname\controllers\Cli.php` |
| **Tabel Audit & Evaluasi** | Database `run_everest_modul` $\rightarrow$ tabel `rabbit_publish_shadow` |
