> ## 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.

# Live streaming

<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: "Live Streaming Tracker"
description: "Tracker live streaming multi-platform, KPI metrics, leaderboard, dan sales analytics di SNISHOP ERP."
-------------------------------------------------------------------------------------------------------------------

# Live Streaming Tracker

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/b2b/live-streaming.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=91e6288f2ae78491c604e15531716446" alt="Live Streaming" width="1920" height="1080" data-path="docs/mintlify/screenshots/b2b/live-streaming.png" />

Live Streaming Tracker adalah modul komprehensif untuk merencanakan, mengeksekusi, dan menganalisis sesi live streaming sebagai channel penjualan. Sistem ini mendukung 6 platform streaming, menghitung KPI secara otomatis, menampilkan leaderboard produk dan sales person, serta mengexport data ke CSV untuk analisis lanjutan.

Modul ini dirancang untuk tim marketing yang memanfaatkan live commerce sebagai revenue stream. Dengan data yang tercatat per sesi — viewer count, engagement rate, conversion rate, dan revenue — tim bisa mengoptimasi strategi live streaming berdasarkan evidence, bukan asumsi.

Sistem ini juga memiliki Role-Based Access Control (RBAC) yang membatasi akses ke 6 role tertentu, memastikan hanya personel yang berwenang yang bisa mengelola dan melihat data live streaming.

## Arsitektur Komponen

```mermaid theme={null}
graph TD
    A[LiveStreamingTracker.jsx<br/>1225 lines] --> B[KPI Dashboard<br/>8 Metric Cards]
    A --> C[Platform Breakdown<br/>Horizontal Bar Chart]
    A --> D[Top Products<br/>Leaderboard]
    A --> E[Sales Person<br/>Leaderboard]
    A --> F[Session Management<br/>Create / Edit / Delete]
    A --> G[CSV Export<br/>With BOM]
    
    B --> H[Viewer Count<br/>Engagement Rate<br/>Conversion Rate<br/>Revenue]
    
    C --> I[6 Platforms<br/>With Colors & Gradients]
    
    D --> J[Product Revenue<br/>Units Sold]
    
    E --> K[Per Person Metrics<br/>Sessions & Revenue]
```

## Entity & Model

### LiveStreamingActivity

| Field | Tipe | Deskripsi |
| - | - | - |
| `id` | UUID | Primary key |
| `title` | String | Judul sesi live streaming |
| `platform` | Enum | 6 platform (lihat tabel di bawah) |
| `scheduled_at` | Timestamp | Waktu dijadwalkan |
| `started_at` | Timestamp | Waktu aktual mulai |
| `ended_at` | Timestamp | Waktu aktual selesai |
| `duration_minutes` | Number | **Auto-calculated**: (ended\_at - started\_at) / 60000 |
| `host_name` | String | Nama host/presenter |
| `viewer_count` | Number | Jumlah viewer (peak atau average) |
| `engagement_count` | Number | Total engagement (comments + shares + likes) |
| `conversion_rate` | Number | **Auto-calculated**: (orders / viewer\_count) \* 100 |
| `orders_count` | Number | Jumlah order dari sesi live |
| `revenue` | Number | Total revenue yang dihasilkan |
| `products_featured` | Array | Daftar produk yang dipromosikan |
| `notes` | Text | Catatan sesi |
| `status` | Enum | `scheduled`, `live`, `completed`, `cancelled` |
| `company_id` | UUID | Multi-tenant scoping |
| `created_at` | Timestamp | Waktu pembuatan record |
| `updated_at` | Timestamp | Waktu update terakhir |

### Supported Platforms

| Platform | Warna | Gradient | Emoji |
| - | - | - | - |
| TikTok Live | `#000000` | Black → Pink | 🎵 |
| Shopee Live | `#EE4D2D` | Orange → Red | 🛒 |
| Instagram Live | `#E4405F` | Purple → Pink → Orange | 📸 |
| Facebook Live | `#1877F2` | Blue gradient | 📘 |
| YouTube Live | `#FF0000` | Red gradient | ▶️ |
| Tokopedia Play | `#42b549` | Green gradient | 🟢 |

### Auto-Calculated Fields

| Field | Formula | Deskripsi |
| - | - | - |
| `duration_minutes` | `(ended_at - started_at) / 60000` | Durasi sesi dalam menit |
| `conversion_rate` | `(orders_count / viewer_count) * 100` | Persentase viewer yang menjadi buyer |

## Fitur Utama

### 1. KPI Dashboard (8 Metric Cards)

Dashboard menampilkan 8 kartu KPI yang memberikan overview performa live streaming:

