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

# Partnership

<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: "Partnership"
description: "Portal partnership dengan AI content generation, multi-type partnership, application management, dan admin CMS di SNISHOP ERP."
---------------------------------------------------------------------------------------------------------------------------------------------

# Partnership

<img src="https://mintcdn.com/quinnofspicy/e4f_upKhVWcjsUmM/docs/mintlify/screenshots/marketing/partnership.png?fit=max&auto=format&n=e4f_upKhVWcjsUmM&q=85&s=664b29e26d30f58a46768b8b522982a0" alt="Partnership" width="1920" height="1080" data-path="docs/mintlify/screenshots/marketing/partnership.png" />

Halaman Partnership adalah portal publik untuk mengelola hubungan kerjasama bisnis — mulai dari B2B, reseller, affiliate, hingga bentuk partnership lainnya. Dibangun di atas `PartnershipPage.jsx` (463 baris) dengan admin CMS yang didukung **AI content generation** via InvokeLLM.

Admin bisa mengelola jenis-jenis partnership, konten halaman, dan meninjau aplikasi partnership baru yang masuk dari calon partner.

## Arsitektur Komponen

```mermaid theme={null}
graph TD
    A[PartnershipPage.jsx<br/>463 lines] --> B[Hero Section]
    A --> C[Partnership Types]
    A --> D[Application Form]
    A --> E[Testimonials]
    A --> F[Stats Display]
    A --> G[PartnershipContentTab<br/>606 lines]
    A --> H[PartnershipApplicationsTab]
    G --> I[AI Content Assistant<br/>InvokeLLM]
    G --> J[Icon Selector<br/>12 icons]
    G --> K[CRUD Partnership Types]
    D --> L[PartnershipApplication Entity]
    A --> M[PartnerDistributorDashboard]
```

## Entity Schema

### PartnershipContent

| Field | Tipe | Deskripsi |
| - | - | - |
| `id` | UUID | Primary key |
| `partnership_types` | array | Daftar jenis partnership |
| `hero_title` | string | Judul hero section |
| `hero_description` | string | Deskripsi hero |
| `contact_email` | string | Email kontak |
| `contact_whatsapp` | string | Nomor WhatsApp kontak |
| `is_active` | boolean | Status aktif |
| `company_id` | FK → Company | Multi-tenant scoping |
| `created_at` | Timestamp | Waktu pembuatan |
| `updated_at` | Timestamp | Waktu update terakhir |

### Partnership Type Object

| Field | Tipe | Deskripsi |
| - | - | - |
| `icon` | string | Icon name (12 pilihan) |
| `title` | string | Nama jenis partnership |
| `description` | string | Deskripsi jenis |
| `commission` | string | Skema komisi |
| `benefits` | string\[] | Daftar manfaat |
| `requirements` | string\[] | Syarat partnership |
| `min_order` | number | Minimum order (opsional) |

### PartnershipApplication

| Field | Tipe | Deskripsi |
| - | - | - |
| `id` | UUID | Primary key |
| `company_name` | string | Nama perusahaan pelamar |
| `contact_name` | string | Nama kontak |
| `contact_email` | string | Email kontak |
| `contact_phone` | string | Nomor telepon |
| `partnership_type` | string | Jenis partnership yang dilamar |
| `business_description` | string | Deskripsi bisnis |
| `target_market` | string | Target pasar |
| `expected_volume` | string | Estimasi volume |
| `proposal_url` | string | Link proposal (Cloudinary) |
| `website_url` | string | Website perusahaan |
| `status` | string | `submitted`, `reviewing`, `approved`, `rejected` |
| `review_notes` | string | Catatan review dari admin |
| `reviewed_by` | FK → User | Admin yang review |
| `reviewed_at` | Timestamp | Waktu review |
| `company_id` | FK → Company | Multi-tenant scoping |
| `created_at` | Timestamp | Waktu submit |

## 12 Icon Options

| Icon | Kegunaan |
| - | - |
| `Store` | Reseller, toko |
| `Zap` | Fast partnership |
| `Users` | Komunitas |
| `Briefcase` | B2B, korporat |
| `Target` | Sales target |
| `Handshake` | Kerjasama umum |
| `Users2` | Tim, kelompok |
| `TrendingUp` | Growth partner |
| `Award` | Premium partner |
| `Rocket` | Startup partner |
| `Star` | Featured partner |
| `Crown` | Top-tier partner |

## AI Content Assistant

Admin CMS menggunakan AI untuk generate konten partnership:

```mermaid theme={null}
sequenceDiagram
    participant Admin
    participant ContentTab
    participant InvokeLLM

    Admin->>ContentTab: Input brief + tone
    ContentTab->>InvokeLLM: Structured JSON schema
    Note over InvokeLLM: Tone: professional/casual/persuasive
    InvokeLLM-->>ContentTab: Generated content
    ContentTab->>ContentTab: Auto-fill form
```

### Tone Options

| Tone | Deskripsi |
| - | - |
| `professional` | Formal, cocok untuk B2B |
| `casual` | Santai, cocok untuk reseller/affiliate |
| `persuasive` | Menjual, cocok untuk landing page |

### AI Prompt Structure

```mermaid theme={null}
flowchart TD
    A[Admin Input] --> B[Brief + Tone]
    B --> C[Build Prompt]
    C --> D[JSON Schema]
    D --> E[InvokeLLM]
    E --> F[Parse Response]
    F --> G[Validate Structure]
    G --> H[Auto-fill Form]
```

## Application Flow

```mermaid theme={null}
sequenceDiagram
    participant CalonPartner
    participant PartnershipPage
    participant Cloudinary
    participant Base44

    CalonPartner->>PartnershipPage: Isi form aplikasi
    CalonPartner->>Cloudinary: Upload proposal
    Cloudinary-->>PartnershipPage: file_url
    PartnershipPage->>Base44: Create PartnershipApplication
    Note over Base44: status = 'submitted'
    Base44-->>Admin: Notifikasi aplikasi baru
    Admin->>Admin: Review & approve/reject
```

### Application Status Flow

