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

# Budget planner

<style>
  {`
    [class*="max-w-none"][class*="table"] {
      display: block !important;
      overflow-x: auto !important;
      max-width: 100% !important;
      width: 100% !important;
      flex-grow: 0 !important;
    }
    [class*="max-w-none"][class*="table"] > table {
      width: 100% !important;
      max-width: 100% !important;
      table-layout: fixed !important;
    }
    .mermaid {
      max-width: 100% !important;
      overflow-x: auto !important;
    }
    article svg[role="img"] {
      max-width: 100% !important;
      height: auto !important;
    }
    article img, .prose img {
      max-width: 100% !important;
      height: auto !important;
    }
    img[src*="LOGO"], img[src*="logo"] {
      max-width: 120px !important;
      max-height: 40px !important;
      width: auto !important;
      height: auto !important;
      object-fit: contain !important;
    }
    `}
</style>

***

title: "Budget Planner"
description: "Perencanaan anggaran dengan 4 periode, alokasi per kategori, monitoring real-time, variance analysis, dan alert system di SNISHOP ERP."
-----------------------------------------------------------------------------------------------------------------------------------------------------

# Budget Planner

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/finance/budget-planner.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=4df65178be7d4b85b806a18237ed6128" alt="Budget Planner" width="1920" height="1080" data-path="docs/mintlify/screenshots/finance/budget-planner.png" />

Budget Planner membantu perusahaan merencanakan dan mengontrol anggaran secara terstruktur. Sistem mendukung **4 periode budget** (weekly, monthly, quarterly, yearly), alokasi per kategori expense Indonesia, monitoring real-time dengan **alert threshold** (default 80%), dan analisis variance antara planned vs actual. Setiap kategori budget terhubung langsung dengan `FinancialRecord` untuk tracking realisasi otomatis.

## Arsitektur Budget Planner

```mermaid theme={null}
graph TB
    subgraph SETUP["Setup Budget"]
        PERIOD["Pilih Periode<br/>Weekly/Monthly/Quarterly/Yearly"]
        CAT["Pilih Kategori<br/>11 expense categories"]
        AMT["Input Planned Amount"]
        THRESH["Set Alert Threshold<br/>Default 80%"]
        DATE["Set Start & End Date"]
    end

    subgraph TRACKING["Real-Time Tracking"]
        FR["FinancialRecord<br/>Actual expenses"]
        CALC["Calculate<br/>actual_amount"]
        COMP["Compare<br/>planned vs actual"]
        ALERT["Alert System<br/>80% warning, 100% over"]
    end

    subgraph REPORTING["Reporting"]
        BVA["Budget vs Actual<br/>Report"]
        VAR["Variance Analysis<br/>Amount & percentage"]
        TREND["Trend Analysis<br/>Historical comparison"]
        EXPORT["Export<br/>PDF/Excel/CSV"]
    end

    SETUP --> TRACKING
    FR --> CALC
    CALC --> COMP
    COMP --> ALERT
    TRACKING --> REPORTING
```

## Entity Budget

### Field Budget

| Field | Tipe | Deskripsi |
| - | - | - |
| category | string | Kategori expense (11 opsi) |
| planned\_amount | number | Anggaran yang direncanakan |
| actual\_amount | number | Realisasi aktual (auto-calculated) |
| alert\_threshold | number | Threshold notifikasi (default 80%) |
| period | enum | weekly, monthly, quarterly, yearly |
| start\_date | date | Tanggal mulai periode |
| end\_date | date | Tanggal selesai periode |
| company\_id | UUID | Multi-tenant isolation |

### 4 Periode Budget

| Period | Durasi | Use Case |
| - | - | - |
| **Weekly** | 7 hari | Operational expenses, cash flow ketat |
| **Monthly** | 30 hari | Most common, salary, utilities |
| **Quarterly** | 90 hari | Project-based, seasonal |
| **Yearly** | 365 hari | Strategic budget, annual planning |

## Kategori Budget

### 11 Expense Categories (Indonesian)

