# BAGIAN 5: RINGKASAN & TABEL REFERENSI
## Summary Tables & Database Schema

---

## 5.1 Ringkasan 5 Fitur Utama

| # | Fitur | Deskripsi Singkat | Kompleksitas |
|---|-------|-------------------|-------------|
| 1 | **Auth** | Autentikasi user dengan Better-Auth, session management, RBAC 3 role (owner/admin/member), forgot/reset password, API key authentication | Tinggi |
| 2 | **Chat** | Real-time omnichannel messaging (WhatsApp/Instagram/Telegram), conversation management (assign/resolve), message templates, file attachments, internal notes, office hours auto-response, profanity filter | Sangat Tinggi |
| 3 | **Campaign** | WhatsApp marketing campaign builder, template management (Meta Resumable API), recipient list dengan variable personalization, batch execution, delivery tracking | Tinggi |
| 4 | **Ticket** | Issue tracking terhubung dengan conversation/contact, full lifecycle (TODO → IN_PROGRESS → RESOLVED → DONE/REJECTED), attachment, status history, batch operations | Sedang |
| 5 | **Settings** | Konfigurasi workspace: user management, channel connection (WhatsApp Embedded Signup, Instagram Business Login), office hours, quick reply, API keys, tags, resolve categories, role permissions | Tinggi |

---

## 5.2 Technology Stack Comparison

| Layer | Frontend (FE) | Backend (BE) |
|-------|--------------|--------------|
| **Runtime** | Browser + Vite Dev Server | Bun (HTTP Server) |
| **Framework** | React 19.2 | Hono 4.10 |
| **Language** | TypeScript 5.9 | TypeScript |
| **UI Library** | MUI v7.3, Emotion | — |
| **State/Data** | SWR 2.3, React Context | — |
| **HTTP Client** | Axios 1.11 | Hono built-in |
| **Validation** | Zod 4.0 + @hookform/resolvers | Zod 4.1 + drizzle-zod |
| **Forms** | React Hook Form 7.62 | — |
| **ORM** | — | Drizzle ORM 0.44 |
| **Database** | — | PostgreSQL (pg driver) |
| **Auth** | better-auth client 1.3 | better-auth server 1.3 |
| **Real-time** | Pusher-js 8.4, Socket.io-client 4.8, react-use-websocket 4.13 | Pusher 5.2, Socket.IO 4.8 |
| **Message Queue** | — | RabbitMQ (amqplib 0.10) |
| **Routing** | react-router v7.8 | Hono router |
| **Rich Text** | TipTap v3, Quill 2.0 | — |
| **Charts** | ApexCharts 5.3 | — |
| **i18n** | i18next 25.3 | — |
| **Animations** | Framer Motion 12.23 | — |
| **PDF** | @react-pdf/renderer 4.3 | — |
| **Package Manager** | Yarn 4.12 | Bun |
| **Build Tool** | Vite 7.1 | Bun |
| **Process Manager** | PM2 (pm2.config.cjs) | PM2 (pm2.config.js) |
| **Container** | Docker | Docker |
| **CI/CD** | GitLab CI | GitLab CI |

---

## 5.3 Role-Based Access Control Matrix