```mermaid theme={null}
stateDiagram-v2
    [*] --> Submitted: Calon partner submit
    Submitted --> Reviewing: Admin mulai review
    Reviewing --> Approved: Admin approve
    Reviewing --> Rejected: Admin reject
    Approved --> [*]: Partnership aktif
    Rejected --> [*]: Tidak lanjut
```

## Static Partner Stats

| Metrik | Nilai |
| - | - |
| Active Partners | 150+ |
| Revenue Shared | Rp 2.5B+ |
| Satisfaction | 98% |
| Countries | 5 |

## Testimonials

| Partner | Deskripsi |
| - | - |
| PT Maju Bersama | Testimonial B2B |
| CV Digital Nusantara | Testimonial digital |
| Startup Hub ID | Testimonial startup |

## Integrasi

| Layanan | Fungsi |
| - | - |
| **Cloudinary** | Upload proposal dokumen |
| **InvokeLLM** | Generate konten partnership |
| **WhatsApp** | Deep link ke WhatsApp kontak |
| **Email** | Mailto link ke kontak |

## RBAC

| Halaman | Akses |
| - | - |
| Partnership landing | Publik |
| Submit application | Memerlukan login |
| Admin CMS | Admin/Owner |

## Cara Akses

Dari sidebar, klik menu **Marketing** > **Partnership**.

## Flow Penggunaan

1. Calon partner buka halaman Partnership — lihat hero section dan jenis-jenis partnership
2. Pilih jenis partnership yang diminati (B2B, reseller, affiliate, dll)
3. Isi form aplikasi dengan data perusahaan dan upload proposal
4. Submit aplikasi — status awal `submitted`
5. Admin menerima notifikasi dan review aplikasi di `PartnershipApplicationsTab`
6. Admin approve atau reject dengan catatan
7. Partner yang di-approve mendapat akses ke portal sesuai jenis partnership

## Tips

* Buat perjanjian kerjasama yang jelas di awal untuk menghindari kesalahpahaman di kemudian hari
* Review performa partner setiap bulan dan berikan feedback yang konstruktif
* Gunakan AI content assistant untuk generate deskripsi partnership yang persuasif dan profesional
* Berikan materi promosi yang up-to-date agar partner mudah menjual produk kamu
* Track aplikasi partnership secara berkala — jangan biarkan terlalu lama dalam status `submitted`
* Berikan onboarding yang jelas untuk partner baru agar mereka cepat produktif

***

## Diagram Relasi Entitas (ERD)

Berikut adalah diagram relasi antar entitas yang terlibat dalam modul Partnership:

```mermaid theme={null}
erDiagram
    User ||--o{ PartnershipApplication : "mengajukan"
    User ||--o{ CompanyMember : "menjadi anggota"
    User ||--o{ ReferralCode : "memiliki"
    User ||--o{ Referral : "merujuk (referrer)"
    User ||--o{ Referral : "dirujuk (referee)"
    User ||--o{ Commission : "menerima komisi"
    User ||--o{ Subscription : "berlangganan"
    User ||--o{ UpgradeRequest : "mengajukan upgrade"

    Company ||--o{ CompanyMember : "memiliki anggota"
    Company ||--o{ PartnershipContent : "mengelola konten"

    PartnershipApplication }o--|| Company : "terkait perusahaan"
    PartnershipApplication }o--|| User : "direview oleh"

    ReferralCode }o--|| User : "dimiliki oleh"
    Referral }o--|| User : "referrer"
    Referral }o--|| User : "referee"

    Commission }o--|| User : "penerima"
    Commission }o--|| UpgradeRequest : "berasal dari"

    ReferralSetting }o--|| Subscription : "konfigurasi komisi per plan"

    User {
        string id PK
        string email UK
        string full_name
        string role
        string subscription_plan
        string admin_type
        string admin_tier
        number balance
        number commission_balance
        string referral_code
        string referred_by
    }

    Company {
        string id PK
        string name
        string owner_id FK
        string owner_email
        string industry
        string owner_subscription_plan
    }

    CompanyMember {
        string id PK
        string company_id FK
        string user_id FK
        string user_email
        string role
        string status
    }

    PartnershipApplication {
        string id PK
        string company_name
        string contact_name
        string contact_email
        string partnership_type
        string status
        string reviewed_by FK
    }

    PartnershipContent {
        string id PK
        string hero_title
        string hero_description
        string contact_email
        string contact_whatsapp
        boolean is_active
    }

    ReferralSetting {
        string id PK
        string plan_key
        number first_purchase_commission_rate
        number renewal_commission_rate
    }

    Referral {
        string id PK
        string referrer_id FK
        string referee_id FK
        string referee_email
        string status
    }

    ReferralCode {
        string id PK
        string code UK
        string user_id FK
        string user_email
        boolean is_active
    }

    Commission {
        string id PK
        string referrer_id FK
        string referee_id FK
        string purchase_id FK
        number purchase_amount
        number commission_rate
        number commission_amount
        string purchase_type
        string status
    }

    Subscription {
        string id PK
        string user_id FK
        string company_id FK
        string service_name
        number cost
        string billing_cycle
        string status
    }

    UpgradeRequest {
        string id PK
        string user_id FK
        string user_email
        string requested_plan
        string status
        number price_paid
    }
```

***

## Schema Entitas Lengkap

### PartnershipApplication