| Kategori | Label Indonesia | Contoh |
| - | - | - |
| salary | Gaji | Gaji karyawan, bonus, tunjangan |
| raw\_material | Bahan Baku | Cabai, bawang, ayam, minyak |
| operational | Operasional | Listrik, air, internet, sewa |
| production\_cost | Biaya Produksi | Gas, packaging, label |
| travel | Perjalanan | Transport, hotel |
| meals | Makan | Makan karyawan, meeting |
| accommodation | Akomodasi | Sewa tempat |
| equipment | Peralatan | Alat produksi, komputer |
| office\_supplies | Perlengkapan Kantor | ATK, tinta, kertas |
| training | Pelatihan | Kursus, sertifikasi |
| other | Lainnya | Biaya lain-lain |

## Create Budget

### Step-by-Step

1. Klik **"Create Budget"**
2. Isi form:

| Field | Required | Deskripsi |
| - | - | - |
| Category | ✓ | Pilih dari 11 kategori |
| Period | ✓ | Weekly, Monthly, Quarterly, Yearly |
| Planned Amount | ✓ | Nominal anggaran |
| Alert Threshold | Opsional | Default 80% |
| Start Date | ✓ | Tanggal mulai |
| End Date | ✓ | Tanggal selesai |

3. Save budget
4. Sistem mulai track actual\_amount dari FinancialRecord

### Template dari Periode Sebelumnya

Sistem menyediakan template berdasarkan anggaran periode sebelumnya:

1. Klik **"Create from Template"**
2. Pilih periode sebelumnya
3. Sistem copy budget lama
4. Edit jika perlu
5. Save sebagai budget baru

## Monitoring Real-Time

### Dashboard Budget

| Metric | Deskripsi |
| - | - |
| Planned Amount | Anggaran yang direncanakan |
| Actual Amount | Realisasi aktual |
| Remaining | Sisa anggaran |
| Usage % | Persentase penggunaan |
| Status | OK / Warning / Over |

### Visual Indicators

```mermaid theme={null}
graph LR
    subgraph OK["OK ≤80%"]
        G["🟢 Hijau"]
    end
    subgraph WARNING["Warning 80-100%"]
        Y["🟡 Kuning"]
    end
    subgraph OVER["Over >100%"]
        R["🔴 Merah"]
    end
```

### Alert Levels

| Level | Threshold | Warna | Aksi |
| - | - | - | - |
| **OK** | ≤80% | Hijau | Lanjut, monitor |
| **Warning** | 80-100% | Kuning | Review expense, kontrol |
| **Over** | >100% | Merah | Investigasi, approve dengan caution |

### Auto-Update

`actual_amount` diupdate otomatis setiap ada `FinancialRecord` baru dengan kategori yang sama dalam periode budget.

```mermaid theme={null}
sequenceDiagram
    participant E as Expense
    participant FR as FinancialRecord
    participant B as Budget
    participant D as Dashboard

    E->>FR: Create expense (category: salary)
    FR->>B: Match category + period
    B->>B: actual_amount += expense.amount
    B->>B: Calculate usage %
    B->>D: Update dashboard
    alt usage > threshold
        B->>D: Show alert
    end
```

## Variance Analysis

### Calculation

```
Variance = actual_amount - planned_amount
Variance % = (actual_amount / planned_amount) × 100%
```

### Interpretation

| Variance | Status | Interpretasi |
| - | - | - |
| Negative | Under budget | Bagus, efisiensi |
| Zero | On budget | Sesuai rencana |
| Positive | Over budget | Perlu investigasi |

### Variance Report

| Category | Planned | Actual | Variance | Variance % | Status |
| - | - | - | - | - | - |
| Salary | Rp 25.000.000 | Rp 24.500.000 | -Rp 500.000 | 98% | OK |
| Raw Material | Rp 15.000.000 | Rp 16.200.000 | +Rp 1.200.000 | 108% | Over |
| Operational | Rp 5.000.000 | Rp 4.800.000 | -Rp 200.000 | 96% | OK |
| Marketing | Rp 3.000.000 | Rp 2.900.000 | -Rp 100.000 | 97% | OK |

## Trend Analysis

### Historical Comparison

Bandingkan budget vs actual dari beberapa periode:

| Period | Planned | Actual | Variance % |
| - | - | - | - |
| Jan 2026 | Rp 50.000.000 | Rp 48.500.000 | -3% |
| Feb 2026 | Rp 50.000.000 | Rp 52.000.000 | +4% |
| Mar 2026 | Rp 55.000.000 | Rp 54.000.000 | -2% |

