# Manajemen & Performa Agent


Halaman ini membahas tiga fitur di menu **Settings** yang digunakan admin untuk mengatur operasional tim: jadwal jam kerja workspace, target kinerja (goals) per-agent, dan tag keahlian agent untuk keperluan skill-based routing.

:::info
**Hak akses:** Ketiga fitur ini memerlukan peran **supervisor** atau **admin**. Manajemen goals dan skills memerlukan izin `agents.manage` — hanya **supervisor** dan **admin** yang memilikinya. Agent reguler hanya dapat melihat goals dan progres mereka sendiri.
:::

---

## Jam Kerja (Working Hours)

Halaman `/settings/working-hours` mengatur jadwal operasional workspace: hari apa saja bisnis buka, jam berapa mulai dan tutup, serta zona waktu yang digunakan. Status **Currently Open / Currently Closed** ditampilkan secara langsung (real-time) di header halaman berdasarkan jadwal dan waktu saat ini.

### Konsep: Global vs. Override Divisi

OmniStream mendukung dua lapisan jadwal:

| Lapisan | Keterangan |
|---|---|
| **Global** | Jadwal default seluruh workspace. Digunakan jika tidak ada override divisi. |
| **Override Divisi** | Jadwal khusus per-divisi yang menggantikan jadwal global untuk divisi tersebut. |

Pilih scope di dropdown **Scope**:
- `Global (Default)` — mengedit jadwal global.
- Nama divisi — mengedit atau membuat override untuk divisi tersebut.

Jika divisi belum memiliki override, UI akan menampilkan *"Using global schedule — save to create a division override."* Menyimpan jadwal pada konteks divisi secara otomatis membuat override.

Tombol **Reset to Global** muncul jika divisi memiliki override aktif. Mengkliknya menghapus override sehingga divisi kembali mengikuti jadwal global.

### Mengatur Zona Waktu

Zona waktu disimpan di tabel `app_settings` dengan `key = 'timezone'` dan berlaku untuk seluruh workspace. Default-nya adalah `UTC` jika belum dikonfigurasi.

1. Pilih zona waktu di dropdown **Timezone**.
2. Klik **Save** (tombol di sebelah kanan dropdown).
3. Status open/closed akan diperbarui menggunakan zona waktu baru.

Zona waktu yang tersedia di UI antara lain: `Asia/Jakarta`, `Asia/Makassar`, `Asia/Jayapura`, `Asia/Singapore`, `Asia/Kuala_Lumpur`, `Asia/Bangkok`, `Asia/Tokyo`, `Asia/Shanghai`, `Europe/London`, `Europe/Berlin`, `America/New_York`, `America/Los_Angeles`, dan beberapa lainnya.

### Mengatur Jadwal Harian

Jadwal terdiri dari 7 baris (Senin–Minggu). Setiap baris memiliki:
- **Toggle on/off** — aktifkan hari tersebut.
- **Jam mulai** dan **jam tutup** dalam format `HH:MM` (24 jam).

**Quick Presets** tersedia untuk mengisi jadwal cepat:

| Preset | Hari Aktif | Jam |
|---|---|---|
| **Weekdays 9-5** | Senin–Jumat | 09:00–17:00 |
| **Weekdays 8-6** | Senin–Jumat | 08:00–18:00 |
| **24/7** | Semua hari | 00:00–23:59 |
| **Custom** | Manual | Manual |

UI menampilkan total jam operasional per minggu secara otomatis (dihitung dari jadwal aktif). Klik **Save Working Hours** untuk menyimpan.

:::warning
Jam tutup harus lebih besar dari jam mulai — backend memvalidasi format `HH:MM` dan menolak nilai yang tidak valid. Status `is_working_hours` di status endpoint menggunakan logika `start_time <= now < end_time` (inklusif di awal, eksklusif di akhir).
:::

### Endpoint (tag **Working Hours**)