Entitas untuk menyimpan aplikasi partnership baru dari calon partner.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `company_name` | string | Ya | Nama perusahaan atau individu yang mengajukan aplikasi partnership |
| `contact_name` | string | Ya | Nama lengkap kontak person dari calon partner |
| `contact_email` | string | Ya | Alamat email kontak untuk komunikasi partnership |
| `contact_phone` | string | Tidak | Nomor telepon kontak person calon partner |
| `partnership_type` | enum | Ya | Tipe partnership yang diinginkan: `reseller`, `integration`, `community`, `strategic` |
| `business_description` | string | Ya | Deskripsi singkat bisnis atau produk calon partner |
| `description` | string | Tidak | Penjelasan rinci mengenai proposal kemitraan, nilai yang ditawarkan, dan rencana kerja sama (maks 1000 karakter) |
| `target_market` | string | Tidak | Target pasar atau customer base dari calon partner |
| `expected_volume` | string | Tidak | Estimasi volume penjualan atau jumlah user base yang diharapkan |
| `proposal_url` | string | Tidak | URL file proposal atau presentasi yang diunggah via Cloudinary |
| `website_url` | string | Tidak | Alamat website resmi perusahaan calon partner |
| `social_media` | object | Tidak | Kumpulan tautan media sosial (instagram, linkedin, facebook) |
| `status` | enum | Tidak | Status aplikasi partnership: `submitted`, `reviewing`, `negotiation`, `approved`, `rejected` (default: `submitted`) |
| `admin_notes` | string | Tidak | Catatan internal admin selama proses review aplikasi |
| `meeting_link` | string | Tidak | Tautan meeting online untuk diskusi partnership |
| `meeting_date` | date-time | Tidak | Tanggal dan waktu meeting yang dijadwalkan |
| `contract_url` | string | Tidak | URL dokumen kontrak partnership (diisi jika aplikasi disetujui) |
| `commission_rate` | number | Tidak | Persentase komisi yang disepakati (khusus untuk tipe reseller) |
| `reviewed_by` | string | Tidak | Email admin yang melakukan review aplikasi |
| `reviewed_date` | date-time | Tidak | Tanggal dan waktu review dilakukan |

### PartnershipContent

Entitas untuk menyimpan konten halaman landing partnership yang dikelola via admin CMS.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `hero_title` | string | Ya | Judul utama pada hero section halaman partnership (default: "Partnership Program") |
| `hero_description` | string | Tidak | Deskripsi pada hero section halaman partnership |
| `why_partner_title` | string | Tidak | Judul section "Mengapa Bermitra" (default: "Mengapa Bermitra dengan SNISHOP?") |
| `why_partner_stats` | array | Tidak | Daftar statistik partnership (nilai dan label) untuk ditampilkan di halaman |
| `partnership_types` | array | Tidak | Daftar tipe-tipe partnership yang tersedia (reseller, integration, community, strategic) |
| `success_stories` | array | Tidak | Daftar kisah sukses partner yang sudah bergabung |
| `how_it_works` | array | Tidak | Daftar langkah-langkah cara kerja program partnership |
| `contact_email` | string | Tidak | Alamat email kontak untuk partnership (default: [partnership@snishop.com](mailto:partnership@snishop.com)) |
| `contact_whatsapp` | string | Tidak | Nomor WhatsApp kontak untuk partnership (default: 081532168812) |
| `is_active` | boolean | Tidak | Status aktif konten halaman partnership (default: true) |

### Partnership Type Object (Nested)

Objek bersarang di dalam field `partnership_types` pada PartnershipContent.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `icon` | string | Tidak | Nama icon dari 12 pilihan yang tersedia (Store, Zap, Users, dll) |
| `title` | string | Tidak | Nama atau judul jenis partnership |
| `description` | string | Tidak | Deskripsi lengkap jenis partnership |
| `commission` | string | Tidak | Skema komisi yang ditawarkan (misal: "20-30%", "Revenue Share") |
| `benefits` | array\[string] | Tidak | Daftar manfaat yang didapat partner |

### Success Story Object (Nested)

Objek bersarang di dalam field `success_stories` pada PartnershipContent.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `partner_name` | string | Tidak | Nama partner yang memberikan testimonial |
| `partner_type` | string | Tidak | Tipe partnership yang dijalankan partner |
| `quote` | string | Tidak | Kutipan testimonial dari partner |
| `result` | string | Tidak | Hasil atau pencapaian yang diraih bersama |

### How It Works Object (Nested)

Objek bersarang di dalam field `how_it_works` pada PartnershipContent.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `step` | number | Tidak | Nomor urutan langkah |
| `title` | string | Tidak | Judul langkah (misal: "Daftar", "Review", "Onboarding", "Launch") |
| `description` | string | Tidak | Penjelasan detail langkah tersebut |

### Company

Entitas perusahaan yang menjadi scope multi-tenant untuk partnership.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `name` | string | Ya | Nama perusahaan |
| `owner_id` | string | Ya | ID user pemilik perusahaan |
| `owner_email` | string | Ya | Email pemilik perusahaan |
| `owner_subscription_plan` | enum | Tidak | Plan langganan pemilik: `free`, `pro`, `business`, `advanced`, `enterprise` |
| `description` | string | Tidak | Deskripsi singkat perusahaan |
| `industry` | enum | Tidak | Sektor industri: `retail`, `manufacturing`, `services`, `technology`, `food_beverage`, `healthcare`, `education`, `other` |
| `address` | string | Tidak | Alamat fisik perusahaan |
| `phone` | string | Tidak | Nomor telepon perusahaan |
| `email` | string | Tidak | Alamat email perusahaan |
| `website` | string | Tidak | Alamat website perusahaan |
| `logo_url` | string | Tidak | URL logo perusahaan |
| `tax_id` | string | Tidak | Nomor NPWP perusahaan |
| `employee_count` | number | Tidak | Jumlah karyawan (default: 0) |
| `metadata` | object | Tidak | Data tambahan atau legacy |
| `landing_page_config` | object | Tidak | Konfigurasi landing page perusahaan (tema, konten, pembayaran) |
| `business_type` | string | Tidak | Kategori bisnis yang dipilih saat onboarding |
| `active_modules` | string | Tidak | JSON string berisi daftar ID modul yang aktif |
| `settings` | object | Tidak | Pengaturan perusahaan (jam kerja, kebijakan cuti, pajak, dll) |

### CompanyMember