### Trend Visualization

* Line chart: Planned vs Actual over time
* Bar chart: Variance per category
* Pie chart: Distribution per category

## Filter & Search

| Filter | Opsi |
| - | - |
| Period | Weekly, Monthly, Quarterly, Yearly |
| Category | 11 kategori |
| Status | OK, Warning, Over |
| Date Range | Start date - End date |

## Reporting

### Budget Summary

| Metric | Deskripsi |
| - | - |
| Total Planned | Total anggaran semua kategori |
| Total Actual | Total realisasi |
| Total Variance | Selisih total |
| Categories Over Budget | Jumlah kategori yang over |

### Category Detail

| Field | Deskripsi |
| - | - |
| Category | Nama kategori |
| Planned | Anggaran |
| Actual | Realisasi |
| Variance | Selisih |
| Usage % | Persentase |
| Status | OK/Warning/Over |

## Export

| Format | Use Case |
| - | - |
| PDF | Presentasi ke management |
| Excel | Analisis lebih lanjut |
| CSV | Integrasi sistem lain |

## Best Practices

### Planning

* Libatkan kepala departemen saat menyusun anggaran
* Gunakan data historis sebagai referensi
* Set realistic targets
* Include buffer untuk unexpected expenses

### Monitoring

* Review budget mingguan/bulanan
* Investigasi variance signifikan
* Adjust budget jika ada perubahan bisnis
* Track seasonal trends

### Control

* Enforce approval workflow untuk expense besar
* Monitor alert thresholds
* Document justification untuk over-budget
* Regular variance analysis

***

## Entity Relationship Diagram (ERD)

Berikut adalah diagram relasi antar-entity yang terlibat dalam modul Budget Planner. Relasi utama menghubungkan `Budget` dengan `TransactionCategory` (melalui field `category`) dan `FinancialRecord` (yang mereferensikan kategori yang sama sehingga `actual_amount` dapat dihitung otomatis).

```mermaid theme={null}
erDiagram
    Budget ||--o{ FinancialRecord : "category + period match"
    Budget }o--|| TransactionCategory : "category references"
    FinancialRecord }o--|| TransactionCategory : "category references"
    Budget }o--|| User : "user_id owns"
    Budget }o--o| Company : "company_id belongs to"
    FinancialRecord }o--|| User : "user_id owns"
    FinancialRecord }o--o| Company : "company_id belongs to"
    TransactionCategory }o--|| User : "user_id creates"
    TransactionCategory }o--o| Company : "company_id scopes"

    Budget {
        string id PK
        string user_id FK
        string company_id FK "nullable"
        string name "Nama anggaran"
        string description "Penjelasan detail, max 1000 char"
        string category FK "Kategori pengeluaran"
        number planned_amount "Anggaran direncanakan"
        number actual_amount "Realisasi, default 0"
        string period "monthly|quarterly|yearly|custom"
        date start_date "Tanggal mulai"
        date end_date "Tanggal akhir"
        string status "active|completed|archived"
        number alert_threshold "Persentase, default 80"
    }

    TransactionCategory {
        string id PK
        string user_id FK
        string name "Nama kategori"
        string description "Penjelasan, max 1000 char"
        string type "income|expense"
        string mode "personal|business"
        string company_id FK "nullable"
        string icon "Emoji atau ikon"
    }

    FinancialRecord {
        string id PK
        string user_id FK
        string company_id FK "nullable"
        string account_id FK "Rekening/kantong"
        string type "income|expense|transfer"
        number amount "Jumlah transaksi"
        string category FK "Kategori transaksi"
        string description "Deskripsi singkat"
        datetime date "Tanggal transaksi"
        string source "manual|ai_text|ai_scan|pos|..."
        string mode "personal|business"
        string reference_type "invoice_payment|pos_transaction|..."
        number cogs_amount "HPP/COGS"
        number tax_amount "Pajak (PPN)"
    }
```

### Penjelasan Relasi