| Menu / Fitur | owner | admin | member | Endpoint Pattern |
|---|:---:|:---:|:---:|---|
| **Login / Register** | ✓ | ✓ | ✓ | `/api/v1/auth/*` |
| **Dashboard — Chat** | ✓ | ✓ | ✓ | `/api/v1/u/conversations/*` |
| **Dashboard — Social Media** | ✓ | ✓ | ✓ | `/api/v1/u/posts/*` |
| **Dashboard — Campaign** | ✓ | ✓ | ✓ | `/api/v1/u/campaigns/*` |
| **Dashboard — Contact** | ✓ | ✓ | ✓ | `/api/v1/u/contacts/*` |
| **Dashboard — Tickets** | ✓ | ✓ | ✓ | `/api/v1/u/tickets/*` |
| **Settings — User Management** | ✓ | ✓ | ✗ | `/api/v1/auth/admin/*` |
| **Settings — Role & Permission** | ✓ | ✓ | ✗ | `/api/v1/u/role-permissions/*` |
| **Settings — Channel Management** | ✓ | ✓ | ✗ | `/api/v1/u/channels/*` |
| **Settings — Workspace Management** | ✓ | ✗ | ✗ | `/api/v1/u/workspaces/*` |
| **Settings — Workspace Members** | ✓ | ✓ | ✗ | `/api/v1/u/workspace-members/*` |
| **Settings — Tags** | ✓ | ✓ | ✗ | `/api/v1/u/tags/*` |
| **Settings — Office Hours** | ✓ | ✓ | ✗ | `/api/v1/u/office-hour-*` |
| **Settings — Quick Reply** | ✓ | ✓ | ✗ | `/api/v1/u/message-templates/*` |
| **Settings — API Keys** | ✓ | ✓ | ✗ | `/api/v1/u/workspace-api-keys/*` |
| **Settings — Resolve Category** | ✓ | ✓ | ✗ | `/api/v1/u/conversation-resolve-category/*` |
| **Settings — My Account** | ✓ | ✓ | ✓ | `/api/v1/u/user/*` |
| **Settings — Change Password** | ✓ | ✓ | ✓ | `/api/v1/auth/change-password` |

---

## 5.4 Complete API Endpoint Catalog

### Auth Endpoints (`/api/v1/auth/*`)

| Method | Endpoint | Auth | Deskripsi |
|--------|----------|------|-----------|
| POST | `/auth/sign-in/email-password` | None | Login |
| POST | `/auth/sign-up/email-password` | None | Register (disabled) |
| POST | `/auth/forget-password` | None | Lupa password |
| POST | `/auth/reset-password` | None | Reset password |
| POST | `/auth/change-password` | Session | Ganti password |
| GET | `/auth/get-session` | Session | Cek session |
| GET | `/auth/admin/list-users` | Session + Admin | List semua user |
| GET | `/auth/admin/get-user` | Session + Admin | Detail user |
| POST | `/auth/admin/create-user` | Session + Admin | Buat user |
| POST | `/auth/admin/update-user` | Session + Admin | Update user |
| POST | `/auth/admin/set-role` | Session + Admin | Set role user |
| POST | `/auth/admin/unban-user` | Session + Admin | Unban user |
| GET | `/auth/organization/list-members` | Session | List member org |
| POST | `/auth/organization/invite-member` | Session + Admin | Invite member |
| POST | `/auth/organization/update-member-role` | Session + Admin | Update role member |
| POST | `/auth/organization/remove-member` | Session + Admin | Hapus member |
| POST | `/auth/organization/accept-invitation` | Session | Terima invitation |
| POST | `/auth/api-key/create` | Session + Admin | Buat API key |

### Channel Endpoints (`/api/v1/u/channels`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/channels` | channel:read | List channels |
| GET | `/channels/with-unread-count` | channel:read | Channels + unread count |
| GET | `/channels/:id` | channel:read | Detail channel |
| POST | `/channels` | channel:create | Buat channel |
| PUT | `/channels/:id` | channel:update | Update channel |
| DELETE | `/channels/:id` | channel:delete | Hapus channel |
| POST | `/channels/:id/generate-webhook` | channel:update | Generate webhook token |
| POST | `/channels/whatsapp` | channel:create | Connect WhatsApp |
| GET | `/channels/whatsapp/get-access-token` | channel:read | Get WA access token |
| POST | `/channels/instagram` | channel:create | Connect Instagram |
| POST | `/channels/:id/upload-icon` | channel:update | Upload icon |