Entitas keanggotaan perusahaan yang menghubungkan user dengan perusahaan dan menentukan role serta permission.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `company_id` | string | Ya | ID perusahaan tempat anggota bergabung |
| `user_id` | string | Tidak | ID user yang menjadi anggota |
| `user_email` | string | Ya | Email user yang menjadi anggota |
| `user_name` | string | Tidak | Nama lengkap user |
| `role` | enum | Tidak | Role dalam perusahaan (default: `employee`) |
| `employee_id` | string | Tidak | Tautan ke entitas Employee |
| `department` | string | Tidak | Departemen tempat anggota bekerja |
| `position` | string | Tidak | Jabatan atau posisi anggota |
| `status` | enum | Tidak | Status keanggotaan: `active`, `inactive`, `pending` (default: `active`) |
| `joined_date` | date | Tidak | Tanggal bergabung dalam perusahaan |
| `invited_by` | string | Tidak | Email pengguna yang mengundang anggota ini |
| `permissions` | object | Tidak | Hak akses detail untuk member (lihat tabel permission di bawah) |
| `assigned_locations` | array\[string] | Tidak | Daftar ID lokasi gudang/outlet yang diizinkan untuk member |
| `working_hours` | object | Tidak | Jam kerja karyawan (start, end) |
| `salary` | number | Tidak | Gaji karyawan (opsional) |
| `notes` | string | Tidak | Catatan tambahan mengenai anggota |

### User

Entitas pengguna sistem yang dapat menjadi pengaju partnership, admin reviewer, atau referrer.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `email` | string | Ya | Alamat email pengguna |
| `full_name` | string | Ya | Nama lengkap pengguna |
| `role` | enum | Tidak | Role pengguna dalam aplikasi: `admin`, `user` |
| `subscription_plan` | enum | Tidak | Plan langganan: `free`, `pro`, `business`, `advanced`, `enterprise` (default: `free`) |
| `subscription_start` | date-time | Tidak | Tanggal mulai langganan aktif |
| `subscription_end` | date-time | Tidak | Tanggal berakhirnya langganan |
| `membership_duration_type` | enum | Tidak | Tipe durasi membership: `monthly`, `yearly`, `custom`, `lifetime` |
| `membership_start_date` | date | Tidak | Tanggal mulai membership |
| `membership_end_date` | date | Tidak | Tanggal berakhir membership |
| `is_readonly_mode` | boolean | Tidak | Mode read-only saat expired dalam grace period 3 hari (default: false) |
| `trial_end` | date-time | Tidak | Tanggal berakhir masa percobaan |
| `active_company_id` | string | Tidak | ID perusahaan yang sedang aktif untuk pengguna Business+ |
| `company_slots_purchased` | number | Tidak | Slot perusahaan tambahan yang dibeli di luar batas plan (default: 0) |
| `ai_monthly_usage` | number | Tidak | Penggunaan AI bulanan (default: 0) |
| `ai_credits` | number | Tidak | Kredit AI yang tersedia (default: 10) |
| `ai_addon_quota` | number | Tidak | Kuota addon AI (default: 0) |
| `ai_usage_period_start` | date | Tidak | Tanggal awal periode penggunaan AI |
| `last_credit_reset` | date-time | Tidak | Tanggal terakhir reset kredit AI |
| `storage_used` | number | Tidak | Penyimpanan yang digunakan (default: 0) |
| `referred_by` | string | Tidak | Kode referral dari pengguna yang merujuk |
| `referral_code` | string | Tidak | Kode referral milik pengguna ini |
| `balance` | number | Tidak | Saldo deposit untuk membeli membership/addon (default: 0) |
| `commission_balance` | number | Tidak | Saldo komisi dari referral yang dapat ditarik (default: 0) |
| `admin_commission_balance` | number | Tidak | Saldo komisi admin basic dari proses transaksi (default: 0) |
| `total_earnings` | number | Tidak | Total komisi yang pernah diterima secara akumulasi (default: 0) |
| `admin_type` | enum | Tidak | Tipe admin aplikasi: `owner` (full access) atau `basic` (hanya transaksi digital) |
| `admin_tier` | enum | Tidak | Tier admin untuk company management: `none`, `business`, `advanced`, `enterprise` (default: `none`) |
| `productivity_score` | number | Tidak | Skor produktivitas pengguna (default: 0) |
| `current_streak` | number | Tidak | Streak hari berturut-turut menyelesaikan tugas (default: 0) |
| `longest_streak` | number | Tidak | Streak terpanjang yang pernah dicapai (default: 0) |
| `last_active_date` | date | Tidak | Tanggal terakhir pengguna aktif |
| `total_tasks_completed` | number | Tidak | Total tugas yang telah diselesaikan (default: 0) |
| `total_notes_created` | number | Tidak | Total catatan yang telah dibuat (default: 0) |
| `achievement_points` | number | Tidak | Poin pencapaian pengguna (default: 0) |
| `user_level` | number | Tidak | Level pengguna berdasarkan achievement points (default: 1) |
| `trial_plan` | string | Tidak | Plan percobaan yang pernah dipilih |
| `trial_expires` | date-time | Tidak | Tanggal berakhirnya masa percobaan |
| `trial_used` | object | Tidak | Track plan percobaan yang sudah pernah digunakan |
| `preferences` | object | Tidak | Preferensi pengguna (theme, primary\_color, wallpaper\_url, referral\_modal\_dismissed) |

### ReferralSetting

Entitas konfigurasi komisi referral per plan langganan.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `plan_key` | string | Ya | Kunci paket langganan terkait (misal: `free`, `pro`, `business`) |
| `description` | string | Tidak | Penjelasan pengaturan komisi referral untuk paket ini (maks 1000 karakter) |
| `first_purchase_commission_rate` | number | Ya | Persentase komisi untuk pembelian pertama (default: 0.50 = 50%) |
| `renewal_commission_rate` | number | Ya | Persentase komisi untuk pembelian selanjutnya/renewal (default: 0.10 = 10%) |

### Referral

Entitas yang mencatat hubungan referral antara pengundang dan yang diundang.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `referrer_id` | string | Ya | ID pengguna yang mengundang (referrer) |
| `referee_id` | string | Ya | ID pengguna yang diundang (referee) |
| `referee_email` | string | Ya | Alamat email pengguna yang diundang |
| `referee_name` | string | Tidak | Nama lengkap pengguna yang diundang |
| `description` | string | Tidak | Catatan tambahan mengenai referral ini (maks 1000 karakter) |
| `status` | enum | Tidak | Status undangan: `signed_up`, `purchased` (default: `signed_up`) |