| Aksi | Endpoint |
|---|---|
| Lihat jadwal global | `GET /api/working-hours` |
| Simpan jadwal global | `PUT /api/working-hours` |
| Lihat jadwal divisi | `GET /api/working-hours/divisions/{id}` |
| Simpan override divisi | `PUT /api/working-hours/divisions/{id}` |
| Hapus override divisi | `DELETE /api/working-hours/divisions/{id}` |
| Cek status open/closed | `GET /api/working-hours/status` |
| Lihat timezone | `GET /api/settings/timezone` |
| Update timezone | `PUT /api/settings/timezone` |

Response `GET /api/working-hours/status`:

```json
{
  "is_working_hours": true,
  "timezone": "Asia/Jakarta",
  "current_time": "14:30",
  "next_change_at": "2026-06-08T10:00:00Z"
}
```

`next_change_at` adalah waktu transisi berikutnya (buka → tutup atau tutup → buka) dalam format RFC3339 UTC.

---

## Target Agent (Agent Goals)

Halaman `/settings/agent-goals` memungkinkan supervisor dan admin menetapkan target KPI kuantitatif per-agent. Setiap goal terdiri dari metrik, nilai target, dan periode pengukuran. Progres dihitung otomatis oleh backend dari data aktual di PostgreSQL dan MongoDB.

### Cara Menggunakan

1. Buka `/settings/agent-goals`.
2. Pilih agent dari daftar di panel kiri.
3. Goals yang sudah ada akan muncul di panel kanan beserta progress bar aktual.
4. Klik **+ Add Goal** untuk membuat goal baru.

### Membuat Goal Baru

Isi tiga field pada form:

| Field | Tipe | Pilihan |
|---|---|---|
| **Metric** | Pilihan | Lihat tabel metrik di bawah |
| **Target** | Angka | Nilai target (desimal didukung) |
| **Period** | Pilihan | `daily`, `weekly`, `monthly` |

Goal baru aktif secara default (`is_active = true`).

### Metrik yang Tersedia

| Metrik | Keterangan | Sumber Data |
|---|---|---|
| `conversations_resolved` | Jumlah percakapan yang diselesaikan | PostgreSQL `conversations` |
| `avg_first_response_seconds` | Rata-rata waktu respons pertama (detik) | PostgreSQL `conversations` |
| `avg_resolution_seconds` | Rata-rata waktu penyelesaian (detik) | PostgreSQL `conversations` |
| `csat_average` | Rata-rata rating CSAT (1–5) | PostgreSQL `csat_surveys` |
| `messages_sent` | Jumlah pesan outbound yang dikirim | MongoDB `messages` |
| `active_conversations` | Percakapan aktif saat ini (open/pending) | PostgreSQL `conversations` |

Periode pengukuran:
- **daily** — mulai dari 00:00 hari ini (UTC).
- **weekly** — mulai dari Senin 00:00 minggu ini (UTC).
- **monthly** — mulai dari tanggal 1 bulan ini (UTC).

### Progress Bar

Untuk setiap goal aktif, UI menampilkan progress bar dengan:
- Nilai saat ini vs. nilai target.
- Persentase progres (max 100%).
- Warna indikator: **hijau** ≥ 80%, **kuning** ≥ 50%, **merah** < 50%.

Goal dianggap *on track* jika progres ≥ 50%.

Untuk metrik waktu (`avg_first_response_seconds`, `avg_resolution_seconds`), nilai ditampilkan dalam format yang mudah dibaca: `30s`, `5m`, `2h 15m`.

### Mengubah Status Goal

Klik **Deactivate** / **Activate** pada kartu goal untuk menonaktifkan atau mengaktifkan kembali sebuah goal tanpa menghapusnya. Goal yang tidak aktif tidak muncul di kalkulasi progres.

:::tip
Gunakan kombinasi `conversations_resolved` (weekly) dan `avg_first_response_seconds` bersama CSAT untuk review kinerja mingguan yang lebih akurat. Satu metrik saja mudah menipu — lihat juga [Kinerja Agent & Review CSAT](/panduan/supervisor/kinerja-agent).
:::