### Conversation Endpoints (`/api/v1/u/conversations`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/conversations` | conversation:read | List conversations |
| GET | `/conversations/total-counts-chat` | conversation:read | Total counts |
| GET | `/conversations/:id` | conversation:read | Detail conversation |
| GET | `/conversations/:id/history` | conversation:read | History chain |
| PATCH | `/conversations/:id/status` | conversation:update_status | Update status |
| PUT | `/conversations/:id/history` | — | Update resolve categories |
| POST | `/conversations/:id/read` | conversation:read | Mark as read |
| POST | `/conversations/get-new-chat` | conversation:update_status | Claim next chat |
| POST | `/conversations/bulk-resolve` | — | Bulk resolve |

### Message Endpoints (`/api/v1/u/conversation-messages`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/conversation-messages` | message:read | List messages |
| POST | `/conversation-messages` | message:create | Kirim pesan |
| POST | `/conversation-messages/template` | message:create | Kirim template |
| PUT | `/conversation-messages/:id/internal-note` | message:internal_note_update | Update note |
| DELETE | `/conversation-messages/:id/internal-note` | message:internal_note_update | Hapus note |
| POST | `/conversation-messages/upload-media` | message:create | Upload media |
| DELETE | `/conversation-messages/:id` | message:create | Hapus pesan |

### Campaign Endpoints (`/api/v1/u/campaigns`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/campaigns` | — | List campaigns |
| GET | `/campaigns/:id` | — | Detail campaign |
| POST | `/campaigns` | — | Buat campaign |
| PUT | `/campaigns/:id` | — | Update campaign |
| DELETE | `/campaigns/:id` | — | Hapus campaign |
| POST | `/campaigns/:id/execute` | — | Eksekusi campaign |

### Template Endpoints (`/api/v1/u/templates`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/templates` | template:read | List templates |
| GET | `/templates/:id` | template:read | Detail template |
| POST | `/templates` | template:create | Buat template |
| POST | `/templates/ticket` | template:create | Buat ticket template |
| PUT | `/templates/:id` | template:update | Update template |
| DELETE | `/templates/:id` | template:delete | Hapus template |
| POST | `/templates/upload-media` | template:create | Upload media (Meta API) |
| POST | `/templates/:id/sync` | template:create | Sync ke WhatsApp |

### Ticket Endpoints (`/api/v1/u/tickets`)

| Method | Endpoint | Permission | Deskripsi |
|--------|----------|-----------|-----------|
| GET | `/tickets` | ticket:read | List tickets |
| GET | `/tickets/:id` | ticket:read | Detail ticket |
| POST | `/tickets` | ticket:create | Buat ticket |
| PUT | `/tickets/:id` | ticket:update | Update ticket |
| DELETE | `/tickets/:id` | ticket:delete | Hapus ticket |
| POST | `/tickets/upload-media` | ticket:create | Upload media |
| DELETE | `/tickets/remove-media/:id` | — | Hapus media |

### Recipient List Endpoints

| Method | Endpoint | Deskripsi |
|--------|----------|-----------|
| GET | `/campaign-recipient-lists` | List recipient lists |
| GET | `/campaign-recipient-lists/:id` | Detail recipient list |
| POST | `/campaign-recipient-lists` | Buat recipient list |
| PUT | `/campaign-recipient-lists/:id` | Update recipient list |
| DELETE | `/campaign-recipient-lists/:id` | Hapus recipient list |
| GET | `/campaign-recipient-list-items` | List items |
| POST | `/campaign-recipient-lists/:id/contacts` | Tambah kontak |
| DELETE | `/campaign-recipient-lists/:id/contacts` | Hapus kontak |

---

## 5.5 Database Schema — Entity Relationship Diagram

