Chat Rooms — dari Store Lokal ke Live Proxy
❌ Alur LAMA
Panel membaca database lokal yang diisi webhook.
Tab Queue/Assigned/Solved dibangun dari kolom contacts.chat_status, dan assign/transfer mengisi contacts.assigned_user_id.
Masalahnya
✅ Alur BARU
Daftar percakapan, isi thread, jumlah tab, dan mark-as-read dibaca langsung dari endpoint internal ChatPanel Jasnita memakai token OAuth kita.
Store lokal tidak dihapus — ia sekarang berperan sebagai riwayat percakapan untuk AI (WhatsappAutoReplyService membaca 30 pesan terakhir dari sana) dan jejak notifikasi pembayaran. Yang berubah hanyalah sumber tampilan panel.
Perbandingan berdampingan
| Aspek | ❌ Lama | ✅ Baru |
|---|---|---|
| Sumber daftar percakapan | contacts lokal | chatpanel/get-with-filter/{status} |
| Sumber isi thread | whatsapp_messages lokal | chatpanel/get-detail |
| Identitas percakapan | Nomor telepon | conversation_id Jasnita |
| Sumber jumlah tab | Hitung sendiri dari chat_status | get-status-count-with-status-filter |
| Percakapan lama | ❌ Tidak ada | ✅ Ada — riwayat penuh dari Jasnita |
| Konsisten dengan ChatPanel Jasnita | ❌ Tidak | ✅ Ya |
| Tandai dibaca | Lokal | mark-as-read-by-conversation-id ke Jasnita |
| Deteksi arah pesan | Kolom direction | sender == gateway_account_id → outbound |
| Zona waktu | Konversi lokal | created_at Jasnita sudah WIB — tidak digeser lagi |
| Ketahanan | Fatal kalau query gagal | Semua error ditelan → kembalikan kosong, panel tidak pernah fatal |
| Beban API | — | Cache 5 detik (daftar/thread), 20 detik (jumlah) |
Yang ikut berubah
1. Kunci pemilihan percakapan
Nomor tetap dibawa karena dibutuhkan untuk mengirim pesan dan mencari Patient.
2. Dua jalur kirim yang berbeda
| Jalur | Metode | Dicatat lokal? |
|---|---|---|
| Balas cepat di thread | sendTextToNumber / sendMediaToNumber | ❌ Tidak — pesan muncul lagi dari get-detail saat polling; mencatatnya = duplikat di layar |
| Template & media ke Contact | sendTemplate / sendMedia | ✅ Ya — percakapan baru belum tentu ada di ChatPanel |
3. Media lewat proksi
Berkas di Jasnita butuh Bearer token. Rute /admin/chat/media menyediakan proksi yang memeriksa login + izin halaman Chat Rooms, lalu mengalirkan berkas — token tidak pernah menyentuh browser.
4. Cache pendek
5. Pemuatan ditunda + auto-scroll
Halaman dirender kosong dulu (instan), lalu wire:init memicu bootstrapPanel(). Ditambah status loading dan auto-scroll ke pesan terbaru.
Sebelumnya halaman memblokir menunggu API Jasnita — agen melihat layar kosong beberapa detik setiap kali membuka menu.
Konsekuensi yang diterima
Kalau API Jasnita mati, panel menampilkan daftar kosong (bukan error fatal, tapi juga bukan data). Di alur lama, panel masih bisa menampilkan apa pun yang sudah tersimpan lokal.
Pertukaran ini diambil karena konsistensi dengan ChatPanel jauh lebih berharga daripada tampilan sebagian yang menyesatkan.
Endpoint chatpanel/* dipakai ChatPanel Jasnita sendiri dan tidak ada di koleksi Postman publik. Endpoint ini bisa berubah sewaktu-waktu tanpa pemberitahuan. Gejala kalau berubah: daftar percakapan tiba-tiba kosong dan log berisi ChatPanel conversations gagal.
Kolom lokal yang masih dipakai
Meski panel tidak lagi membacanya untuk tampilan, kolom-kolom ini tetap ada dan terpakai:
| Kolom | Masih dipakai untuk |
|---|---|
contacts.number | Identitas kontak, pencocokan dengan whatsapp_messages, penempelan label |
contacts.name | Daftar Kontak, ekspor Excel |
contacts.handled_by | Takeover eksplisit — memblokir auto-reply |
contacts.assigned_user_id | Nama agen pemegang; penyaringan percakapan per agen non-admin |
contacts.chat_assigned_at | Waktu pengambilalihan |
contacts.chat_status, chat_created_at | Diisi saat kontak dibuat; nilai historis |
whatsapp_messages.* | Riwayat percakapan untuk AI + jejak notifikasi pembayaran |
whatsapp_messages.sent_by / sent_by_user_id | Atribusi AI vs agen — lihat Siapa Memegang Percakapan |