Model Contact
Model Contact
Entitas Contact merepresentasikan pelanggan akhir (end-user) yang
berkomunikasi dengan organisasi melalui channel manapun. Definisinya ada
di crates/omni-common/src/models/contact.rs dan skema tabelnya
berasal dari migrasi awal migrations/20260218000001_initial_schema.sql.
Struct Rust
Code
Sumber: crates/omni-common/src/models/contact.rs:7-16.
Field penjelasan
| Field | Tipe | Nullable | Catatan |
|---|---|---|---|
id | uuid | no | Primary key, UUID v4 yang di-generate saat insert |
phone_number | text | yes | Nomor WhatsApp/Instagram. Bisa kosong untuk contact email-only |
name | text | yes | Nama display; diambil dari metadata webhook kalau tersedia |
email | text | yes | Alamat email (untuk channel email-SMTP) |
channel_source | text | no | Channel asal: whatsapp, instagram, email — salah satu harus ada |
tags | jsonb | no | Array string; defaultnya [] |
created_at | timestamptz | no | Set otomatis oleh Postgres (DEFAULT now()) |
updated_at | timestamptz | no | Di-update oleh trigger saat row berubah |
Kunci unik & upsert
Contact di-upsert saat inbound message datang. Aturan upsert di
chat-engine memakai kombinasi (channel_source, phone_number) untuk
WhatsApp/Instagram dan (channel_source, email) untuk channel email.
Konsekuensi: satu nomor HP yang sama di WhatsApp dan Instagram akan
menghasilkan dua contact row yang berbeda karena channel_source
juga jadi bagian dari kunci.
Payload API
Endpoint REST memakai dua payload tambahan di file yang sama:
Code
Detail parameter filter (search, tag, page, per_page) ada di
ContactListQuery (crates/omni-common/src/models/contact.rs:36-43).
Endpoint HTTP-nya dikonsumsi lewat tag Contacts di API Reference.
Query list contacts
Endpoint list di crates/api-gateway/src/routes/contacts.rs memakai
daftar kolom eksplisit (bukan SELECT *). Jika anda menambahkan kolom
baru di tabel contacts, jangan lupa memperbarui query di file itu —
aturan ini juga disebut di CLAUDE.md pada bagian "Key Conventions".