engine-whatsapp memakai MongoDB sebagai datastore via Mongoose 9.1. Tidak ada migration — bentuk dokumen diturunkan dari Mongoose schema di src/model/.
Koneksi MongoDB
src/config/database.ts — connectDB() async, memakai MONGO_URL dari .env:
const MONGO_URL = config.mongo_url; // dari .env
export const connectDB = async (): Promise<void> => {
try {
await mongoose.connect(MONGO_URL);
console.log("Mongodb Connected");
} catch (error: any) {
console.error("Mongodb Error Connection: ", error)
process.exit(1); // fail-fast
}
}| Environment | Database | Host |
|---|---|---|
| lokal (default) | dazo | 127.0.0.1:27017 |
| remote | dari MONGO_URL | connection string dari tim |
Primary key
Sama seperti dazoapp, backend-go, dan engine-bot, koleksi Dazo memakai field id (string UUID) sebagai primary key logis — bukan _id Mongo default:
const device = await DeviceModel.findOne({ id: instanceId });_id Mongo tetap ada (auto ObjectId), tapi query bisnis berdasarkan id string.
Pola akses koleksi
Engine WhatsApp memakai Mongoose model — ada layer ODM tipis:
// src/model/devices.model.ts
const DeviceSchema = new Schema<DeviceCollection>({ id: { type: String, required: true, index: true }, ... });
export const DeviceModel = model<DeviceCollection>('devices', DeviceSchema, 'devices');
// src/service/devices/deviceServices.ts
const device = await DeviceModel.findOne({ id: instanceId });Koleksi utama
Hanya 4 koleksi yang dikelola engine-whatsapp:
| Koleksi | Model | Dipakai untuk |
|---|---|---|
devices | src/model/devices.model.ts | Device milik user. Diupdate saat koneksi open/close (no_wa, is_connected) |
admin_devices | src/model/admin_devices.model.ts | Fallback bila instanceId tidak ada di devices; punya field tambahan status (0/1) |
chat_inbox | src/model/chatInbox.model.ts | Pesan. Dibaca engine untuk mencari temp_id. strict: false |
chat_histories | src/model/chatHistory.model.ts | Sesi percakapan per nomor. Dibuat otomatis saat ada pesan masuk bila belum ada yang aktif |
devices vs admin_devices
Saat status koneksi berubah (open/close), engine mencari devices lebih dulu. Jika tidak ketemu, update diarahkan ke admin_devices:
// src/service/whatsappService.ts — connection.update handler
let deviceMember = await DeviceService.findOne(instanceId);
if (!deviceMember) {
// Fallback ke admin_devices
await DeviceService.updateDeviceAdmin(instanceId, {
no_wa: phoneNumber,
is_connected: 'Connected',
status: 1,
});
} else {
await DeviceService.update(instanceId, {
no_wa: phoneNumber,
is_connected: 'Connected',
});
}Pertahankan pola percabangan ini saat menyentuh kode update device.
admin_devices punya field ekstra status: 0|1 (0 = disconnected, 1 = connected) yang tidak ada di devices.
Relasi custom
Relasi implicit via instanceId — bukan _id Mongo:
devices.id/admin_devices.id=instanceId= nama foldersession/auth/<instanceId>chat_inbox.instance=instanceIdchat_histories.instance=instanceId
Shared dengan dazoapp dan backend-go
| Koleksi | Engine WhatsApp menulis | Engine WhatsApp membaca | Dibagi dengan |
|---|---|---|---|
devices | ✅ update no_wa, is_connected | ✅ findOne untuk chat_histories lookup | dazoapp, backend-go |
admin_devices | ✅ update (fallback) | ❌ | dazoapp |
chat_inbox | ❌ read-only | ✅ cari temp_id | backend-go (writer) |
chat_histories | ✅ create | ✅ cari existing | backend-go |
chat_histories logic
ChatHistoryService.manageChatHistory() (src/service/chatHistory/chatHistoryService.ts) dipanggil untuk setiap pesan masuk:
- Cari
devicesberdasarkaninstanceIduntuk dapatstore_id - Jika device tidak ada → return (tidak buat history)
- Cari
chat_historiesdengan filter:store_id+instance+nohp+end_date: null+status != "close" - Jika tidak ada → buat baru dengan
id: uuid,status: "open",chat_status: "new",chat_start: messageId - Jika ada → skip (tidak duplikat)
Nomor disimpan dengan format +628... (prefix + lalu nomor tanpa @s.whatsapp.net).
Inkonsistensi yang diketahui
| Masalah | Detail |
|---|---|
Nama model Admin_Device | Mongoose auto-pluralize → koleksi admin_devices (bukan Admin_Devices) |
connectDB tidak di-await | app.ts:37 — server.listen jalan berbarengan dengan DB connect |
chat_inbox.strict: false | Field tambahan dari writer (backend-go) tetap tersimpan tanpa validasi |
| Tidak ada index komposit | Query chat_histories filter store_id + instance + nohp + end_date + status tanpa compound index |
Lihat Tech Debt untuk daftar lengkap.
Konteks vs dazoapp, backend-go, engine-bot
| Aspek | dazoapp (Laravel) | backend-go | engine-bot | engine-whatsapp |
|---|---|---|---|---|
| ODM/ORM | MongoDB Eloquent | mongo-driver | Mongoose | Mongoose |
| Jumlah koleksi dikelola | 79 model | ~5 | 24 | 4 |
| Multi-DB | 4 koneksi | 2 koneksi | 1 | 1 |
| PK | UUID string | field id | field id | field id |
| Tenant scope | store_id | store_id | store_id | instanceId (per device) |
| Startup fail-fast | ✅ | ❌ | ❌ | ✅ (tapi tidak di-await) |
| Auth | JWT issuer | — | validate-only | ❌ tidak ada |
Langkah berikutnya
- Detail field koleksi? Baca Schema.
- Cara koneksi Baileys? Baca Session Lifecycle.
- Known issues? Baca Tech Debt.