* **Budget → TransactionCategory**: Setiap Budget mereferensikan satu `TransactionCategory` melalui field `category`. Kategori ini harus bertipe `expense` dan mode `business` untuk budget perusahaan.
* **Budget → FinancialRecord**: Budget tidak langsung memiliki relasi foreign key ke `FinancialRecord`. Sebaliknya, sistem melakukan **matching otomatis** berdasarkan kesamaan `category` dan overlap tanggal (`start_date` ≤ `FinancialRecord.date` ≤ `end_date`). Setiap `FinancialRecord` bertipe `expense` dengan kategori yang sama akan menjumlahkan `amount`-nya ke `actual_amount` Budget.
* **TransactionCategory → FinancialRecord**: Setiap `FinancialRecord` mereferensikan sebuah `TransactionCategory` melalui field `category`, yang menentukan klasifikasi pengeluaran/pemasukan.

***

## Complete Entity Schema — Budget (12 Fields)

Tabel berikut mencakup **seluruh 12 field** pada entity `Budget` sesuai definisi JSONC, termasuk tipe data, constraint, default value, dan penjelasan lengkap.

| # | Field | Tipe | Required | Default | Enum / Format | Deskripsi Lengkap |
| - | - | - | - | - | - | - |
| 1 | `user_id` | string | **Ya** | — | UUID | ID pengguna yang membuat dan memiliki anggaran ini. Setiap budget selalu dimiliki oleh satu user spesifik. |
| 2 | `company_id` | string | Tidak | `null` | UUID | ID perusahaan untuk multi-tenant isolation. Bernilai `null` jika budget bersifat personal (di luar konteks perusahaan). |
| 3 | `name` | string | **Ya** | — | — | Nama anggaran, misalnya "Budget Bahan Baku Q1 2026" atau "Gaji Karyawan Januari". |
| 4 | `description` | string | Tidak | — | maxLength: 1000 | Penjelasan tujuan dan detail anggaran. Digunakan untuk dokumentasi internal dan audit trail. |
| 5 | `category` | string | **Ya** | — | 11 expense categories | Kategori pengeluaran yang di-budget-kan. Mereferensikan nama `TransactionCategory` dengan `type=expense`. Opsi: salary, raw\_material, operational, production\_cost, travel, meals, accommodation, equipment, office\_supplies, training, other. |
| 6 | `planned_amount` | number | **Ya** | — | — | Jumlah anggaran yang direncanakan dalam Rupiah. Ini adalah target maksimal yang seharusnya tidak dilampaui. |
| 7 | `actual_amount` | number | Tidak | `0` | — | Jumlah pengeluaran aktual yang terakumulasi dari `FinancialRecord` dengan kategori yang sama dalam periode budget. Dihitung dan diupdate **otomatis** oleh sistem. |
| 8 | `period` | string | Tidak | `"monthly"` | `monthly`, `quarterly`, `yearly`, `custom` | Periode anggaran. `monthly` = 1 bulan, `quarterly` = 3 bulan, `yearly` = 1 tahun, `custom` = rentang tanggal ditentukan manual via `start_date` dan `end_date`. |
| 9 | `start_date` | date | **Ya** | — | ISO 8601 date | Tanggal mulai periode anggaran. `FinancialRecord` dengan `date` ≥ `start_date` akan dihitung sebagai realisasi. |
| 10 | `end_date` | date | **Ya** | — | ISO 8601 date | Tanggal akhir periode anggaran. `FinancialRecord` dengan `date` ≤ `end_date` akan dihitung sebagai realisasi. |
| 11 | `status` | string | Tidak | `"active"` | `active`, `completed`, `archived` | Status lifecycle budget. `active` = sedang berjalan dan tracking realisasi. `completed` = periode telah berakhir. `archived` = diarsipkan dan tidak ditampilkan di dashboard utama. |
| 12 | `alert_threshold` | number | Tidak | `80` | Persentase (0-100) | Persentase threshold untuk memicu notifikasi/alert. Ketika `actual_amount / planned_amount × 100%` ≥ nilai ini, sistem menampilkan warning. Default 80% berarti warning muncul saat realisasi mencapai 80% dari anggaran. |

### Constraint & Validasi

```
Required fields: user_id, name, category, planned_amount, start_date, end_date
Default values:  actual_amount = 0, period = "monthly", status = "active", alert_threshold = 80
RLS Policy:      Create/Read/Update/Delete terbatas pada owner (user_id) atau admin
Multi-tenant:    company_id memisahkan data antar perusahaan dalam satu instance
```