```mermaid
erDiagram
    users {
        uuid user_id PK
        varchar user_email "NOT NULL, INDEXED"
        varchar user_username "NOT NULL, INDEXED"
        varchar user_fullname
        varchar user_phone
        boolean user_is_email_verified "default: false"
        varchar user_image_url
        varchar user_role
        boolean user_is_banned "default: false"
        text user_ban_reason
        timestamp user_ban_expires
        varchar user_status "OFFLINE / ONLINE"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
        uuid created_by "FK → users"
        uuid updated_by "FK → users"
        uuid deleted_by "FK → users"
    }

    workspaces {
        uuid workspace_id PK
        varchar workspace_name "NOT NULL"
        varchar workspace_slug "UNIQUE"
        varchar workspace_logo
        integer session_time "default: 604800 (7 days)"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
        uuid created_by "FK → users"
        uuid updated_by "FK → users"
        uuid deleted_by "FK → users"
    }

    workspace_members {
        uuid workspace_member_id PK
        uuid workspace_id FK "FK → workspaces, CASCADE"
        uuid user_id FK "FK → users, CASCADE"
        text workspace_member_role "default: member"
        varchar workspace_member_status "ACTIVE / INACTIVE / SUSPENDED"
        boolean is_developer "default: false"
        boolean is_devops "default: false"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    workspace_invitations {
        uuid workspace_invitation_id PK
        uuid workspace_id FK "FK → workspaces"
        varchar workspace_invitation_email
        varchar workspace_invitation_role
        varchar workspace_invitation_status "default: pending"
        boolean is_developer
        boolean is_devops
        timestamp expires_at
    }

    sessions {
        uuid session_id PK
        varchar session_token "UNIQUE"
        uuid session_active_workspace_id
        uuid user_id FK "FK → users, CASCADE"
        timestamp expires_at
    }

    api_keys {
        uuid id PK
        text name
        text start
        text prefix
        text key
        uuid user_id FK "FK → users"
        text permissions "JSON string"
        jsonb metadata "workspaceId, appName"
        boolean rate_limit_enabled
        integer rate_limit_time_window
        integer rate_limit_max
    }

    channels {
        uuid channel_id PK
        varchar channel_name "NOT NULL"
        varchar channel_code "WHATSAPP / INSTAGRAM / TELEGRAM / etc."
        varchar channel_icon
        varchar channel_platform_id
        varchar channel_waba_id
        text channel_api_token
        varchar channel_api_webhook_token
        varchar channel_status "ACTIVE / INACTIVE / MAINTENANCE"
        jsonb metadata
        jsonb channel_instagram_permission
        uuid workspace_id FK "FK → workspaces"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    member_channels {
        uuid member_channel_id PK
        uuid workspace_member_id FK "FK → workspace_members"
        uuid channel_id FK "FK → channels"
        timestamp created_at
    }

    contacts {
        uuid contact_id PK
        varchar contact_name "NOT NULL"
        varchar contact_phone "NOT NULL"
        varchar contact_username
        varchar contact_email
        varchar contact_location
        boolean contact_is_testing
        uuid channel_id FK "FK → channels"
        uuid workspace_id FK "FK → workspaces"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    tags {
        uuid tag_id PK
        varchar tag_name "UNIQUE"
        varchar tag_color "default: #3B82F6"
        uuid workspace_id FK "FK → workspaces"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    contact_tags {
        uuid contact_tag_id PK
        uuid contact_id FK "FK → contacts"
        uuid tag_id FK "FK → tags"
        timestamp created_at
    }

    conversations {
        uuid conversation_id PK
        uuid conversation_from
        uuid conversation_to
        varchar conversation_status "UNASSIGNED / ASSIGNED / RESOLVED / CLOSED"
        text conversation_last_message
        timestamp conversation_last_message_at
        boolean conversation_is_testing
        timestamp conversation_first_response_at
        uuid conversation_first_response_by
        timestamp conversation_24h_window_start
        timestamp conversation_24h_window_end
        uuid previous_conversation_id FK "self-ref (chain)"
        uuid assigned_to FK "FK → users"
        uuid assigned_by FK "FK → users"
        timestamp assigned_at
        timestamp resolved_at
        uuid resolved_by FK "FK → users"
        text resolved_description
        uuid channel_id FK "FK → channels"
        uuid contact_id FK "FK → contacts"
        varchar conversation_raw_id
        uuid read_by FK "FK → users"
        integer unread_counts "default: 0"
        varchar conversation_context "DM / POST_COMMENT / STORY_COMMENT"
        uuid instagram_post_id FK "FK → instagram_posts"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    conversation_messages {
        uuid conversation_message_id PK
        uuid conversation_id FK "FK → conversations"
        uuid conversation_message_from
        uuid conversation_message_to
        text conversation_message_content
        integer conversation_message_type_id FK "FK → conversation_message_types"
        boolean conversation_message_is_system "default: false"
        integer conversation_message_system_type_id FK "FK → conversation_message_system_types"
        varchar conversation_message_status "SENT / DELIVERED / READ / FAILED"
        uuid replied_to_message_id FK "self-ref (reply)"
        jsonb conversation_message_template_components
        boolean is_answered
        uuid answered_by
        timestamp answered_at
        uuid created_by FK "FK → users"
        timestamp created_at
        timestamp updated_at
    }

    message_attachments {
        uuid attachment_id PK
        uuid conversation_message_id FK "FK → conversation_messages, CASCADE"
        varchar attachment_file_name
        bigint file_size
        varchar mime_type
        varchar file_url
        varchar attachment_storage_type "LOCAL / S3 / GCS / AZURE"
        jsonb attachment_metadata
        timestamp expired_at
        timestamp created_at
    }

    conversation_message_reactions {
        uuid conversation_message_reaction_id PK
        uuid conversation_message_id FK "FK → conversation_messages"
        varchar reaction_type
        varchar emoji
        varchar sender_id
        timestamp created_at
    }

    tickets {
        uuid ticket_id PK
        uuid conversation_id FK "FK → conversations"
        varchar ticket_title "NOT NULL"
        text ticket_description "NOT NULL"
        text ticket_error_info
        varchar ticket_status "TODO / IN_PROGRESS / RESOLVED / DONE / REJECTED / DELETED"
        varchar ticket_number
        uuid assigned_to FK "FK → users"
        uuid assigned_by FK "FK → users"
        timestamp assigned_at
        uuid resolved_by FK "FK → users"
        timestamp resolved_at
        text resolved_note
        uuid rejected_by FK "FK → users"
        timestamp rejected_at
        text reject_reason
        uuid closed_by FK "FK → users"
        timestamp closed_at
        text reassign_note
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    ticket_attachments {
        uuid ticket_attachment_id PK
        uuid ticket_id FK "FK → tickets"
        varchar attachment_file_name
        bigint file_size
        varchar mime_type
        varchar file_url
        timestamp created_at
    }

    ticket_status_history {
        bigint ticket_status_history_id PK
        uuid ticket_id FK "FK → tickets"
        varchar old_status
        varchar new_status
        uuid updated_by FK "FK → users"
        uuid assigned_to FK "FK → users"
        uuid resolved_by FK "FK → users"
        uuid rejected_by FK "FK → users"
        timestamp created_at
    }

    templates {
        uuid template_id PK
        varchar template_name
        varchar template_language
        varchar template_category "MARKETING / UTILITY / AUTHENTICATION"
        varchar template_status "APPROVED / REJECTED / PENDING / PAUSED"
        varchar template_whatsapp_id
        jsonb template_components
        varchar template_quality_score "GREEN / YELLOW / RED / UNKNOWN"
        uuid channel_id FK "FK → channels"
        boolean template_is_used_in_campaign
        boolean template_is_ticket "default: false"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    campaigns {
        uuid campaign_id PK
        varchar campaign_name
        text campaign_description
        varchar campaign_status "DRAFT / SCHEDULED / RUNNING / COMPLETED / CANCELLED"
        uuid template_id FK "FK → templates"
        timestamp campaign_scheduled_at
        timestamp campaign_started_at
        timestamp campaign_completed_at
        integer campaign_total_recipients
        integer campaign_sent_count
        integer campaign_failed_count
        integer campaign_delivered_count
        integer campaign_read_count
        uuid channel_id FK "FK → channels"
        uuid workspace_id FK "FK → workspaces"
        uuid campaign_recipient_list_id FK "FK → campaign_recipient_lists"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    campaign_recipient_lists {
        uuid campaign_recipient_list_id PK
        varchar campaign_recipient_list_name
        text campaign_recipient_list_description
        jsonb campaign_recipient_list_variables
        uuid workspace_id FK "FK → workspaces"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    campaign_recipient_list_items {
        uuid campaign_recipient_list_item_id PK
        uuid campaign_recipient_list_id FK "FK → campaign_recipient_lists"
        uuid contact_id FK "FK → contacts"
        jsonb variable_values
        timestamp created_at
    }

    campaign_recipients {
        uuid campaign_recipient_id PK
        uuid campaign_id FK "FK → campaigns"
        uuid contact_id FK "FK → contacts"
        uuid conversation_id FK "FK → conversations"
        uuid conversation_message_id FK "FK → conversation_messages"
        varchar status "PENDING / SENT / DELIVERED / READ / FAILED"
        timestamp created_at
        timestamp updated_at
    }

    message_templates {
        serial message_template_id PK
        varchar message_template_name
        text message_template_content
        varchar message_template_shortcut
        uuid workspace_id FK "FK → workspaces"
        uuid channel_id FK "FK → channels"
        jsonb message_template_variables
        boolean message_template_is_global
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    notes {
        uuid note_id PK
        varchar note_title
        text note_description
        uuid workspace_id FK "FK → workspaces"
        uuid contact_id FK "FK → contacts"
        uuid created_by FK "FK → users"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    conversation_resolve_category {
        uuid resolve_category_id PK
        varchar resolve_category_name
        varchar resolve_category_color
        text resolve_category_description
        uuid workspace_id FK "FK → workspaces"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    conversation_resolve_categories {
        uuid conversation_resolve_category_id PK
        uuid conversation_id FK "FK → conversations"
        uuid resolve_category_id FK "FK → conversation_resolve_category"
        timestamp created_at
    }

    office_hours_schedule {
        uuid office_hours_schedule_id PK
        uuid workspace_id FK "FK → workspaces"
        integer day_of_week "0-6"
        time start_time
        time end_time
        varchar timezone
        boolean is_active "default: true"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    channel_office_hours_schedule {
        uuid channel_office_hours_schedule_id PK
        uuid channel_id FK "FK → channels"
        integer day_of_week "0-6"
        time start_time
        time end_time
        varchar timezone
        boolean is_active "default: true"
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    office_hours_auto_responses {
        uuid office_hours_auto_response_id PK
        uuid workspace_id FK "FK → workspaces"
        text during_office_hours_message
        text outside_office_hours_message
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    channel_office_hours_auto_responses {
        uuid channel_office_hours_auto_response_id PK
        uuid channel_id FK "FK → channels"
        text during_office_hours_message
        text outside_office_hours_message
        timestamp created_at
        timestamp updated_at
        timestamp deleted_at
    }

    users ||--o{ sessions : "has"
    users ||--o{ workspace_members : "belongs_to"
    users ||--o{ api_keys : "owns"
    users ||--o{ workspace_invitations : "invited by"
    workspaces ||--o{ workspace_members : "contains"
    workspaces ||--o{ channels : "has"
    workspaces ||--o{ tags : "has"
    workspaces ||--o{ office_hours_schedule : "has"
    workspaces ||--o{ office_hours_auto_responses : "has"
    workspaces ||--o{ campaigns : "has"
    workspaces ||--o{ message_templates : "has"
    workspaces ||--o{ conversation_resolve_category : "has"
    workspaces ||--o{ campaign_recipient_lists : "has"
    workspaces ||--o{ notes : "has"
    channels ||--o{ contacts : "receives"
    channels ||--o{ conversations : "has"
    channels ||--o{ templates : "has"
    channels ||--o{ campaigns : "uses"
    channels ||--o{ member_channels : "has"
    channels ||--o{ channel_office_hours_schedule : "has"
    channels ||--o{ channel_office_hours_auto_responses : "has"
    contacts ||--o{ conversations : "initiates"
    contacts ||--o{ contact_tags : "has"
    contacts ||--o{ campaign_recipient_list_items : "included in"
    contacts ||--o{ notes : "has"
    tags ||--o{ contact_tags : "applied to"
    conversations ||--o{ conversation_messages : "contains"
    conversations ||--o{ tickets : "generates"
    conversations ||--o{ conversation_resolve_categories : "categorized"
    conversations ||--o| conversations : "chained"
    conversation_messages ||--o{ message_attachments : "has"
    conversation_messages ||--o{ conversation_message_reactions : "has"
    conversation_messages ||--o| conversation_messages : "replies to"
    tickets ||--o{ ticket_attachments : "has"
    tickets ||--o{ ticket_status_history : "tracks"
    templates ||--o{ campaigns : "used by"
    campaigns ||--o{ campaign_recipients : "sends to"
    campaign_recipient_lists ||--o{ campaign_recipient_list_items : "contains"
    conversation_resolve_category ||--o{ conversation_resolve_categories : "links"
    workspace_members ||--o{ member_channels : "has access"
```