| # | Metric | Sumber | Deskripsi |
| - | - | - | - |
| 1 | Total Sessions | `COUNT(sessions)` | Jumlah sesi live yang sudah dilakukan |
| 2 | Total Revenue | `SUM(revenue)` | Akumulasi revenue dari semua sesi |
| 3 | Total Orders | `SUM(orders_count)` | Total order yang dihasilkan |
| 4 | Avg. Viewers | `AVG(viewer_count)` | Rata-rata viewer per sesi |
| 5 | Avg. Engagement | `AVG(engagement_count)` | Rata-rata engagement per sesi |
| 6 | Avg. Conversion Rate | `AVG(conversion_rate)` | Rata-rata konversi viewer → buyer |
| 7 | Total Duration | `SUM(duration_minutes)` | Total menit live streaming |
| 8 | Revenue per Session | `Total Revenue / Total Sessions` | Efisiensi revenue per sesi |

### 2. Platform Breakdown Chart

Horizontal bar chart yang menampilkan distribusi performa per platform:

```mermaid theme={null}
graph LR
    A[TikTok Live 🎵] ████████████████ Rp 15.2M
    B[Shopee Live 🛒] ████████████ Rp 11.8M
    C[Instagram Live 📸] ████████ Rp 7.5M
    D[Facebook Live 📘] █████ Rp 4.2M
    E[YouTube Live ▶️] ███ Rp 2.1M
    F[Tokopedia Play 🟢] ██ Rp 1.5M
```

**Visual Encoding**:

| Platform | Bar Color | Background |
| - | - | - |
| TikTok | `#000000` | Black gradient |
| Shopee | `#EE4D2D` | Orange gradient |
| Instagram | `#E4405F` | Pink-purple gradient |
| Facebook | `#1877F2` | Blue gradient |
| YouTube | `#FF0000` | Red gradient |
| Tokopedia | `#42b549` | Green gradient |

### 3. Top Products Leaderboard

Ranking produk yang paling sering muncul dan menghasilkan revenue tertinggi dari sesi live:

| Rank | Product Name | Times Featured | Units Sold | Revenue |
| - | - | - | - | - |
| 1 | Saos Extra Pedas 350ml | 12 sessions | 1,240 bottles | Rp 8.7M |
| 2 | Bumbu Rendang 200g | 8 sessions | 856 packs | Rp 5.1M |
| 3 | Saos BBQ 250ml | 6 sessions | 620 bottles | Rp 3.7M |

### 4. Sales Person Leaderboard

Ranking host/presenter berdasarkan performa live streaming:

| Rank | Host Name | Sessions Hosted | Total Revenue | Avg. Viewers |
| - | - | - | - | - |
| 1 | Sarah | 15 sessions | Rp 22.5M | 2,340 |
| 2 | Budi | 12 sessions | Rp 18.2M | 1,890 |
| 3 | Andi | 10 sessions | Rp 14.7M | 1,650 |

### 5. Session Management

**Create Session Flow**:

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant LST as LiveStreamingTracker
    participant DB as Database
    participant CAL as Calendar

    U->>LST: Click "Jadwalkan Live"
    LST->>U: Show create form
    
    U->>LST: Fill form<br/>title, platform, scheduled_at, host_name
    U->>LST: Select products to feature
    U->>LST: Submit
    
    LST->>LST: Set status = "scheduled"
    LST->>DB: Insert LiveStreamingActivity
    DB-->>LST: Return created record
    LST->>CAL: Add to calendar (optional)
    LST-->>U: Session scheduled
```

**Session Lifecycle**:

```mermaid theme={null}
stateDiagram-v2
    [*] --> Scheduled: Session dibuat
    Scheduled --> Live: Host mulai live
    Live --> Completed: Host akhiri live
    Completed --> [*]
    
    Scheduled --> Cancelled: Dibatalkan sebelum mulai
    Cancelled --> [*]