***

## State Diagram — Budget Lifecycle

Budget memiliki lifecycle yang diatur oleh field `status` dan persentase penggunaan (`actual_amount / planned_amount × 100%`). State diagram berikut menggambarkan transisi status budget berdasarkan kondisi realisasi.

```mermaid theme={null}
stateDiagram-v2
    [*] --> Active : Budget dibuat\n(status = "active")

    state Active {
        [*] --> OK : actual/planned ≤ 80%
        OK --> Warning : actual/planned 80%-100%
        Warning --> Exceeded : actual/planned > 100%
        Warning --> OK : Expense dihapus/dikurangi\nsehingga usage < 80%
        Exceeded --> Warning : Expense dikoreksi\nsehingga usage < 100%
    }

    Active --> Completed : Periode berakhir\n(end_date telah lewat)
    Active --> Archived : Diarsipkan manual\noleh user
    Completed --> Archived : Diarsipkan setelah\nperiode selesai
    Archived --> [*]
    Completed --> [*]
```

### Penjelasan State

| State | Kondisi | Indikator Visual | Tindakan yang Disarankan |
| - | - | - | - |
| **OK** | `actual_amount / planned_amount ≤ 80%` | 🟢 Hijau | Lanjutkan monitoring normal. Anggaran masih aman dan terkendali. |
| **Warning** | `80% ≤ actual_amount / planned_amount ≤ 100%` | 🟡 Kuning | Tingkatkan kewaspadaan. Review pengeluaran yang masuk dan pertimbangkan pembatasan expense baru pada kategori ini. |
| **Exceeded** | `actual_amount / planned_amount > 100%` | 🔴 Merah | Segera investigasi. Hentikan atau ketatkan approval untuk expense pada kategori ini. Dokumentasikan justifikasi over-budget. |
| **Completed** | `end_date < tanggal hari ini` | ⚪ Abu-abu | Periode telah berakhir. Data digunakan untuk trend analysis dan referensi budget periode berikutnya. |
| **Archived** | User mengarsipkan | 📁 Arsip | Tidak ditampilkan di dashboard utama. Data tetap tersimpan untuk audit dan referensi historis. |

***

## Budget vs Actual — Flow Diagram Perbandingan

Diagram berikut menggambarkan alur lengkap bagaimana data Budget dan Actual dibandingkan, dari input budget awal hingga menghasilkan laporan variance.

```mermaid theme={null}
flowchart TD
    subgraph INPUT["1. Input Budget"]
        B1["User membuat Budget"]
        B2["Set planned_amount,\ncategory, period,\nstart_date, end_date"]
        B3["Set alert_threshold\n(default 80%)"]
        B1 --> B2 --> B3
    end

    subgraph COLLECT["2. Pengumpulan Data Actual"]
        F1["User/Sistem membuat\nFinancialRecord (expense)"]
        F2["Sistem match:\ncategory sama?\ndate dalam range\nstart_date..end_date?"]
        F3["actual_amount +=\nFinancialRecord.amount"]
        F1 --> F2 --> F3
    end

    subgraph CALC["3. Kalkulasi & Monitoring"]
        C1["Hitung usage %:\nactual / planned × 100%"]
        C2["Hitung variance:\nplanned - actual"]
        C3["Bandingkan dengan\nalert_threshold"]
        C1 --> C2 --> C3
    end

    subgraph ALERT["4. Alert & Reporting"]
        A1{"usage % vs threshold"}
        A2["🟢 OK\nLanjut monitoring"]
        A3["🟡 Warning\nNotifikasi ke user"]
        A4["🔴 Exceeded\nAlert kritis +\nrequire approval"]
        A5["Generate report:\nBudget vs Actual\n+ Variance Analysis"]
        A1 -->|"≤ 80%"| A2
        A1 -->|"80-100%"| A3
        A1 -->|"> 100%"| A4
        A2 --> A5
        A3 --> A5
        A4 --> A5
    end

    INPUT --> COLLECT --> CALC --> ALERT
```

### Penjelasan Alur (Bahasa Indonesia)

