# Kustomisasi Data & Konten


Halaman ini mencakup empat fitur pengaturan yang memungkinkan Admin menyesuaikan cara data kontak disimpan dan cara konten quick reply diorganisir di seluruh workspace.

---

## Custom Fields Kontak

**Rute frontend:** `/settings/custom-fields`

Custom fields adalah field tambahan yang dapat Anda definisikan dan lampirkan ke setiap kontak. Nilai disimpan sebagai JSONB di kolom `contacts.custom_fields` di PostgreSQL, dan divalidasi secara ketat terhadap tipe field saat disimpan.

### Tipe field yang tersedia

| Tipe | Nilai JSON yang valid | Catatan |
|------|-----------------------|---------|
| `text` | String | Teks bebas |
| `number` | Integer atau desimal | Contoh: `42`, `3.14` |
| `date` | String ISO-8601 | Contoh: `"2025-06-01"` atau `"2025-06-01T10:00:00Z"` |
| `boolean` | `true` / `false` | Bukan string `"true"` |
| `select` | String dari daftar opsi | Harus ada minimal 1 opsi |
| `multi_select` | Array string dari daftar opsi | Setiap elemen harus ada di opsi |
| `url` | String URL dengan skema | Harus diawali `http://` atau `https://` |
| `email` | String email valid | Harus mengandung `@` |
| `phone` | String nomor telepon | Tidak boleh kosong |

### Membuat custom field baru

1. Buka **Settings → Custom Fields**.
2. Klik **Add Field**.
3. Isi **Name** (maks 100 karakter) — field key akan di-generate otomatis dari nama.
4. Pilih **Type**. Untuk tipe `select` atau `multi_select`, tambahkan opsi satu per satu.
5. Centang **Required field** jika field wajib diisi sebelum nilai lain bisa disimpan ke kontak.
6. Klik **Create**.

:::note
**Field key** dibuat otomatis dari nama (snake_case, maks 64 karakter, hanya huruf kecil/digit/underscore, diawali huruf). Field key **tidak dapat diubah** setelah dibuat. Tipe field juga bersifat permanen — pilih dengan cermat.
:::

### Mengedit dan menonaktifkan

- Klik ikon **Edit** (pensil) untuk mengubah nama, deskripsi, status required, dan daftar opsi.
- Klik ikon **Delete** (tempat sampah) untuk menonaktifkan field (`is_active = false`). Data nilai yang sudah tersimpan di kontak tidak terhapus, tetapi field tidak akan muncul lagi di UI.
- Gunakan tombol panah atas/bawah untuk mengatur urutan tampil (`display_order`).

### Mengisi nilai custom field pada kontak

Buka detail kontak → tab **Profile fields**. Nilai dikirim via:

```http
PUT /api/contacts/{id}/custom-fields
Content-Type: application/json

{
  "fields": {
    "company_name": "Acme Corp",
    "tier": "gold",
    "is_vip": true
  }
}
```

Backend memvalidasi setiap key terhadap definisi aktif — key tidak dikenal atau nilai dengan tipe salah akan ditolak dengan HTTP 422. Nilai bersifat **merge** (tidak menghapus key yang tidak disertakan).

### Mencari kontak berdasarkan custom field

```http
GET /api/contacts/search-by-field?field_name=company_name&value=Acme&limit=50
```

Hasil berisi `contact_id`, `contact_name`, `contact_phone`, `field_name`, dan `field_value`. Parameter `limit` default 50, maksimum 200.

### Endpoint ringkasan

| Method | Path | Keterangan |
|--------|------|------------|
| `GET` | `/api/custom-fields` | Daftar semua definisi (urut `display_order`) |
| `POST` | `/api/custom-fields` | Buat definisi baru |
| `PATCH` | `/api/custom-fields/{id}` | Edit definisi |
| `DELETE` | `/api/custom-fields/{id}` | Nonaktifkan definisi |
| `GET` | `/api/contacts/{id}/custom-fields` | Baca nilai custom field kontak |
| `PUT` | `/api/contacts/{id}/custom-fields` | Simpan/merge nilai |
| `GET` | `/api/contacts/search-by-field` | Cari kontak berdasarkan nilai |

