OmniStream Docs
  • Panduan Pengguna
  • Developer
  • API Reference
Developer Hub
Pendahuluan
Autentikasi
Model Data
    Ikhtisar Model DataSchema PostgreSQLKoleksi MongoDBRedis Pub/SubModel AgentModel ContactModel ConversationModel MessageRoles & Permissions
Webhook
WebSocket
Self-Hosting
Error & Rate Limit
Model Data

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
pub struct Conversation { pub id: Uuid, pub contact_id: Uuid, pub assigned_agent_id: Option<Uuid>, pub division_id: Option<Uuid>, pub status: ConversationStatus, pub last_message_at: DateTime<Utc>, pub unread_count: i32, pub last_message_preview: Option<String>, pub last_message_direction: Option<String>, pub last_customer_message_at: Option<DateTime<Utc>>, pub first_response_at: Option<DateTime<Utc>>, pub resolved_at: Option<DateTime<Utc>>, pub messaging_window_expires_at: Option<DateTime<Utc>>, pub tags: serde_json::Value, pub created_at: DateTime<Utc>, pub updated_at: DateTime<Utc>, }

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
pub enum ConversationStatus { Open, Resolved, }
  • open — default saat conversation dibuat; masih aktif di inbox agent.
  • resolved — ditutup oleh agent/supervisor; resolved_at di-set.

Transisi legal:

  • open → resolved (via PATCH /api/conversations/{id} atau action resolve di UI)
  • resolved → open (re-open, biasanya saat contact mengirim pesan baru — chat-engine men-trigger ulang ke open)

Field penting

FieldSumber update
last_message_atDi-set oleh chat-engine setiap ada inbound/outbound
last_message_previewDi-populate dari message.content (migrasi 20260303000015)
last_customer_message_atHanya di-update untuk direction inbound (dipakai SLA scheduler)
first_response_atSet saat outbound pertama dari agent dikirim; basis metrik SLA
messaging_window_expires_atUntuk WhatsApp — jendela 24 jam (migrasi 20260309000036)
unread_countCounter per conversation, di-reset saat agent membaca pesan
assigned_agent_idNull = unassigned; di-isi saat transfer atau claim
division_idForeign 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):

  1. crates/api-gateway/src/routes/conversations/core.rs::list_conversations (~baris 31)
  2. crates/api-gateway/src/routes/conversations/core.rs::get_conversation (~baris 125)
  3. 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
pub struct AssignAgentRequest { pub agent_id: Option<Uuid>, // None = unassign } pub struct UpdateStatusRequest { pub status: ConversationStatus, }

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 (migrasi 20260306000018_conversation_transfers.sql)
  • Routing otomatis: migrations/20260301000013_conversation_routing.sql
  • SLA: tabel sla_policies + sla_breach_logs — lihat developer/self-hosting/migrations
Last modified on June 8, 2026
Model ContactModel Message
On this page
  • Struct Rust
  • State machine
  • Field penting
  • Query-query kritis
  • Payload API
  • Topik terkait
Rust
Rust
Rust