:::warning
Menghapus goal bersifat permanen. Konfirmasi dialog akan muncul sebelum penghapusan dieksekusi.
:::

### Endpoint (tag **Agent Goals**)

| Aksi | Endpoint |
|---|---|
| List semua goals | `GET /api/agent-goals` |
| List goals per-agent | `GET /api/agent-goals/{agent_id}/goals` |
| Buat goal baru | `POST /api/agent-goals` |
| Update goal | `PATCH /api/agent-goals/{id}` |
| Hapus goal | `DELETE /api/agent-goals/{id}` |
| Progres goal sendiri | `GET /api/agent-goals/progress` |
| Progres goal per-agent | `GET /api/agent-goals/{agent_id}/progress` |

Contoh request membuat goal:

```json
{
  "agent_id": "uuid-agent",
  "metric": "conversations_resolved",
  "target_value": 50,
  "period": "weekly"
}
```

Contoh response progres:

```json
{
  "goals": [
    {
      "id": "uuid-goal",
      "agent_id": "uuid-agent",
      "metric": "conversations_resolved",
      "target_value": 50.0,
      "period": "weekly",
      "is_active": true,
      "current_value": 32.0,
      "progress_pct": 64.0,
      "on_track": true
    }
  ]
}
```

---

## Keahlian Agent (Agent Skills)

Halaman `/settings/agent-skills` menampilkan ringkasan keahlian (skill tags) yang telah ditetapkan ke agent di seluruh workspace. Skills digunakan sebagai label kemampuan agent — misalnya `"English"`, `"Technical Support"`, atau `"Billing"` — yang dapat dijadikan dasar routing percakapan secara manual.

### Ringkasan Skill di Settings

Halaman ini menampilkan daftar semua skill yang ada beserta jumlah agent yang memilikinya, diurutkan dari yang paling banyak digunakan:

| Kolom | Keterangan |
|---|---|
| **Skill Name** | Nama tag keahlian |
| **Agent Count** | Jumlah agent yang memiliki skill tersebut |

Tampilan ini bersifat **read-only** — hanya untuk monitoring distribusi skill. Penambahan dan penghapusan skill dilakukan per-agent melalui endpoint API.

:::note
Halaman settings ini hanya menampilkan summary (`GET /api/skills/summary`). Untuk menetapkan atau menghapus skill pada agent tertentu, gunakan endpoint `POST /api/agents/{id}/skills` dan `DELETE /api/agents/{id}/skills/{skill_id}` langsung via [API Reference](/api).
:::

### Proficiency

Setiap skill memiliki level `proficiency`. Default-nya adalah `"intermediate"` jika tidak ditentukan saat penambahan. Nilai ini disimpan di kolom `proficiency` tabel `agent_skills` di PostgreSQL dan tersedia di response API untuk logika routing kustom.

### Endpoint (tag **Agent Skills**)

| Aksi | Endpoint |
|---|---|
| Ringkasan skill (semua agent) | `GET /api/skills/summary` |
| List skill per-agent | `GET /api/agents/{id}/skills` |
| Tambah skill ke agent | `POST /api/agents/{id}/skills` |
| Hapus skill dari agent | `DELETE /api/agents/{id}/skills/{skill_id}` |

Contoh request menambah skill:

```json
{
  "skill_name": "Technical Support",
  "proficiency": "expert"
}
```

Jika skill dengan nama yang sama sudah ada pada agent tersebut, operasi `POST` akan memperbarui `proficiency` (upsert berdasarkan `(agent_id, skill_name)`).

---

## Rute terkait

- [Manajemen Pengguna](/panduan/admin/manajemen-pengguna) — CRUD akun agent, peran, dan status
- [Divisi](/panduan/admin/divisi) — pengelompokan agent ke unit bisnis
- [Kinerja Agent & Review CSAT](/panduan/supervisor/kinerja-agent) — review metrik kinerja dan CSAT
- [Kebijakan SLA](/panduan/admin/kebijakan-sla) — aturan SLA terkait jam kerja