```

| Status | Deskripsi | Aksi yang Tersedia |
| - | - | - |
| Scheduled | Dijadwalkan, belum mulai | Edit, Cancel, Start |
| Live | Sedang berlangsung | Update metrics, End |
| Completed | Selesai, data final | View, Export |
| Cancelled | Dibatalkan | View, Reschedule |

### 6. RBAC (Role-Based Access Control)

Akses ke Live Streaming Tracker dibatasi untuk 6 role tertentu:

| Role | Akses | Deskripsi |
| - | - | - |
| Super Admin | Full | Semua operasi |
| Admin | Full | Semua operasi |
| Marketing Manager | Full | Semua operasi |
| Marketing Staff | Create, Read, Update | Bisa buat dan edit sesi |
| Sales Manager | Read | Hanya lihat data |
| Content Creator | Create, Read | Bisa buat sesi dan lihat data |

### 7. CSV Export

Data sesi live streaming bisa diexport ke CSV dengan **BOM (Byte Order Mark)** untuk kompatibilitas Excel:

| Kolom Export | Sumber Field |
| - | - |
| Title | `title` |
| Platform | `platform` |
| Date | `scheduled_at` |
| Duration (min) | `duration_minutes` |
| Host | `host_name` |
| Viewers | `viewer_count` |
| Engagement | `engagement_count` |
| Orders | `orders_count` |
| Conversion Rate | `conversion_rate` |
| Revenue | `revenue` |

**BOM Prefix**: File CSV di-prefix dengan `\uFEFF` (UTF-8 BOM) agar Microsoft Excel correctly interpret UTF-8 characters, terutama untuk nama produk dan host berbahasa Indonesia.

## Cara Akses

Dari sidebar, klik menu **B2B** > **Live Streaming**.

## Flow Penggunaan

### Marketing Manager

1. Buka halaman Live Streaming dari sidebar
2. Review KPI dashboard untuk melihat performa keseluruhan
3. Analisis platform breakdown untuk tahu platform mana yang paling efektif
4. Check top products leaderboard untuk planning produk mana yang harus di-feature
5. Review sales person leaderboard untuk evaluasi performa tim
6. Jadwalkan sesi live baru berdasarkan insight dari data

### Content Creator / Host

1. Buka halaman Live Streaming
2. Klik "Jadwalkan Live" untuk membuat sesi baru
3. Isi detail: judul, platform, waktu, produk yang akan dipromosikan
4. Saat waktu tiba, mulai live dari platform yang dipilih
5. Setelah selesai, update metrics: viewer count, engagement, orders, revenue
6. Sistem otomatis hitung duration dan conversion rate

### Admin / Analyst

1. Buka halaman Live Streaming untuk monitoring
2. Export data ke CSV untuk analisis lanjutan di spreadsheet
3. Bandingkan performa antar platform dan antar host
4. Identifikasi pola: waktu terbaik, platform terbaik, produk paling laris
5. Buat rekomendasi strategi live streaming berdasarkan data

## Integrasi Cross-Module

```mermaid theme={null}
graph LR
    A[Live Streaming Tracker] --> B[Product Catalog<br/>Featured products]
    A --> C[CRM<br/>Host/customer data]
    A --> D[Finance<br/>Revenue tracking]
    A --> E[Analytics<br/>Performance reporting]
    A --> F[Calendar<br/>Schedule management]
    
    B --> G[CompanyPOSProduct]
    C --> H[User entity]
    D --> I[Revenue aggregation]
    E --> J[KPI dashboard]