1. **Input Budget**: User (biasanya manager atau admin keuangan) membuat budget baru dengan menentukan kategori pengeluaran, jumlah anggaran yang direncanakan (`planned_amount`), periode budget, dan threshold untuk alert.
2. **Pengumpulan Data Actual**: Setiap kali ada pengeluaran (`FinancialRecord` bertipe `expense`) yang dicatat — baik manual, dari POS, dari invoice, atau dari modul lainnya — sistem akan mencocokkan kategori dan tanggalnya dengan budget yang aktif. Jika cocok, `amount` dari `FinancialRecord` ditambahkan ke `actual_amount` budget.
3. **Kalkulasi & Monitoring**: Sistem secara real-time menghitung persentase penggunaan (`usage %`), variance (selisih antara planned dan actual), dan membandingkannya dengan threshold yang telah diset.
4. **Alert & Reporting**: Berdasarkan perbandingan `usage %` dengan `alert_threshold`, sistem menentukan level alert dan menghasilkan laporan untuk manajemen.

***

## Alert Threshold — Tabel Detail dengan Color Coding

Tabel berikut menjelaskan secara detail setiap level alert, warna indikator, kondisi pemicu, dan tindakan yang harus dilakukan oleh user.

| Level | Range Usage % | Warna | Ikon | Kondisi Pemicu | Notifikasi | Tindakan yang Harus Dilakukan |
| - | - | - | - | - | - | - |
| **Aman (OK)** | 0% – 79% | 🟢 Hijau | `✅` | `actual_amount / planned_amount < alert_threshold` | Tidak ada | Lanjutkan monitoring seperti biasa. Tidak perlu tindakan khusus. |
| **Perhatian (Warning)** | 80% – 99% | 🟡 Kuning | `⚠️` | `actual_amount / planned_amount ≥ alert_threshold` DAN `< 100%` | In-app notification + email opsional | Review semua expense pada kategori ini. Pertimbangkan untuk menunda pengeluaran yang tidak urgent. Siapkan rencana kontinjensi. |
| **Bahaya (Exceeded)** | ≥ 100% | 🔴 Merah | `🚨` | `actual_amount / planned_amount ≥ 100%` | In-app alert + email + dashboard highlight | **Investigasi segera.** Hentikan expense baru pada kategori ini kecuali mendapat approval khusus. Dokumentasikan justifikasi over-budget. Buat budget amendment jika diperlukan. |
| **Kritis (Critical)** | ≥ 120% | 🔴 Merah Tua | `💀` | `actual_amount / planned_amount ≥ 120%` | Escalation ke atasan + notifikasi multi-channel | **Eskalasi ke manajemen.** Freeze semua expense pada kategori ini. Lakukan audit terhadap transaksi yang menyebabkan over-budget signifikan. |
| **Selesai (Completed)** | N/A | ⚪ Abu-abu | `📋` | `end_date < current_date` | Notifikasi periode berakhir | Buat laporan final variance. Gunakan data untuk referensi budget periode berikutnya. |
| **Arsip (Archived)** | N/A | 📁 Biru | `📦` | User mengarsipkan secara manual | — | Data tetap tersimpan untuk audit trail dan referensi historis. |

### Contoh Visualisasi Threshold pada Dashboard

```
Budget: Bahan Baku Q1 2026
Planned:  Rp 15.000.000
Actual:   Rp 12.500.000
Usage:    83.3%
Threshold: 80%

[████████████████████████████████░░░░░░] 83.3%
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----
 |--- OK (0-80%) ---|-- Warning (80-100%)--|-- Over (100%+) --|
                    ▲
                    Current: 83.3% → 🟡 WARNING
```

***

## Sequence Diagram — Budget Creation, Tracking, dan Alerting

### 1. Budget Creation Flow

