Model Conversation
Model Conversation
Conversation adalah state container tiap sesi chat. Satu contact bisa
punya banyak conversation lintas waktu (mis. pelanggan menghubungi ulang
minggu depan → conversation baru). Definisi ada di
crates/omni-common/src/models/conversation.rs dengan tabel Postgres
conversations yang ditentukan di
migrations/20260218000001_initial_schema.sql dan di-extend oleh
sejumlah migrasi berikutnya.
Struct Rust
Code
Sumber: crates/omni-common/src/models/conversation.rs:15-33.
State machine
Status disederhanakan menjadi dua state per migrasi
migrations/20260326000039_simplify_conversation_statuses.sql:
Code
open— default saat conversation dibuat; masih aktif di inbox agent.resolved— ditutup oleh agent/supervisor;resolved_atdi-set.
Transisi legal:
open → resolved(viaPATCH /api/conversations/{id}atau action resolve di UI)resolved → open(re-open, biasanya saat contact mengirim pesan baru — chat-engine men-trigger ulang keopen)
Field penting
| Field | Sumber update |
|---|---|
last_message_at | Di-set oleh chat-engine setiap ada inbound/outbound |
last_message_preview | Di-populate dari message.content (migrasi 20260303000015) |
last_customer_message_at | Hanya di-update untuk direction inbound (dipakai SLA scheduler) |
first_response_at | Set saat outbound pertama dari agent dikirim; basis metrik SLA |
messaging_window_expires_at | Untuk WhatsApp — jendela 24 jam (migrasi 20260309000036) |
unread_count | Counter per conversation, di-reset saat agent membaca pesan |
assigned_agent_id | Null = unassigned; di-isi saat transfer atau claim |
division_id | Foreign key ke divisions untuk routing |
Query-query kritis
Tiga query dengan daftar kolom eksplisit yang WAJIB di-update saat tabel
conversations berubah (aturan ini tercatat di CLAUDE.md):
crates/api-gateway/src/routes/conversations/core.rs::list_conversations(~baris 31)crates/api-gateway/src/routes/conversations/core.rs::get_conversation(~baris 125)crates/api-gateway/src/routes/contacts.rs::list_contact_conversations(~baris 376)
Kalau anda menambahkan kolom baru tapi lupa menambahkannya ke salah satu
dari tiga query di atas, deserialisasi sqlx::FromRow akan gagal saat
runtime.
Payload API
Code
Filter list conversation lengkap (status, assigned_agent_id,
assigned_to, channel, tag, search, page, per_page) ada di
ConversationListQuery (conversation.rs:48-62). Channel filter
bekerja dengan JOIN terhadap tabel contacts.channel_source.
Topik terkait
- Transfer percakapan: tabel
conversation_transfers(migrasi20260306000018_conversation_transfers.sql) - Routing otomatis:
migrations/20260301000013_conversation_routing.sql - SLA: tabel
sla_policies+sla_breach_logs— lihatdeveloper/self-hosting/migrations