:::warning
Izin `contacts.manage` diperlukan untuk membuat, mengedit, dan menonaktifkan definisi, serta untuk menyimpan nilai ke kontak. Membaca definisi dan nilai cukup dengan `contacts.view`.
:::

---

## Tag Terkelola (Managed Tags)

**Rute frontend:** `/settings/managed-tags`

Managed tags adalah daftar tag standar workspace dengan warna yang dapat diterapkan ke kontak dan percakapan. Berbeda dengan tag bebas, managed tags memastikan konsistensi penamaan dan tampilan warna di seluruh tim.

### Atribut tag

| Field | Keterangan |
|-------|------------|
| `name` | Nama tag (wajib, tidak boleh kosong) |
| `color` | Hex color 7 karakter, contoh `#ef4444` (default `#6b7280`) |
| `description` | Deskripsi opsional untuk konteks tim |

### Mengelola tag

1. Buka **Settings → Managed Tags**.
2. Klik **New Tag** untuk membuat tag baru.
3. Isi nama, pilih warna via color picker atau ketik kode hex, tambahkan deskripsi opsional.
4. Klik **Create** — preview chip warna tampil secara langsung di form.
5. Untuk mengedit, klik ikon pensil pada kartu tag.
6. Untuk menghapus, klik ikon tempat sampah — konfirmasi dialog akan muncul. Penghapusan bersifat **permanen** dan akan melepas tag dari semua kontak yang menggunakannya.

:::warning
Menghapus managed tag akan melepas tag tersebut dari **semua kontak**. Pastikan tag memang sudah tidak digunakan sebelum menghapus.
:::

### Endpoint ringkasan

| Method | Path | Keterangan |
|--------|------|------------|
| `GET` | `/api/managed-tags` | Daftar semua tag (urut nama) |
| `POST` | `/api/managed-tags` | Buat tag baru (HTTP 201) |
| `PATCH` | `/api/managed-tags/{id}` | Edit tag |
| `DELETE` | `/api/managed-tags/{id}` | Hapus tag permanen |

:::tip
Gunakan warna yang konsisten secara semantik: merah untuk `urgent`, hijau untuk `vip`, abu-abu untuk `inactive`. Tim akan lebih cepat memindai status kontak dari warna tagnya.
:::

---

## Tanda Tangan Email (Email Signatures)

**Rute frontend:** `/settings/email-signatures`

Email signatures adalah tanda tangan HTML per-agent yang ditambahkan secara otomatis ke pesan email keluar. Setiap agent mengelola koleksi tanda tangannya sendiri — agent lain tidak dapat melihat atau mengubah tanda tangan milik agent lain.

### Atribut tanda tangan

| Field | Keterangan |
|-------|------------|
| `name` | Label tanda tangan (wajib), contoh: `"Work"`, `"Support"` |
| `body` | Konten HTML tanda tangan (wajib, tidak boleh kosong) |
| `is_default` | Bila `true`, tanda tangan ini otomatis dipilih saat mengirim email |

### Membuat tanda tangan

1. Buka **Settings → Email Signatures**.
2. Klik **Add Signature**.
3. Isi **Name** dan **Signature Body** dalam format HTML.
4. Aktifkan toggle **Set as default signature** bila ini yang ingin digunakan secara otomatis.
5. Klik **Create**.

:::note
Hanya **satu** tanda tangan yang dapat menjadi default per agent. Saat Anda menetapkan tanda tangan baru sebagai default, semua tanda tangan lain milik Anda akan dilepas status defaultnya secara otomatis.
:::

### Aturan kepemilikan

- Setiap agent hanya dapat melihat, mengedit, dan menghapus tanda tangan miliknya sendiri (`agent_id = claims.sub`).
- Backend menegakkan kepemilikan di level SQL — tidak ada risiko agent A menghapus tanda tangan agent B.
- Daftar terbatas 50 tanda tangan terbaru per agent.

### Format body HTML

Gunakan HTML standar. Contoh:

```html
<p>Salam hangat,<br/>
<strong>Budi Santoso</strong><br/>
Customer Support — OmniStream<br/>
<a href="tel:+62811000000">+62 811-000-000</a></p>
```

### Endpoint ringkasan