```mermaid theme={null}
sequenceDiagram
    actor User as User/Manager
    participant UI as Frontend UI
    participant API as API Server
    participant DB as Database
    participant TC as TransactionCategory

    User->>UI: Klik "Create Budget"
    UI->>API: GET /api/transaction-categories?type=expense&mode=business
    API->>DB: Query TransactionCategory
    DB-->>API: Return 11 expense categories
    API-->>UI: Return kategori tersedia
    UI->>User: Tampilkan form (kategori, amount, period, threshold, dates)

    User->>UI: Isi form & submit
    UI->>API: POST /api/budgets {name, category, planned_amount, period, start_date, end_date, alert_threshold}

    API->>API: Validasi required fields
    API->>API: Validasi planned_amount > 0
    API->>API: Validasi start_date < end_date
    API->>API: Validasi alert_threshold 0-100
    API->>API: Set default: actual_amount=0, status="active"

    API->>DB: INSERT INTO budgets (...)
    DB-->>API: Return created budget
    API-->>UI: Return 201 Created + budget data
    UI-->>User: Tampilkan budget baru di dashboard
```

### 2. Real-Time Tracking Flow

```mermaid theme={null}
sequenceDiagram
    actor User as User/Staff
    participant UI as Frontend UI
    participant API as API Server
    participant FR as FinancialRecord
    participant BE as Budget Engine
    participant DB as Database
    participant DASH as Dashboard

    User->>UI: Catat pengeluaran baru
    UI->>API: POST /api/financial-records {type:"expense", amount:500000, category:"raw_material", date:"2026-03-15"}

    API->>DB: INSERT FinancialRecord
    DB-->>API: Return created record

    API->>BE: Trigger budget recalculation
    BE->>DB: Query budgets WHERE category="raw_material"<br/>AND start_date ≤ "2026-03-15"<br/>AND end_date ≥ "2026-03-15"<br/>AND status="active"
    DB-->>BE: Return matching budget(s)

    BE->>DB: SUM(amount) FROM financial_records<br/>WHERE category="raw_material"<br/>AND date BETWEEN start_date AND end_date
    DB-->>BE: Return total actual_amount

    BE->>DB: UPDATE budgets SET actual_amount = total
    BE->>BE: Hitung usage % = actual/planned × 100%
    BE->>BE: Bandingkan dengan alert_threshold

    alt usage % ≥ 120% (Critical)
        BE->>DB: INSERT notification (level: critical)
        BE->>DASH: Update indicator → 🔴 Critical
    else usage % ≥ 100% (Exceeded)
        BE->>DB: INSERT notification (level: exceeded)
        BE->>DASH: Update indicator → 🔴 Exceeded
    else usage % ≥ threshold (Warning)
        BE->>DB: INSERT notification (level: warning)
        BE->>DASH: Update indicator → 🟡 Warning
    else usage % < threshold (OK)
        BE->>DASH: Update indicator → 🟢 OK
    end

    API-->>UI: Return 201 Created
    UI-->>User: Expense tercatat, dashboard updated
```

### 3. Alert & Notification Flow

```mermaid theme={null}
sequenceDiagram
    participant BE as Budget Engine
    participant NT as Notification Service
    participant EM as Email Service
    participant DB as Database
    actor User as User/Manager
    participant UI as Dashboard UI

    BE->>BE: Deteksi usage % melewati threshold

    BE->>NT: Kirim event: budget_alert {budget_id, level, usage_pct}
    NT->>DB: INSERT notification {user_id, type:"budget_warning", message:"Budget Raw Material telah mencapai 85%"}
    NT->>EM: Kirim email alert (jika user opt-in)

    EM-->>User: Email: "⚠️ Alert: Budget Bahan Baku 85%"
    DB-->>UI: Dashboard menampilkan badge notifikasi

    User->>UI: Klik notifikasi
    UI->>DB: GET /api/budgets/:id
    DB-->>UI: Return budget detail + recent expenses
    UI-->>User: Tampilkan detail budget + daftar expense<br/>yang menyebabkan alert

    alt User ingin investigasi
        User->>UI: Filter expenses by category + date range
        UI-->>User: Tampilkan daftar expense detail
    else User ingin adjust budget
        User->>UI: Edit budget → increase planned_amount
        UI->>DB: UPDATE budgets SET planned_amount = new_value
        DB-->>UI: Return updated budget
        BE->>BE: Recalculate usage % dengan planned_amount baru
    end
```

***

## Perbandingan Entity — Budget vs FinancialRecord vs TransactionCategory

Tabel berikut membandingkan ketiga entity utama yang terlibat dalam modul Budget Planner, untuk membantu developer memahami tanggung jawab masing-masing entity.