---

## 5.6 Statistik Final

| Metrik | Jumlah |
|--------|--------|
| **Total API Endpoints** | ~60+ |
| **Total Service Modules (BE)** | 47 |
| **Total Database Tables** | 30+ |
| **Total FE Component Files** | ~200+ |
| **Total FE Hooks** | ~30+ |
| **Total FE Pages** | ~40+ |
| **Chat Module Files (FE)** | 82 |
| **Campaign Module Files (FE)** | 33 |
| **Ticket Module Files (FE)** | 25 |
| **Settings Pages** | 20+ |
| **Auth Methods Supported** | 6 (better-auth active, 5备用) |
| **External Channel Integrations** | 3 active (WA, IG, TG) |
| **Real-time Mechanisms** | 3 (Pusher, Socket.IO, WebSocket) |
| **User Roles** | 3 (owner, admin, member) |
| **Permission Resources** | ~10 (channel, contact, conversation, message, ticket, template, campaign, tag, note, workspace) |
| **Conversation Statuses** | 4 (UNASSIGNED, ASSIGNED, RESOLVED, CLOSED) |
| **Ticket Statuses** | 6 (TODO, IN_PROGRESS, RESOLVED, DONE, REJECTED, DELETED) |
| **Campaign Statuses** | 5 (DRAFT, SCHEDULED, RUNNING, COMPLETED, CANCELLED) |

---

## 5.7 Daftar File Report

| # | File | Isi |
|---|------|-----|
| 1 | `00-EXECUTIVE-SUMMARY.md` | Ringkasan eksekutif, daftar isi, statistik |
| 2 | `01-OVERALL-ARCHITECTURE.md` | Arsitektur sistem, user journey, navigasi, data flow, multi-channel message flow |
| 3 | `02-INTEGRATION-FLOW.md` | API integration map, real-time flow, auth integration, file upload flow, middleware stack |
| 4 | `03-FE-FLOWCHARTS.md` | FE routing, auth flow, chat flow (82 files detail), campaign flow, ticket flow, settings flow, SWR data fetching pattern |
| 5 | `04-BE-FLOWCHARTS.md` | BE service architecture, auth RBAC, chat engine, conversation status, campaign execution, ticket lifecycle, webhook processing, service module pattern, error handling |
| 6 | `05-SUMMARY-TABLES.md` | Ringkasan fitur, tech stack, RBAC matrix, API catalog, database ERD, statistik final |