### ReferralCode

Entitas kode referral unik yang dimiliki setiap pengguna untuk mengajak orang lain bergabung.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `code` | string | Ya | Kode referral unik (8 karakter) |
| `user_id` | string | Ya | ID user pemilik kode referral |
| `user_email` | string | Tidak | Email user pemilik kode |
| `user_name` | string | Tidak | Nama user pemilik kode |
| `description` | string | Tidak | Catatan atau pesan promosi yang menyertai kode referral (maks 1000 karakter) |
| `is_active` | boolean | Tidak | Status aktif kode referral (default: true) |

### Commission

Entitas yang mencatat transaksi komisi referral dari pembelian yang berhasil.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `referrer_id` | string | Ya | ID pengguna yang menerima komisi (referrer) |
| `referee_id` | string | Ya | ID pengguna yang melakukan pembelian (referee) |
| `purchase_id` | string | Tidak | ID dari transaksi pembelian terkait (misal: ID UpgradeRequest) |
| `purchase_amount` | number | Ya | Jumlah pembelian yang menjadi dasar perhitungan komisi |
| `commission_rate` | number | Ya | Persentase komisi yang diterapkan pada pembelian |
| `commission_amount` | number | Ya | Jumlah nominal komisi yang didapat |
| `plan_purchased` | string | Tidak | Paket langganan yang dibeli (misal: Pro, Business) |
| `purchase_type` | enum | Tidak | Jenis pembelian: `first_time`, `renewal` |
| `description` | string | Tidak | Catatan detail mengenai komisi ini (maks 1000 karakter) |
| `status` | enum | Tidak | Status komisi: `unpaid`, `paid_to_balance`, `rejected` (default: `unpaid`) |

### Subscription

Entitas langganan layanan yang dapat menjadi objek revenue sharing partnership.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `user_id` | string | Ya | ID pengguna pemilik langganan |
| `company_id` | string | Tidak | ID perusahaan (null untuk langganan personal) |
| `service_name` | string | Ya | Nama layanan atau produk yang berlangganan |
| `cost` | number | Ya | Biaya langganan per periode |
| `currency` | string | Tidak | Mata uang (default: IDR) |
| `billing_cycle` | enum | Tidak | Siklus penagihan: `weekly`, `monthly`, `quarterly`, `yearly` (default: `monthly`) |
| `next_due_date` | date | Ya | Tanggal jatuh tempo pembayaran berikutnya |
| `start_date` | date | Tidak | Tanggal mulai langganan |
| `end_date` | date | Tidak | Tanggal akhir langganan (jika ada) |
| `status` | enum | Tidak | Status langganan: `active`, `paused`, `cancelled` (default: `active`) |
| `payment_method` | string | Tidak | Metode pembayaran yang digunakan |
| `auto_renew` | boolean | Tidak | Apakah langganan otomatis diperpanjang (default: true) |
| `notes` | string | Tidak | Catatan tambahan mengenai langganan |

### UpgradeRequest

Entitas pengajuan upgrade plan yang menjadi pemicu perhitungan komisi referral.

| Field | Tipe | Required | Deskripsi |
| - | - | - | - |
| `user_id` | string | Ya | ID pengguna yang mengajukan upgrade |
| `user_email` | string | Ya | Email pengguna yang mengajukan |
| `user_full_name` | string | Tidak | Nama lengkap pengguna |
| `requested_plan` | enum | Ya | Plan yang diajukan: `pro`, `advanced`, `enterprise`, `business` |
| `proof_image_url` | string | Ya | URL gambar bukti pembayaran |
| `status` | enum | Tidak | Status pengajuan: `pending`, `approved`, `rejected` (default: `pending`) |
| `admin_notes` | string | Tidak | Catatan admin terkait pengajuan |
| `description` | string | Tidak | Catatan atau alasan pengajuan upgrade dari pengguna (maks 1000 karakter) |
| `billing_period` | enum | Tidak | Periode penagihan: `monthly`, `yearly` |
| `price_paid` | number | Tidak | Harga final setelah diskon voucher |
| `original_price` | number | Tidak | Harga asli sebelum diskon voucher |
| `voucher_code_used` | string | Tidak | Kode voucher yang digunakan (jika ada) |
| `balance_used` | number | Tidak | Jumlah saldo komisi yang digunakan untuk membayar (default: 0) |

***

## Siklus Hidup Partnership (State Diagram)

```mermaid theme={null}
stateDiagram-v2
    [*] --> Submitted: Calon partner mengirim aplikasi

    Submitted --> Reviewing: Admin mulai meninjau aplikasi

    Reviewing --> Negotiation: Admin membutuhkan diskusi lanjutan
    Reviewing --> Approved: Aplikasi disetujui admin
    Reviewing --> Rejected: Aplikasi ditolak admin

    Negotiation --> Approved: Kesepakatan tercapai setelah negosiasi
    Negotiation --> Rejected: Negosiasi gagal

    Approved --> Active: Partner onboarded dan kontrak ditandatangani
    Active --> Suspended: Partner melanggar ketentuan
    Active --> Terminated: Kontrak berakhir atau partner mengundurkan diri

    Suspended --> Active: Setelah evaluasi dan perbaikan
    Suspended --> Terminated: Pelanggaran berat tidak dapat diperbaiki

    Rejected --> [*]: Proses berakhir
    Terminated --> [*]: Proses berakhir

    note right of Submitted: Status default saat aplikasi baru masuk
    note right of Reviewing: Admin memeriksa kelengkapan data
    note right of Negotiation: Diskusi detail kerjasama via meeting
    note right of Approved: Aplikasi disetujui, menunggu onboarding
    note right of Active: Partnership berjalan aktif
    note right of Suspended: Partnership dibekukan sementara
    note right of Terminated: Partnership dihentikan secara permanen
```

***

## Diagram Sekuens (Sequence Diagrams)

### 1. Alur Pengajuan Aplikasi Partnership