| Aspek | Budget | FinancialRecord | TransactionCategory |
| - | - | - | - |
| **Fungsi Utama** | Perencanaan & kontrol anggaran | Pencatatan transaksi keuangan aktual | Klasifikasi jenis transaksi |
| **Jumlah Field** | 12 field | 19 field | 7 field |
| **Sifat Data** | Plan (rencana/target) | Actual (realisasi) | Master data (referensi) |
| **Update `amount`** | `actual_amount` diupdate otomatis oleh sistem | `amount` diinput manual atau dari modul lain | Tidak ada field amount |
| **Periodisitas** | Memiliki periode (start\_date, end\_date) | Per transaksi (date per record) | Tidak terbatas periode |
| **Status Lifecycle** | active → completed → archived | Tidak ada status lifecycle | Tidak ada status lifecycle |
| **Relasi ke Budget** | — | Match via `category` + date range | Referenced by `category` field |
| **Multi-tenant** | `company_id` (nullable) | `company_id` (nullable) | `company_id` (nullable) |
| **Mode** | N/A | personal / business | personal / business |
| **Contoh Use Case** | "Budget Gaji Januari: Rp 25jt" | "Bayar gaji Budi: Rp 3.5jt" | Kategori "salary" untuk semua transaksi gaji |

***

## Ringkasan Alur Data End-to-End (Bahasa Indonesia)

Berikut adalah ringkasan alur data lengkap modul Budget Planner dari awal hingga akhir, dijelaskan dalam Bahasa Indonesia untuk memudahkan pemahaman stakeholder non-teknis.

### Tahap 1: Persiapan & Setup

Perusahaan PT Selera Pedas Nusantara (Quinn of Spicy) pertama-tama menyiapkan **kategori transaksi** (`TransactionCategory`) untuk semua jenis pengeluaran yang relevan dengan bisnis F\&B, seperti bahan baku (cabai, bawang, ayam), gaji karyawan, biaya operasional (listrik, air, sewa), dan lain-lain. Total terdapat **11 kategori expense** yang tersedia secara default.

### Tahap 2: Pembuatan Budget

Manager atau admin keuangan membuat **Budget** untuk setiap kategori pada periode tertentu. Misalnya: "Budget Bahan Baku bulan Januari 2026" dengan `planned_amount` = Rp 15.000.000, `period` = monthly, dan `alert_threshold` = 80%. Sistem menyimpan budget ini dengan `status = "active"` dan `actual_amount = 0`.

### Tahap 3: Tracking Realisasi

Setiap kali ada pengeluaran yang dicatat di SNISHOP ERP — baik melalui input manual, transaksi POS, invoice pembelian, atau modul lainnya — sistem secara otomatis:

1. Mencocokkan **kategori** pengeluaran dengan budget yang aktif
2. Memastikan **tanggal** pengeluaran berada dalam rentang `start_date` hingga `end_date` budget
3. Menambahkan **amount** pengeluaran ke `actual_amount` budget yang sesuai
4. Menghitung **persentase penggunaan** (`actual_amount / planned_amount × 100%`)

### Tahap 4: Monitoring & Alert

Sistem continuously memantau persentase penggunaan setiap budget aktif:

* Jika usage **≤ 80%** (default threshold): indikator **hijau**, semua aman
* Jika usage **80-100%**: indikator **kuning**, sistem mengirim notifikasi warning
* Jika usage **> 100%**: indikator **merah**, sistem mengirim alert kritis dan menyarankan investigasi

### Tahap 5: Analisis & Reporting

Di akhir periode (atau kapan saja), manajemen dapat melihat:

* **Budget vs Actual Report**: Perbandingan planned vs actual per kategori
* **Variance Analysis**: Selisih dan persentase deviasi
* **Trend Analysis**: Perbandingan antar periode untuk identifikasi pola
* **Export**: Laporan dapat diexport ke PDF (untuk presentasi), Excel (untuk analisis lanjutan), atau CSV (untuk integrasi sistem lain)

Data dari budget yang telah selesai (`status = "completed"`) digunakan sebagai referensi untuk menyusun budget periode berikutnya, menciptakan siklus perencanaan yang terus membaik (**continuous improvement**).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.