> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doman.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Bus::chain() vs. Pipeline

### **Appendix A: Architectural Decision - `Bus::chain()` vs. `Pipeline`**

A key decision in this system's architecture was the choice of `Bus::chain()` with Jobs over Laravel's `Pipeline` pattern for executing sequential tasks. While both can run operations in order, they are designed for different purposes. This section clarifies why the Job Chain was chosen.

#### **Core Concepts**

* **`Bus::chain()` with Jobs (The Project Manager):** This pattern is designed for orchestrating a series of **discrete, self-contained actions**. Each "Job" is a complete task. The system ensures one job finishes before the next begins. It is ideal for long-running or heavy processes like file manipulation.

* **Analogy**: A construction project where the foundation must be built (`StampDocumentJob`) before the walls are erected (`GenerateThumbnailJob`).

* **`app(Pipeline::class)` with Pipes (The Assembly Line):** This pattern is designed for **transforming a single piece of data** through a series of steps or "Pipes". The same data object is passed from one step to the next, being modified along the way.

* **Analogy**: A car chassis moving down an assembly line, where each station adds a new part to the same object.

#### **Comparison and Justification**

| Feature              | **Bus::chain()** with Jobs                                                                                                            | **app(Pipeline::class)** with Pipes                                                                        | Why We Chose **Bus::chain()**                                                                                                                                                                                                                                                        |
| :------------------- | :------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Execution**        | **Asynchronous-first**. Can run in the background (with **database**/**redis** drivers) or immediately (**sync** driver).             | **Strictly Synchronous**. Always runs immediately.                                                         | This provides **future flexibility**. If the tasks become too slow, we can switch to a background queue without changing any application code—only an **.env** variable.                                                                                                             |
| **State**            | **Stateless between jobs**. Each job is independent and should fetch its required state from a persistent source (like the database). | **Stateful**. The same object is passed from pipe to pipe.                                                 | Our tasks are independent actions. **GenerateThumbnailJob** only needs to know that **StampDocumentJob** is *finished*, not receive data directly from it. It fetches the updated model state (**\$model->refresh()**). This is a cleaner, more robust approach for I/O-heavy tasks. |
| **Failure Handling** | **Robust**. Integrates with Laravel's queue system for retries, timeouts, and dedicated **failed()** job handlers.                    | **Basic**. Throws an exception that must be handled with a **try/catch** block around the entire pipeline. | File processing can fail for many reasons (corrupt files, server issues). The advanced error handling of the queue system is far superior for this use case.                                                                                                                         |
| **Purpose**          | Orchestrating **actions**.                                                                                                            | Transforming **data**.                                                                                     | Stamping a PDF and generating a thumbnail are heavy **actions**, not simple data transformations. The Job pattern is the semantically correct choice.                                                                                                                                |

#### **Conclusion**

For processing documents—which involves external system calls, file I/O, and potentially long execution times—`Bus::chain()` is the superior and more conventional Laravel pattern. It provides the necessary robustness, state separation, and crucial flexibility to scale from synchronous to asynchronous processing in the future.

***

### **Addendum Dokumentasi Bahasa Indonesia**

### **Lampiran A: Keputusan Arsitektur - `Bus::chain()` vs. `Pipeline`**

Sebuah keputusan kunci dalam arsitektur sistem ini adalah pemilihan `Bus::chain()` dengan Jobs dibandingkan dengan pattern `Pipeline` dari Laravel untuk mengeksekusi tugas sekuensial. Meskipun keduanya dapat menjalankan operasi secara berurutan, mereka dirancang untuk tujuan yang berbeda. Bagian ini menjelaskan mengapa Job Chain dipilih.

#### **Konsep Inti**

* **`Bus::chain()` dengan Jobs (Manajer Proyek):** Pattern ini dirancang untuk mengorkestrasi serangkaian **aksi yang terpisah dan mandiri**. Setiap "Job" adalah sebuah tugas yang utuh. Sistem memastikan satu job selesai sebelum job berikutnya dimulai. Ini ideal untuk proses yang berat atau berjalan lama seperti manipulasi file.

* **Analogi**: Proyek konstruksi di mana fondasi harus dibangun (`StampDocumentJob`) sebelum dinding didirikan (`GenerateThumbnailJob`).

* **`app(Pipeline::class)` dengan Pipes (Lini Perakitan):** Pattern ini dirancang untuk **mengubah (transformasi) sebuah data** melalui serangkaian langkah atau "Pipes". Objek data yang sama diteruskan dari satu langkah ke langkah berikutnya, dan dimodifikasi di sepanjang jalan.

* **Analogi**: Sasis mobil yang bergerak di lini perakitan, di mana setiap stasiun menambahkan bagian baru ke objek yang sama.

#### **Perbandingan dan Justifikasi**

| Fitur                    | `Bus::chain()` dengan Jobs                                                                                                                                        | `app(Pipeline::class)` dengan Pipes                                                                             | Alasan Memilih `Bus::chain()`                                                                                                                                                                                                                                                                     |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Eksekusi**             | **Asinkron-first**. Dapat berjalan di latar belakang (dengan driver `database`/`redis`) atau secara langsung (`sync` driver).                                     | **Hanya Sinkron**. Selalu berjalan secara langsung.                                                             | Ini memberikan **fleksibilitas di masa depan**. Jika tugas menjadi terlalu lambat, kita dapat beralih ke antrian latar belakang tanpa mengubah kode aplikasi sama sekali—hanya variabel di `.env`.                                                                                                |
| **State**                | **Stateless (tanpa state) antar job**. Setiap job bersifat independen dan harus mengambil state yang dibutuhkannya dari sumber yang persisten (seperti database). | **Stateful (dengan state)**. Objek yang sama diteruskan dari satu pipe ke pipe berikutnya.                      | Tugas kita adalah aksi independen. `GenerateThumbnailJob` hanya perlu tahu bahwa `StampDocumentJob` telah *selesai*, bukan menerima data langsung darinya. Ia mengambil state model yang terbaru (`$model->refresh()`). Ini adalah pendekatan yang lebih bersih dan kuat untuk tugas-tugas berat. |
| **Penanganan Kegagalan** | **Kuat**. Terintegrasi dengan sistem antrian Laravel untuk fitur coba-ulang (retry), timeout, dan handler `failed()` khusus untuk job.                            | **Dasar**. Melemparkan exception yang harus ditangani dengan blok `try/catch` yang membungkus seluruh pipeline. | Pemrosesan file bisa gagal karena banyak alasan (file korup, masalah server). Penanganan error canggih dari sistem antrian jauh lebih unggul untuk skenario ini.                                                                                                                                  |
| **Tujuan**               | Mengorkestrasi **aksi**.                                                                                                                                          | Mentransformasi **data**.                                                                                       | Memberi stempel pada PDF dan membuat thumbnail adalah **aksi** yang berat, bukan transformasi data sederhana. Pattern Job adalah pilihan yang paling tepat secara semantik.                                                                                                                       |

#### **Kesimpulan**

Untuk memproses dokumen—yang melibatkan panggilan sistem eksternal, I/O file, dan waktu eksekusi yang berpotensi lama—`Bus::chain()` adalah pattern Laravel yang lebih unggul dan konvensional. Pattern ini menyediakan kekokohan, pemisahan state, dan fleksibilitas krusial untuk beralih dari pemrosesan sinkron ke asinkron di kemudian hari.