```mermaid theme={null}
sequenceDiagram
    participant CP as Calon Partner
    participant PP as PartnershipPage.jsx
    participant CLD as Cloudinary
    participant B44 as Base44 Backend
    participant ADM as Admin

    CP->>PP: Membuka halaman Partnership
    PP->>B44: GET PartnershipContent (hero, types, stats)
    B44-->>PP: Return konten halaman
    PP-->>CP: Tampilkan hero section & tipe partnership

    CP->>PP: Memilih tipe partnership & mengisi form
    CP->>CLD: Upload dokumen proposal
    CLD-->>PP: Return proposal_url

    PP->>PP: Validasi field required (company_name, contact_name, contact_email, partnership_type, business_description)
    PP->>B44: POST PartnershipApplication
    Note over B44: status = 'submitted'
    B44-->>PP: Return created application
    PP-->>CP: Konfirmasi aplikasi berhasil dikirim

    B44->>ADM: Notifikasi aplikasi partnership baru
    ADM->>B44: GET PartnershipApplication (filter: status=submitted)
    B44-->>ADM: Daftar aplikasi baru
```

### 2. Alur Review dan Approval Aplikasi Partnership

```mermaid theme={null}
sequenceDiagram
    participant ADM as Admin
    participant B44 as Base44 Backend
    participant CP as Calon Partner
    participant NT as Notifikasi

    ADM->>B44: GET PartnershipApplication (list)
    B44-->>ADM: Daftar aplikasi partnership

    ADM->>ADM: Meninjau detail aplikasi & proposal
    ADM->>B44: PATCH PartnershipApplication (status: reviewing)
    B44-->>ADM: Updated

    alt Membutuhkan negosiasi
        ADM->>B44: PATCH PartnershipApplication (status: negotiation, meeting_link, meeting_date)
        B44->>NT: Kirim notifikasi ke calon partner
        NT->>CP: Undangan meeting diskusi partnership
        CP->>ADM: Meeting diskusi & negosiasi
        ADM->>B44: PATCH PartnershipApplication (status: approved, commission_rate, contract_url)
    else Langsung approve
        ADM->>B44: PATCH PartnershipApplication (status: approved, admin_notes, reviewed_by, reviewed_date)
    else Reject
        ADM->>B44: PATCH PartnershipApplication (status: rejected, admin_notes, reviewed_by, reviewed_date)
    end

    B44->>NT: Kirim notifikasi hasil review
    NT->>CP: Hasil review aplikasi partnership
```

### 3. Alur Revenue Sharing via Referral Commission

```mermaid theme={null}
sequenceDiagram
    participant RF as Referrer (Partner)
    participant RR as Referee (Calon User)
    participant B44 as Base44 Backend
    participant RS as ReferralSetting
    participant COM as Commission Entity
    participant USR as User Entity

    RF->>B44: GET ReferralCode (milik referrer)
    B44-->>RF: Return kode referral unik

    RF->>RR: Membagikan kode referral
    RR->>B44: Registrasi dengan kode referral
    B44->>B44: CREATE Referral (referrer_id, referee_id, status: signed_up)
    B44->>USR: UPDATE User (referred_by = kode referral)

    RR->>B44: POST UpgradeRequest (belanja plan)
    B44->>B44: Verifikasi pembayaran
    B44->>B44: UPDATE Referral (status: purchased)

    B44->>RS: GET ReferralSetting (plan_key = plan yang dibeli)
    RS-->>B44: Return first_purchase_commission_rate / renewal_commission_rate

    B44->>B44: Hitung commission_amount = purchase_amount x commission_rate
    B44->>COM: CREATE Commission (referrer_id, referee_id, purchase_amount, commission_rate, commission_amount, purchase_type, status: unpaid)

    B44->>USR: UPDATE User.commission_balance += commission_amount
    B44->>COM: UPDATE Commission (status: paid_to_balance)

    B44->>USR: UPDATE User.total_earnings += commission_amount
```

### 4. Alur Referral Tracking dan Code Generation

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant B44 as Base44 Backend
    participant RC as ReferralCode
    participant REF as Referral
    participant RS as ReferralSetting

    U->>B44: Registrasi akun baru
    B44->>B44: Generate kode referral unik (8 karakter)
    B44->>RC: CREATE ReferralCode (code, user_id, user_email, user_name, is_active: true)
    B44->>U: Return kode referral

    U->>U: Membagikan kode referral ke teman/kolega

    Note over U,RC: Teman mendaftar menggunakan kode referral

    U->>B44: GET Referral (filter: referrer_id = user.id)
    B44-->>U: Daftar referral yang diundang

    U->>B44: GET Commission (filter: referrer_id = user.id)
    B44-->>U: Riwayat komisi yang diterima

    U->>B44: GET User (commission_balance, total_earnings)
    B44-->>U: Saldo komisi dan total penghasilan

    Note over U,RS: Admin mengelola konfigurasi komisi per plan
    B44->>RS: GET/PUT ReferralSetting (plan_key, rates)
    RS-->>B44: Return konfigurasi komisi