```

## Tips

* Fokus pada conversion rate, bukan hanya viewer count — 500 viewer dengan 5% conversion lebih berharga dari 5000 viewer dengan 0.1% conversion
* Rotasi host secara berkala dan gunakan sales person leaderboard untuk identifikasi top performer
* Schedule live di jam prime time (19:00-21:00 WIB) berdasarkan data historis viewer count
* Feature 3-5 produk per sesi — terlalu banyak produk menurunkan focus dan conversion
* Export CSV setiap bulan untuk analisis tren jangka panjang dan planning quarter berikutnya
* Gunakan platform breakdown untuk alokasi resource — invest lebih banyak di platform yang menghasilkan revenue tertinggi

***

## Entity Relationship Diagram

```mermaid theme={null}
erDiagram
    LiveStreamingActivity {
        string company_id PK "ID perusahaan (multi-tenant)"
        string sales_person_id FK "ID user sales yang live streaming"
        string sales_person_name "Nama sales person"
        date activity_date "Tanggal live streaming"
        enum platform "Platform live streaming"
        string platform_label "Label platform lain (jika other)"
        datetime start_time "Waktu mulai live"
        datetime end_time "Waktu selesai live"
        number duration_minutes "Durasi live (auto: end - start)"
        number peak_viewers "Peak viewers"
        number avg_viewers "Rata-rata viewers"
        array promoted_product_ids "ID produk yang dipromosikan"
        array promoted_product_names "Nama produk yang dipromosikan"
        number orders_count "Jumlah order dari live"
        number revenue "Revenue dari live streaming"
        string screenshot_url "URL screenshot live"
        string recording_link "Link recording live"
        number conversion_rate "Conversion rate (auto)"
        enum status "Status live streaming"
        string notes "Catatan tambahan"
    }

    CompanyPOSProduct {
        string company_id PK "ID perusahaan"
        string name "Nama produk"
        string sku "SKU/Barcode produk"
        string category "Kategori produk"
        string category_key "Kategori canonical"
        string variant_key "Varian canonical"
        number price "Harga jual"
        number cost "Harga modal/beli"
        number stock "Stok saat ini"
        string product_type "Tipe produk"
        number sold_count "Total produk terjual"
        boolean is_active "Status aktif produk"
    }

    User {
        string email PK "Email user"
        string full_name "Nama lengkap"
        enum role "Role: admin atau user"
        string active_company_id FK "ID perusahaan aktif"
        enum subscription_plan "Paket langganan"
        enum admin_type "Tipe admin aplikasi"
        enum admin_tier "Tier admin company management"
    }

    Customer {
        string company_id PK "ID perusahaan"
        string name "Nama customer"
        string phone "Nomor telepon"
        string email "Email customer"
        enum customer_type "Tipe customer"
        enum status "Status customer"
        number lifetime_value "Total nilai transaksi"
        number total_orders "Jumlah transaksi"
    }

    CompanyPOSCategory {
        string company_id PK "ID perusahaan"
        string name "Nama kategori"
        string description "Deskripsi kategori"
        string icon "Icon emoji"
        string color "Warna kategori"
        number order "Urutan kategori"
    }

    LiveStreamingActivity ||--o{ CompanyPOSProduct : "promoted_product_ids"
    LiveStreamingActivity }o--|| User : "sales_person_id"
    CompanyPOSProduct }o--|| CompanyPOSCategory : "category"
    User ||--o{ LiveStreamingActivity : "membuat sesi live"
    Customer ||--o{ LiveStreamingActivity : "melalui orders dari live"
```

## Entity Schema Detail (dari JSONC)

### LiveStreamingActivity

Entitas utama yang menyimpan setiap sesi live streaming. Setiap record merepresentasikan satu sesi live dengan metrik performa lengkap.

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `company_id` | String | Ya | - | ID perusahaan (multi-tenant scoping) |
| `sales_person_id` | String | Tidak | - | ID user sales yang melakukan live streaming |
| `sales_person_name` | String | Tidak | - | Nama sales person (denormalisasi untuk performa query) |
| `activity_date` | Date | Ya | - | Tanggal live streaming dilaksanakan |
| `platform` | Enum | Ya | - | Platform live streaming (lihat tabel enum di bawah) |
| `platform_label` | String | Tidak | - | Label platform lain (diisi jika platform = `other`) |
| `start_time` | DateTime | Ya | - | Waktu mulai live streaming |
| `end_time` | DateTime | Tidak | - | Waktu selesai live streaming |
| `duration_minutes` | Number | Tidak | `0` | Durasi live dalam menit (auto: end\_time - start\_time) |
| `peak_viewers` | Number | Tidak | `0` | Jumlah viewer tertinggi selama sesi live |
| `avg_viewers` | Number | Tidak | `0` | Rata-rata jumlah viewers selama sesi live |
| `promoted_product_ids` | Array\[String] | Tidak | - | Daftar ID produk yang dipromosikan saat live |
| `promoted_product_names` | Array\[String] | Tidak | - | Daftar nama produk yang dipromosikan (denormalisasi) |
| `orders_count` | Number | Tidak | `0` | Jumlah order yang masuk dari sesi live |
| `revenue` | Number | Tidak | `0` | Total revenue yang dihasilkan dari sesi live |
| `screenshot_url` | String | Tidak | - | URL screenshot/thumbnail live streaming |
| `recording_link` | String | Tidak | - | Link recording/replay live streaming |
| `conversion_rate` | Number | Tidak | `0` | Conversion rate (auto: orders\_count / avg\_viewers \* 100) |
| `status` | Enum | Tidak | `completed` | Status live streaming (lihat tabel enum di bawah) |
| `notes` | String | Tidak | - | Catatan tambahan untuk sesi live |

**Required fields**: `company_id`, `activity_date`, `platform`, `start_time`

### CompanyPOSProduct

Entitas produk POS yang menjadi referensi untuk produk yang dipromosikan dalam sesi live streaming.

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `company_id` | String | Ya | - | ID perusahaan pemilik produk |
| `name` | String | Ya | - | Nama produk |
| `sku` | String | Tidak | - | SKU/Barcode produk |
| `category` | String | Tidak | - | Kategori produk |
| `category_key` | String | Tidak | - | Kategori canonical: kecil, besar, pouch, bundle, snack |
| `category_name` | String | Tidak | - | Label kategori canonical |
| `variant_key` | String | Tidak | - | Varian canonical: original, extra\_spicy, bundle |
| `variant_name` | String | Tidak | - | Label varian canonical |
| `variant_label` | String | Tidak | - | Gabungan kategori dan varian untuk POS/inventory |
| `size_grams` | Number | Tidak | - | Ukuran canonical produk dalam gram |
| `base_product_key` | String | Tidak | - | Kunci produk utama sebelum kategori/varian |
| `description` | String | Tidak | - | Deskripsi produk |
| `price` | Number | Ya | - | Harga jual produk |
| `cost` | Number | Tidak | - | Harga modal/beli produk |
| `stock` | Number | Tidak | `0` | Stok saat ini |
| `min_stock` | Number | Tidak | `5` | Minimum stok untuk alert |
| `image_url` | String | Tidak | - | URL gambar utama produk |
| `gallery` | Array\[String] | Tidak | - | Galeri foto produk (maks 20 foto) |
| `is_active` | Boolean | Tidak | `true` | Status aktif produk |
| `product_type` | Enum | Tidak | `finished_good` | Tipe produk: finished\_good, raw\_material, semi\_finished, packaging\_material, bundle |
| `packaging_type` | Enum | Tidak | - | Jenis kemasan: jar\_glass, pouch\_zipper, pouch\_sealed, toples\_plastic, bottle\_plastic, bulk, other |
| `net_weight_grams` | Number | Tidak | - | Berat bersih isi produk dalam gram |
| `gross_weight_grams` | Number | Tidak | - | Berat kotor termasuk kemasan dalam gram |
| `storage_condition` | Enum | Tidak | `room_temperature` | Kondisi penyimpanan: room\_temperature, chilled, frozen |
| `is_bundle` | Boolean | Tidak | `false` | Menandakan paket bundle virtual |
| `sold_count` | Number | Tidak | `0` | Total jumlah produk terjual (akumulator) |
| `tax_rate` | Number | Tidak | `0` | Persentase pajak (0-100) |
| `supplier` | String | Tidak | - | Nama supplier |
| `unit` | String | Tidak | `pcs` | Satuan produk |
| `barcode` | String | Tidak | - | Barcode / QR Code produk (EAN-13) |
| `is_locked` | Boolean | Tidak | `false` | Data terkunci karena sudah ada transaksi |
| `deactivated_at` | DateTime | Tidak | - | Waktu SKU dinonaktifkan |
| `deactivated_by` | String | Tidak | - | Akun yang menonaktifkan SKU |

**Required fields**: `company_id`, `name`, `price`

### User

Entitas user yang menjadi referensi untuk sales person / host yang melakukan live streaming.

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `email` | String | Ya | - | Email user |
| `full_name` | String | Ya | - | Nama lengkap user |
| `role` | Enum | Tidak | - | Role: `admin` atau `user` |
| `active_company_id` | String | Tidak | - | ID perusahaan yang sedang aktif |
| `subscription_plan` | Enum | Tidak | `free` | Paket langganan: free, pro, business, advanced, enterprise |
| `admin_type` | Enum | Tidak | - | Tipe admin: `owner` (full access) atau `basic` (terbatas) |
| `admin_tier` | Enum | Tidak | `none` | Tier admin: none, business, advanced, enterprise |
| `productivity_score` | Number | Tidak | `0` | Skor produktivitas pengguna |
| `user_level` | Number | Tidak | `1` | Level pengguna berdasarkan achievement points |

**Required fields**: `email`, `full_name`

### Customer

Entitas customer yang terkait dengan order yang dihasilkan dari sesi live streaming.

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `company_id` | String | Ya | - | ID perusahaan |
| `name` | String | Ya | - | Nama customer |
| `phone` | String | Ya | - | Nomor telepon |
| `email` | String | Tidak | - | Email customer |
| `whatsapp_number` | String | Tidak | - | Nomor WhatsApp untuk follow up |
| `company` | String | Tidak | - | Nama perusahaan customer |
| `address` | String | Tidak | - | Alamat customer |
| `customer_type` | Enum | Tidak | `individual` | Tipe: individual, business, retail, reseller, distributor, modern\_market |
| `status` | Enum | Tidak | `lead` | Status: lead, prospect, customer, inactive |
| `lifetime_value` | Number | Tidak | `0` | Total nilai transaksi sepanjang waktu |
| `total_orders` | Number | Tidak | `0` | Jumlah transaksi |
| `average_order_value` | Number | Tidak | `0` | Rata-rata nilai transaksi |
| `membership_level_name` | String | Tidak | - | Nama level membership |
| `membership_points` | Number | Tidak | `0` | Total poin member saat ini |
| `is_active` | Boolean | Tidak | `true` | Status aktif customer |

**Required fields**: `company_id`, `name`, `phone`

### CompanyPOSCategory

Entitas kategori produk yang mengelompokkan produk-produk yang dipromosikan dalam live streaming.

| Field | Tipe | Required | Default | Deskripsi |
| - | - | - | - | - |
| `company_id` | String | Ya | - | ID perusahaan |
| `name` | String | Ya | - | Nama kategori |
| `description` | String | Tidak | - | Deskripsi kategori (maks 1000 karakter) |
| `icon` | String | Tidak | - | Icon emoji untuk kategori |
| `color` | String | Tidak | `#3b82f6` | Warna kategori |
| `order` | Number | Tidak | `0` | Urutan pengurutan kategori |

**Required fields**: `company_id`, `name`

## Diagram State Sesi Live Streaming

```mermaid theme={null}
stateDiagram-v2
    [*] --> Ongoing: Sales person mulai sesi live
    Ongoing --> Completed: Host akhiri live & input metrik final
    Completed --> [*]

    Ongoing --> Cancelled: Dibatalkan di tengah sesi
    Cancelled --> [*]

    state Ongoing {
        [*] --> InputViewer
        InputViewer --> InputOrders: Update viewer count
        InputOrders --> InputRevenue: Update orders & revenue
        InputRevenue --> Finalisasi: Input data selesai
    }

    state Completed {
        [*] --> DataTercatat
        DataTercatat --> BisaExport: Data final tersimpan
        BisaExport --> BisaAnalisis: Bisa export CSV
    }
```

## Diagram Sekuens: Alur Lengkap Live Streaming

### Alur Pembuatan & Eksekusi Sesi Live

```mermaid theme={null}
sequenceDiagram
    participant SP as Sales Person / Host
    participant UI as LiveStreamingTracker UI
    participant SVC as Backend Service
    participant DB as Database
    participant PROD as CompanyPOSProduct
    participant USR as User Entity

    SP->>UI: Buka halaman Live Streaming
    UI->>SVC: Fetch daftar sesi live (company_id)
    SVC->>DB: SELECT * FROM LiveStreamingActivity WHERE company_id = ?
    DB-->>SVC: Return daftar sesi
    SVC->>USR: Resolve sales_person_name dari sales_person_id
    USR-->>SVC: Return nama sales person
    SVC-->>UI: Return data sesi + nama host

    SP->>UI: Klik "Buat Sesi Live Baru"
    UI->>UI: Tampilkan form input

    SP->>UI: Pilih platform (TikTok/Shopee/IG/dll)
    SP->>UI: Pilih tanggal & waktu mulai
    SP->>UI: Pilih produk dari katalog (CompanyPOSProduct)
    UI->>PROD: Fetch daftar produk aktif
    PROD-->>UI: Return daftar produk (name, sku, price)
    UI-->>SP: Tampilkan daftar produk untuk dipilih

    SP->>UI: Submit form
    UI->>SVC: CREATE LiveStreamingActivity
    Note over SVC: Set status = "ongoing"<br/>Set start_time = NOW()
    SVC->>DB: INSERT LiveStreamingActivity
    DB-->>SVC: Return created record
    SVC-->>UI: Return sesi yang dibuat
    UI-->>SP: Konfirmasi sesi live berhasil dibuat
```

### Alur Update Metrik Setelah Live Selesai

```mermaid theme={null}
sequenceDiagram
    participant SP as Sales Person / Host
    participant UI as LiveStreamingTracker UI
    participant SVC as Backend Service
    participant DB as Database

    SP->>UI: Buka sesi live yang sedang berlangsung
    UI->>DB: Fetch LiveStreamingActivity by ID
    DB-->>UI: Return data sesi

    SP->>UI: Input peak_viewers & avg_viewers
    SP->>UI: Input orders_count & revenue
    SP->>UI: Upload screenshot_url (opsional)
    SP->>UI: Input recording_link (opsional)
    SP->>UI: Input end_time (waktu selesai)
    SP->>UI: Klik "Selesai & Simpan"

    UI->>SVC: UPDATE LiveStreamingActivity
    Note over SVC: Hitung otomatis:<br/>duration_minutes = (end_time - start_time) / 60000<br/>conversion_rate = (orders_count / avg_viewers) * 100<br/>status = "completed"
    SVC->>DB: UPDATE SET duration_minutes, conversion_rate, status, ...
    DB-->>SVC: Return updated record
    SVC-->>UI: Return sesi yang sudah diperbarui
    UI-->>SP: Konfirmasi data metrik berhasil disimpan
```

### Alur Export CSV

```mermaid theme={null}
sequenceDiagram
    participant SP as Marketing Manager
    participant UI as LiveStreamingTracker UI
    participant CALC as KPI Calculator
    participant CSV as CSV Generator

    SP->>UI: Klik tombol "Export CSV"
    UI->>CALC: Hitung semua KPI metrics
    CALC-->>UI: Return data sesi + KPI

    UI->>CSV: Generate CSV data
    Note over CSV: Tambahkan BOM prefix (\uFEFF)<br/>untuk kompatibilitas Excel
    CSV->>CSV: Map field ke kolom CSV:<br/>Title, Platform, Date, Duration,<br/>Host, Viewers, Engagement,<br/>Orders, Conversion Rate, Revenue
    CSV-->>UI: Return CSV blob

    UI->>SP: Download file CSV<br/>(live_streaming_export.csv)
```

### Alur Leaderboard & Analytics

```mermaid theme={null}
sequenceDiagram
    participant SP as Marketing Manager
    participant UI as LiveStreamingTracker UI
    participant KPI as KPI Engine
    participant DB as Database

    SP->>UI: Buka dashboard Live Streaming
    UI->>KPI: Hitung 8 KPI metrics
    KPI->>DB: Aggregate queries

    Note over DB: SELECT COUNT(*) → Total Sessions<br/>SELECT SUM(revenue) → Total Revenue<br/>SELECT SUM(orders_count) → Total Orders<br/>SELECT AVG(viewer_count) → Avg Viewers<br/>SELECT AVG(engagement) → Avg Engagement<br/>SELECT AVG(conversion_rate) → Avg Conv Rate<br/>SELECT SUM(duration) → Total Duration<br/>Revenue / Sessions → Revenue per Session

    DB-->>KPI: Return aggregate results
    KPI-->>UI: Return 8 KPI values

    UI->>DB: Fetch data untuk Platform Breakdown
    DB-->>UI: Return data per platform
    UI->>DB: Fetch data untuk Top Products Leaderboard
    DB-->>UI: Return ranking produk
    UI->>DB: Fetch data untuk Sales Person Leaderboard
    DB-->>UI: Return ranking host

    UI-->>SP: Tampilkan dashboard lengkap dengan KPI, chart, dan leaderboard
```

## Tabel Enum Lengkap

### Enum: `platform` (LiveStreamingActivity)

| Nilai | Deskripsi | Warna Brand |
| - | - | - |
| `shopee_live` | Shopee Live — platform live streaming Shopee | `#EE4D2D` (Orange) |
| `tiktok` | TikTok Live — platform live streaming TikTok | `#000000` (Hitam) |
| `instagram` | Instagram Live — platform live streaming Instagram | `#E4405F` (Pink) |
| `facebook` | Facebook Live — platform live streaming Facebook | `#1877F2` (Biru) |
| `youtube` | YouTube Live — platform live streaming YouTube | `#FF0000` (Merah) |
| `other` | Platform lain — gunakan field `platform_label` untuk mengisi nama platform | - |

### Enum: `status` (LiveStreamingActivity)

| Nilai | Deskripsi | Warna Indikator |
| - | - | - |
| `ongoing` | Sesi live sedang berlangsung | Hijau (berkedip) |
| `completed` | Sesi live sudah selesai dan data final tersimpan | Biru |
| `cancelled` | Sesi live dibatalkan | Merah |

### Enum: `role` (User)

| Nilai | Deskripsi |
| - | - |
| `admin` | Administrator dengan akses penuh ke semua modul |
| `user` | User biasa dengan akses terbatas sesuai konfigurasi |

### Enum: `subscription_plan` (User)

| Nilai | Deskripsi |
| - | - |
| `free` | Paket gratis dengan fitur dasar |
| `pro` | Paket profesional dengan fitur lanjutan |
| `business` | Paket bisnis untuk tim kecil-menengah |
| `advanced` | Paket advanced untuk perusahaan menengah-besar |
| `enterprise` | Paket enterprise dengan fitur lengkap dan prioritas support |

### Enum: `admin_type` (User)

| Nilai | Deskripsi |
| - | - |
| `owner` | Owner aplikasi — full access ke seluruh fitur aplikasi |
| `basic` | Admin basic — hanya bisa mengelola transaksi produk digital |

### Enum: `admin_tier` (User)

| Nilai | Deskripsi |
| - | - |
| `none` | Tidak memiliki tier admin |
| `business` | Tier admin untuk manajemen company level business |
| `advanced` | Tier admin untuk manajemen company level advanced |
| `enterprise` | Tier admin untuk manajemen company level enterprise |

### Enum: `customer_type` (Customer)

| Nilai | Deskripsi |
| - | - |
| `individual` | Customer perorangan / konsumen akhir |
| `business` | Customer perusahaan / B2B |
| `retail` | Customer ritel / toko kecil |
| `reseller` | Reseller yang membeli untuk dijual kembali |
| `distributor` | Distributor yang mendistribusikan produk |
| `modern_market` | Customer dari pasar modern (minimarket, supermarket) |

### Enum: `status` (Customer)

| Nilai | Deskripsi |
| - | - |
| `lead` | Prospek baru yang belum di-follow up |
| `prospect` | Prospek yang sudah diidentifikasi potensinya |
| `customer` | Sudah menjadi customer aktif |
| `inactive` | Customer yang sudah tidak aktif |

### Enum: `product_type` (CompanyPOSProduct)

| Nilai | Deskripsi |
| - | - |
| `finished_good` | Produk jadi siap jual |
| `raw_material` | Bahan baku untuk produksi |
| `semi_finished` | Produk setengah jadi |
| `packaging_material` | Material kemasan/packaging |
| `bundle` | Paket bundle virtual (kumpulan beberapa SKU) |

### Enum: `packaging_type` (CompanyPOSProduct)

| Nilai | Deskripsi |
| - | - |
| `jar_glass` | Kemasan toples kaca |
| `pouch_zipper` | Kemasan pouch dengan zipper |
| `pouch_sealed` | Kemasan pouch sealed/segel |
| `toples_plastic` | Kemasan toples plastik |
| `bottle_plastic` | Kemasan botol plastik |
| `bulk` | Kemasan curah/bulk |
| `other` | Jenis kemasan lainnya |

### Enum: `storage_condition` (CompanyPOSProduct)

| Nilai | Deskripsi |
| - | - |
| `room_temperature` | Penyimpanan suhu ruang |
| `chilled` | Penyimpanan dingin (chiller) |
| `frozen` | Penyimpanan beku (freezer) |

## Tabel RBAC Lengkap (Role-Based Access Control)

| Role | Create | Read | Update | Delete | Export CSV | Deskripsi Akses |
| - | - | - | - | - | - | - |
| **Super Admin** | Ya | Ya | Ya | Ya | Ya | Akses penuh ke semua operasi live streaming, termasuk hapus data dan konfigurasi global |
| **Admin** | Ya | Ya | Ya | Ya | Ya | Akses penuh ke semua operasi live streaming dalam scope perusahaan |
| **Marketing Manager** | Ya | Ya | Ya | Ya | Ya | Akses penuh untuk mengelola strategi live streaming, termasuk hapus sesi yang tidak relevan |
| **Marketing Staff** | Ya | Ya | Ya | Tidak | Ya | Bisa membuat, melihat, dan mengedit sesi live streaming, tetapi tidak bisa menghapus |
| **Sales Manager** | Tidak | Ya | Tidak | Tidak | Ya | Hanya bisa melihat data dan leaderboard untuk monitoring performa tim sales |
| **Content Creator** | Ya | Ya | Tidak | Tidak | Tidak | Bisa membuat sesi live baru dan melihat data sendiri, tetapi tidak bisa edit atau hapus |

### Matriks Fitur per Role

| Fitur | Super Admin | Admin | Marketing Manager | Marketing Staff | Sales Manager | Content Creator |
| - | :-: | :-: | :-: | :-: | :-: | :-: |
| Lihat KPI Dashboard | Ya | Ya | Ya | Ya | Ya | Ya |
| Lihat Platform Breakdown | Ya | Ya | Ya | Ya | Ya | Ya |
| Lihat Top Products Leaderboard | Ya | Ya | Ya | Ya | Ya | Ya |
| Lihat Sales Person Leaderboard | Ya | Ya | Ya | Ya | Ya | Ya |
| Buat Sesi Live Baru | Ya | Ya | Ya | Ya | Tidak | Ya |
| Edit Sesi Live | Ya | Ya | Ya | Ya | Tidak | Tidak |
| Hapus Sesi Live | Ya | Ya | Ya | Tidak | Tidak | Tidak |
| Update Metrik (viewer, orders, revenue) | Ya | Ya | Ya | Ya | Tidak | Tidak |
| Export CSV | Ya | Ya | Ya | Ya | Ya | Tidak |
| Upload Screenshot | Ya | Ya | Ya | Ya | Tidak | Tidak |
| Input Recording Link | Ya | Ya | Ya | Ya | Tidak | Tidak |

## Catatan Teknis Implementasi

### Multi-Tenancy

Setiap entitas `LiveStreamingActivity` terikat ke `company_id` untuk isolasi data antar perusahaan. Query selalu di-filter berdasarkan `company_id` user yang sedang login (`active_company_id` dari entitas `User`).

### Auto-Calculated Fields

| Field | Formula | Kapan Dihitung |
| - | - | - |
| `duration_minutes` | `(end_time - start_time) / 60000` | Saat `end_time` diinput |
| `conversion_rate` | `(orders_count / avg_viewers) * 100` | Saat `orders_count` atau `avg_viewers` diupdate |

### Denormalisasi untuk Performa

Beberapa field disimpan secara denormalisasi untuk menghindari join query yang mahal:

| Field | Sumber Asli | Alasan Denormalisasi |
| - | - | - |
| `sales_person_name` | `User.full_name` | Menghindari join ke tabel User saat menampilkan daftar sesi |
| `promoted_product_names` | `CompanyPOSProduct.name` | Menghindari array join ke tabel Product saat menampilkan leaderboard |
| `platform_label` | Enum `platform` | Menyimpan label kustom untuk platform `other` |

### RLS (Row-Level Security)

Entitas `LiveStreamingActivity` menggunakan RLS dengan operasi `create`, `read`, `update`, dan `delete` yang semuanya aktif. Filter `company_id` diterapkan di level database untuk memastikan isolasi data multi-tenant.


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