Koleksi MongoDB
Koleksi MongoDB
OmniStream menyimpan dua kelas data di MongoDB: pesan chat
(messages) dan payload webhook mentah (webhook_audit). Alasan
kedua kelas ini bukan di PostgreSQL sama: volume tinggi,
dominan append-only, dan jarang di-update.
Database name default: omnistream (di-override lewat MONGODB_URI).
Koleksi dan indeks dibuat otomatis saat service pertama kali
start, via setup_indexes() di
crates/omni-common/src/db/mongodb.rs:31.
Koleksi messages
Setiap dokumen merepresentasikan satu pesan chat. Struct Rust dan
schema lapangan lengkap dibahas di
developer/model-data/message —
halaman ini fokus pada koleksinya (indeks, volume, pattern akses).
Indeks yang dibuat otomatis
Dari setup_indexes (mongodb.rs:31-104):
-
Compound
{ conversation_id: 1, created_at: 1 }Query hot path: "ambil N pesan terakhir di conversation X, urut waktu". Cursor pagination memakai ini. -
Sparse unique
{ external_id: 1 }Dedup pesan webhook. Field bolehnull(mis. pesan outbound sistem yang belum punya ID dari Meta), sparse index mengizinkan banyak null tanpa konflik. -
Text
{ "content.body": "text", "content.text": "text", "content.caption": "text" }dengan opsilanguage_override = "text_search_language". Full-text search pesan di halaman Inbox.language_overridedipakai agar fieldlanguage.codedi payload template WhatsApp tidak salah diinterpretasi sebagai hint bahasa indeks (salah satu bug awal yang sudah ditangani —setup_indexesotomatis men-drop indeks text lama kalau tidak memilikilanguage_overridedan membuatnya ulang).
Pattern akses umum
| Pattern | Query |
|---|---|
| Ambil 50 pesan terakhir per conversation | find({conversation_id}).sort({created_at: -1}).limit(50) |
| Pagination cursor | find({conversation_id, _id: {$lt: cursor}}).sort({_id: -1}) |
| Full-text search | find({$text: {$search: "...", $language: "simple"}}) |
| Dedup pada webhook ingest | Upsert by external_id + conversation_id |
Volume
Per percakapan aktif, ekspektasi kira-kira 20-200 dokumen. Pada tenant yang ramai, koleksi bisa mencapai puluhan juta dokumen — itu sebabnya kami tidak memasang TTL di sini. Histori pesan adalah data bisnis yang harus dipertahankan. Pembersihan dilakukan secara eksplisit lewat tool admin (bukan bagian v1).
Koleksi webhook_audit
Dokumen di koleksi ini adalah payload mentah dari setiap
webhook inbound yang diterima webhook-ingestor, disimpan sebelum
parsing. Tujuannya tiga:
- Replay — kalau parser punya bug, kita bisa mengulang ingest dari raw payload tanpa meminta ulang ke Meta.
- Forensik — debug kenapa sebuah pesan tidak muncul di UI: cek apakah webhook bahkan sampai ke kita.
- Audit eksternal — bukti bahwa integrasi channel sedang hidup (jumlah dokumen per hari = throughput).
Struct Rust ada di crates/omni-common/src/models/webhook_audit.rs.
Indeks TTL
Tidak seperti messages, webhook_audit ada TTL:
Code
Semua dokumen dihapus otomatis oleh MongoDB setelah 90 hari
sejak received_at. Kalau anda butuh retention lebih lama
(regulated industry, audit legal), edit nilai expire_after di
mongodb.rs dan restart service — MongoDB akan mengubah TTL
indeks tanpa drop-and-create.
Koneksi dan konfigurasi
Variabel lingkungan:
MONGODB_URI— wajib (mis.mongodb://mongo:27017/omnistream). Tidak ada nilai default; service gagal start kalau kosong.
Connection pool: omni-common membangun mongodb::Client sekali
per service lewat db::mongodb::build_client() dan men-share-nya
via AppState. Seluruh service memakai UUID sebagai BinData(0)
(bukan sebagai string) supaya ukuran index lebih kecil dan query
tipe-safe — konversi uuid::Uuid ↔ bson::Binary ditangani oleh
helper bson::Uuid::from(uuid::Uuid).
Troubleshooting cepat
| Gejala | Penyebab umum |
|---|---|
| Pesan inbound tidak muncul di UI, tapi webhook Meta OK | Cek webhook_audit — kalau ada raw payload tapi messages kosong, bug parser |
| Text search warning "language override ..." | Indeks text lama. Restart service: setup_indexes auto-drop dan rebuild |
| Duplikasi pesan di conversation | external_id tidak terisi pada ingest. Cek parser channel terkait |
Koleksi webhook_audit terus tumbuh | Fitur TTL bekerja di background — tunggu 24 jam pertama, MongoDB men-sweep secara berkala |
Referensi
- Model Rust:
crates/omni-common/src/models/message.rs,crates/omni-common/src/models/webhook_audit.rs - Setup indeks:
crates/omni-common/src/db/mongodb.rs::setup_indexes(mongodb.rs:31-130) - Parser channel:
crates/chat-engine/src/parser/*.rs - Detail field Message:
developer/model-data/message