```

***

## Referensi Enum dan Status

### partnership\_type (PartnershipApplication)

| Nilai | Deskripsi |
| - | - |
| `reseller` | Partnership tipe reseller — menjual lisensi SNISHOP dan mendapatkan komisi recurring |
| `integration` | Partnership tipe integrasi — mengintegrasikan produk pihak ketiga dengan platform SNISHOP |
| `community` | Partnership tipe komunitas — membangun komunitas dan event bersama SNISHOP |
| `strategic` | Partnership tipe strategis — kerjasama bisnis strategis jangka panjang |

### status (PartnershipApplication)

| Nilai | Deskripsi |
| - | - |
| `submitted` | Aplikasi baru saja dikirim oleh calon partner dan menunggu review admin |
| `reviewing` | Aplikasi sedang dalam proses peninjauan oleh admin |
| `negotiation` | Admin dan calon partner sedang dalam tahap negosiasi dan diskusi |
| `approved` | Aplikasi telah disetujui oleh admin, menunggu proses onboarding |
| `rejected` | Aplikasi ditolak oleh admin dengan catatan penolakan |

### role (CompanyMember)

| Nilai | Deskripsi |
| - | - |
| `owner` | Pemilik perusahaan dengan akses penuh ke semua fitur |
| `admin` | Administrator dengan akses luas ke manajemen perusahaan |
| `supervisor` | Supervisor yang mengawasi operasional |
| `store_admin` | Admin toko/khusus untuk manajemen outlet |
| `stock_admin` | Admin stok untuk manajemen inventori |
| `finance_admin` | Admin keuangan untuk pengelolaan finansial |
| `hr_admin` | Admin HR untuk pengelolaan sumber daya manusia |
| `transaction_admin` | Admin transaksi untuk mengelola transaksi |
| `employee` | Karyawan biasa dengan akses terbatas (default) |
| `production_operator` | Operator produksi untuk manajemen batch produksi |
| `qc_inspector` | Inspector quality control untuk verifikasi kualitas |
| `sales_marketing` | Staff sales dan marketing untuk pengelolaan penjualan |
| `partner_distributor` | Distributor partner untuk akses portal partnership |

### status (CompanyMember)

| Nilai | Deskripsi |
| - | - |
| `active` | Anggota aktif dan dapat mengakses sistem |
| `inactive` | Anggota nonaktif, akses ditangguhkan |
| `pending` | Anggota baru diundang dan belum menerima/menyetujui |

### role (User)

| Nilai | Deskripsi |
| - | - |
| `admin` | Pengguna dengan hak akses administrator sistem |
| `user` | Pengguna biasa dengan akses standar |

### subscription\_plan (User / Company)

| Nilai | Deskripsi |
| - | - |
| `free` | Plan gratis dengan fitur dasar |
| `pro` | Plan profesional dengan fitur lanjutan |
| `business` | Plan bisnis dengan fitur lengkap untuk tim |
| `advanced` | Plan advanced dengan fitur premium |
| `enterprise` | Plan enterprise dengan akses penuh dan prioritas support |

### admin\_type (User)

| Nilai | Deskripsi |
| - | - |
| `owner` | Admin pemilik — memiliki akses penuh ke seluruh aplikasi |
| `basic` | Admin basic — hanya dapat melakukan transaksi produk digital |

### admin\_tier (User)

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

### industry (Company)

| Nilai | Deskripsi |
| - | - |
| `retail` | Industri ritel dan perdagangan |
| `manufacturing` | Industri manufaktur dan produksi |
| `services` | Industri jasa dan layanan |
| `technology` | Industri teknologi dan perangkat lunak |
| `food_beverage` | Industri makanan dan minuman |
| `healthcare` | Industri kesehatan dan medis |
| `education` | Industri pendidikan dan pelatihan |
| `other` | Industri lainnya |

### status (Referral)

| Nilai | Deskripsi |
| - | - |
| `signed_up` | Referee telah mendaftar menggunakan kode referral referrer |
| `purchased` | Referee telah melakukan pembelian plan berbayar |

### purchase\_type (Commission)

| Nilai | Deskripsi |
| - | - |
| `first_time` | Pembelian pertama kali — dikenakan first\_purchase\_commission\_rate |
| `renewal` | Pembelian perpanjangan — dikenakan renewal\_commission\_rate |

### status (Commission)

| Nilai | Deskripsi |
| - | - |
| `unpaid` | Komisi belum dibayarkan ke saldo referrer |
| `paid_to_balance` | Komisi telah dibayarkan ke saldo komisi referrer |
| `rejected` | Komisi ditolak (misal karena pelanggaran atau pembatalan) |

### billing\_cycle (Subscription)

| Nilai | Deskripsi |
| - | - |
| `weekly` | Penagihan mingguan |
| `monthly` | Penagihan bulanan (default) |
| `quarterly` | Penagihan per kuartal (3 bulan) |
| `yearly` | Penagihan tahunan |

### status (Subscription)

| Nilai | Deskripsi |
| - | - |
| `active` | Langganan aktif dan berjalan normal |
| `paused` | Langganan dijeda sementara oleh pengguna |
| `cancelled` | Langganan telah dibatalkan |

### requested\_plan (UpgradeRequest)

| Nilai | Deskripsi |
| - | - |
| `pro` | Pengajuan upgrade ke plan Pro |
| `advanced` | Pengajuan upgrade ke plan Advanced |
| `enterprise` | Pengajuan upgrade ke plan Enterprise |
| `business` | Pengajuan upgrade ke plan Business |

### status (UpgradeRequest)

| Nilai | Deskripsi |
| - | - |
| `pending` | Pengajuan menunggu verifikasi admin |
| `approved` | Pengajuan disetujui dan plan telah diupgrade |
| `rejected` | Pengajuan ditolak oleh admin |

### membership\_duration\_type (User)

| Nilai | Deskripsi |
| - | - |
| `monthly` | Durasi membership bulanan |
| `yearly` | Durasi membership tahunan |
| `custom` | Durasi membership kustom sesuai kesepakatan |
| `lifetime` | Durasi membership seumur hidup |

***

## RBAC Permission Matrix — Partnership Module

Tabel berikut menunjukkan hak akses berdasarkan role CompanyMember terhadap fitur-fitur di modul Partnership:

| Fitur | owner | admin | supervisor | partner\_distributor | employee |
| - | - | - | - | - | - |
| Lihat halaman landing partnership | ✅ | ✅ | ✅ | ✅ | ✅ |
| Submit aplikasi partnership | ✅ | ✅ | ✅ | ❌ | ❌ |
| Lihat daftar PartnershipApplication | ✅ | ✅ | ✅ | ❌ | ❌ |
| Review aplikasi partnership | ✅ | ✅ | ❌ | ❌ | ❌ |
| Approve/reject aplikasi | ✅ | ✅ | ❌ | ❌ | ❌ |
| Edit konten PartnershipContent (CMS) | ✅ | ✅ | ❌ | ❌ | ❌ |
| Generate konten via AI (InvokeLLM) | ✅ | ✅ | ❌ | ❌ | ❌ |
| Atur ReferralSetting | ✅ | ❌ | ❌ | ❌ | ❌ |
| Lihat kode referral pribadi | ✅ | ✅ | ✅ | ✅ | ✅ |
| Lihat riwayat komisi | ✅ | ✅ | ❌ | ✅ | ❌ |
| Tarik saldo komisi ke balance | ✅ | ✅ | ❌ | ✅ | ❌ |
| Kelola CompanyMember permissions | ✅ | ✅ | ❌ | ❌ | ❌ |
| Lihat statistik partner | ✅ | ✅ | ✅ | ❌ | ❌ |
| Atur meeting & negosiasi | ✅ | ✅ | ❌ | ❌ | ❌ |
| Upload kontrak partnership | ✅ | ✅ | ❌ | ❌ | ❌ |

### Permission Flags (CompanyMember.permissions)

Berikut adalah daftar flag permission yang relevan dengan modul partnership dan referral:

| Permission Flag | Default | Deskripsi |
| - | - | - |
| `can_view_dashboard` | `true` | Dapat melihat dashboard utama perusahaan |
| `can_view_tasks` | `true` | Dapat melihat daftar tugas |
| `can_create_tasks` | `true` | Dapat membuat tugas baru |
| `can_edit_tasks` | `true` | Dapat mengedit tugas yang ada |
| `can_delete_tasks` | `false` | Dapat menghapus tugas |
| `can_view_notes` | `true` | Dapat melihat catatan |
| `can_create_notes` | `true` | Dapat membuat catatan baru |
| `can_edit_notes` | `true` | Dapat mengedit catatan |
| `can_delete_notes` | `false` | Dapat menghapus catatan |
| `can_view_hr` | `false` | Dapat melihat modul HR |
| `can_edit_hr` | `false` | Dapat mengedit data HR |
| `can_view_finance` | `false` | Dapat melihat modul keuangan |
| `can_edit_finance` | `false` | Dapat mengedit data keuangan |
| `can_view_inventory` | `false` | Dapat melihat modul inventori |
| `can_edit_inventory` | `false` | Dapat mengedit data inventori |
| `can_view_projects` | `false` | Dapat melihat modul proyek |
| `can_edit_projects` | `false` | Dapat mengedit data proyek |
| `can_view_pos` | `false` | Dapat melihat modul POS |
| `can_use_pos` | `false` | Dapat menggunakan kasir POS |
| `can_view_reports` | `false` | Dapat melihat laporan |
| `can_manage_members` | `false` | Dapat mengelola anggota perusahaan |
| `can_manage_roles` | `false` | Dapat mengelola role dan permission |
| `can_view_settings` | `false` | Dapat melihat pengaturan perusahaan |
| `can_edit_settings` | `false` | Dapat mengedit pengaturan perusahaan |
| `can_manage_cashier_shift` | `false` | Dapat mengelola shift kasir |
| `can_approve_stock_opname` | `false` | Dapat menyetujui stock opname |
| `can_count_stock_opname` | `false` | Dapat melakukan penghitungan stock opname |
| `can_transfer_inventory` | `false` | Dapat melakukan transfer inventori |
| `can_create_production_batch` | `false` | Dapat membuat batch produksi |
| `can_release_production_qc` | `false` | Dapat merilis hasil QC produksi |
| `can_view_hpp` | `false` | Dapat melihat perhitungan HPP |
| `can_manage_channel_pricing` | `false` | Dapat mengelola harga per channel |
| `can_view_distribution` | `false` | Dapat melihat modul distribusi |
| `can_create_distribution_shipment` | `false` | Dapat membuat pengiriman distribusi |
| `can_confirm_distribution_shipment` | `false` | Dapat mengonfirmasi pengiriman distribusi |
| `can_view_b2b_invoices` | `false` | Dapat melihat invoice B2B |
| `can_create_b2b_invoice` | `false` | Dapat membuat invoice B2B |
| `can_verify_b2b_payment` | `false` | Dapat memverifikasi pembayaran B2B |

***

## Integrasi Data Partnership

```mermaid theme={null}
flowchart LR
    subgraph Frontend
        A[PartnershipPage.jsx<br/>463 lines]
        B[PartnershipContentTab<br/>606 lines]
        C[PartnershipApplicationsTab]
        D[PartnerDistributorDashboard]
    end

    subgraph Backend Entities
        E[PartnershipContent]
        F[PartnershipApplication]
        G[ReferralSetting]
        H[ReferralCode]
        I[Referral]
        J[Commission]
        K[User]
        L[Company]
        M[CompanyMember]
    end

    subgraph External Services
        N[Cloudinary<br/>Upload proposal]
        O[InvokeLLM<br/>AI content generation]
        P[WhatsApp<br/>Deep link kontak]
    end

    A --> E
    A --> F
    A --> N
    B --> E
    B --> O
    C --> F
    D --> H
    D --> I
    D --> J
    F --> K
    F --> L
    J --> K
    J --> G
    I --> K
    H --> K
    M --> L
    M --> K
    A --> P
```

## Catatan Teknis

* **Multi-tenant**: PartnershipContent dan PartnershipApplication di-scope berdasarkan company. Setiap perusahaan dapat memiliki konfigurasi partnership yang berbeda.
* **AI Content Generation**: Admin CMS menggunakan InvokeLLM dengan JSON schema untuk menghasilkan konten partnership yang terstruktur. Tone dapat dipilih: `professional`, `casual`, atau `persuasive`.
* **Cloudinary Upload**: Proposal partnership diunggah ke Cloudinary dan URL-nya disimpan di field `proposal_url`.
* **Commission Calculation**: Komisi dihitung berdasarkan `ReferralSetting` yang dikonfigurasi per plan. Pembelian pertama menggunakan `first_purchase_commission_rate`, renewal menggunakan `renewal_commission_rate`.
* **Balance Integration**: Komisi yang sudah dibayarkan (`paid_to_balance`) ditambahkan ke `User.commission_balance` dan dapat digunakan untuk membeli membership atau addon.
* **Role `partner_distributor`**: Role khusus di CompanyMember yang memberikan akses ke PartnerDistributorDashboard untuk melihat kode referral dan riwayat komisi.


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