| Method | Path | Keterangan |
|--------|------|------------|
| `GET` | `/api/email-signatures` | Daftar tanda tangan milik agent yang login (maks 50) |
| `POST` | `/api/email-signatures` | Buat tanda tangan baru (HTTP 201) |
| `PUT` | `/api/email-signatures/{id}` | Update tanda tangan |
| `DELETE` | `/api/email-signatures/{id}` | Hapus tanda tangan |

---

## Kategori & Folder Quick Reply

**Rute frontend:** `/settings/quick-reply-categories`, `/settings/quick-reply-folders`

Quick reply dapat diorganisir melalui dua mekanisme berbeda: **kategori** (label teks pada quick reply) dan **folder** (struktur hierarki dengan dukungan parent-child). Keduanya memudahkan agent menemukan balasan yang tepat dari koleksi yang besar.

### Kategori

Kategori adalah label string yang melekat pada setiap quick reply. Satu quick reply hanya dapat memiliki satu kategori. Kategori dikelola di tabel `quick_reply_categories` dengan field `name` dan `sort_order`.

**Mengelola kategori:**

1. Buka **Settings → Quick Reply Categories**.
2. Klik **New Category**, isi nama dan sort order (angka, default 0 — lebih kecil = lebih atas).
3. Klik **Create**.
4. Tabel menampilkan nama, sort order, dan tanggal pembuatan.

:::note
Menghapus kategori **tidak menghapus** quick reply di dalamnya — quick reply tersebut menjadi tidak berkategori (`category = NULL`). Gunakan filter `__uncategorized__` di endpoint list untuk menemukan mereka kembali.
:::

Untuk mem-filter quick reply berdasarkan kategori saat menggunakan API:

```http
GET /api/quick-replies?category=greetings
GET /api/quick-replies?category=__uncategorized__
```

### Folder

Folder adalah struktur hierarki yang mendukung satu level nested (`parent_id`). Quick reply dapat ditempatkan di folder via field `folder_id`. Folder dikelola di tabel `quick_reply_folders`.

**Mengelola folder:**

1. Buka **Settings → Quick Reply Folders**.
2. Klik **New Folder**, isi nama dan sort order.
3. Klik **Create** — folder muncul sebagai kartu grid.
4. Saat mengedit folder, Anda dapat menetapkan `parent_id` untuk membuat subfolder.

:::note
Menghapus folder akan melepas semua quick reply dari folder tersebut (`folder_id = NULL`) sebelum folder dihapus — quick reply tidak ikut terhapus.
:::

### Endpoint ringkasan

| Method | Path | Keterangan |
|--------|------|------------|
| `GET` | `/api/quick-reply-categories` | Daftar kategori (urut `sort_order`, lalu `name`) |
| `POST` | `/api/quick-reply-categories` | Buat kategori (HTTP 201) |
| `PATCH` | `/api/quick-reply-categories/{id}` | Edit kategori |
| `DELETE` | `/api/quick-reply-categories/{id}` | Hapus kategori |
| `GET` | `/api/quick-reply-folders` | Daftar folder (urut `sort_order`, lalu `name`) |
| `POST` | `/api/quick-reply-folders` | Buat folder |
| `PATCH` | `/api/quick-reply-folders/{id}` | Edit folder |
| `DELETE` | `/api/quick-reply-folders/{id}` | Hapus folder (quick reply dilepas, tidak dihapus) |

### Perbedaan kategori vs folder

| Aspek | Kategori | Folder |
|-------|----------|--------|
| Struktur | Flat (label string) | Hierarki (parent-child) |
| Filter API | `?category=nama` | Via `folder_id` pada quick reply |
| Efek hapus | Quick reply menjadi `NULL` kategori | Quick reply `folder_id` di-set `NULL` |
| Penggunaan | Pengelompokan semantik (`sales`, `support`) | Organisasi navigasi (subfolder per tim/divisi) |

:::tip
Untuk tim kecil, kategori sudah cukup. Gunakan folder bila Anda memiliki ratusan quick reply dan perlu navigasi bertingkat, misalnya `Support → Billing → Refund`.
:::

Lihat juga: [Quick Replies](/panduan/agent/quick-replies), [Manajemen Kontak](/panduan/agent/kontak).
