D
Engineering

Tech Debt Roadmap

Prioritas dari AGENTS.md §9 dan README known issues — auth, secret enkripsi, Socket.IO auth, SSRF media, ESLint rusak, sendContact belum terdaftar, quoted_raw_message lokasi, Set dedupe tidak dibersihkan.

Daftar known issues engine-whatsapp dari AGENTS.md §9 dan readme.md. Diurutkan prioritas risiko, bukan berdasarkan seberapa mengganggu. Tujuan: pembenahan tidak menghentikan pengiriman fitur.

Aturan utama: Jangan gabungkan pembenahan dengan fitur dalam satu commit. Pisahkan agar mudah di-revert.


Prioritas 1 — Tambahkan autentikasi (kritis)

AspekDetail
MasalahTidak ada auth di semua endpoint /api/*. Siapapun yang dapat mengakses port 5002 dapat: buat sesi, kirim pesan, logout device, push notif, submit pixel
Lokasisrc/routes/itemRoutes.ts (tidak ada middleware auth), src/app.ts
TargetMiddleware auth (JWT shared dengan dazoapp, atau API key khusus) di group /api. Atau perimeter jaringan yang ketat (reverse proxy + IP allowlist)
RisikoKritis — unauthorized access ke semua operasi WhatsApp
PrasyaratPrioritas 6

Prioritas 2 — Perbaiki enkripsi AES-256-CBC (kritis)

AspekDetail
Masalah(a) Secret My32charPasswordAndInitVectorStr hard-coded di utils/helper.ts:13. (b) IV diturunkan dari secret yang sama (secret.substr(0, 16)) — IV statis, melanggar prinsip enkripsi aman
Lokasisrc/utils/helper.ts:12-14
Target(a) Pindahkan secret ke env var (ENCRYPTION_SECRET). (b) Generate IV acak per enkripsi (16 byte random), kirim IV bersama ciphertext
RisikoKritis — siapapun dengan akses repo dapat mendekripsi field id di event socket
PrasyaratPrioritas 6

Prioritas 3 — Amankan Socket.IO (kritis)

AspekDetail
Masalah(a) CORS origin: "*" mengizinkan client dari origin apapun. (b) Socket handshake tidak authenticated — client apapun dapat join_instance ke room manapun dan menerima event qrcode, message_upsert, getmessage, dll
Lokasisrc/service/socketService.ts:21-25 (CORS), :27-47 (connection handler)
Target(a) Batasi CORS ke domain frontend valid. (b) Tambahkan auth middleware di io.use() — verifikasi JWT atau token khusus saat handshake
RisikoKritis — data pesan masuk, QR, dan status device dapat bocor ke client manapun
PrasyaratPrioritas 1 (auth)

Prioritas 4 — Amankan media fetch SSRF (tinggi)

AspekDetail
MasalahPOST /api/send-media menerima url tanpa protocol/domain allowlist, private network block, redirect restriction, atau size limit. Hanya cek HTTP HEAD 200
Lokasisrc/utils/helper.ts:294-300 — isMediaUrlValid
TargetRestricted media fetcher dengan HTTPS allowlist, DNS/IP validation (block 10.x, 192.168.x, 127.0.0.1, 169.254.x), byte limit, content-type check
RisikoTinggi — SSRF ke internal network, metadata leak
PrasyaratPrioritas 6

Prioritas 5 — Perbaiki keterbatasan operasional (tinggi)

AspekDetail
Masalah(a) connectDB tidak di-await di app.ts:37 — server.listen jalan berbarengan. (b) Set dedupe (processedUpdates) tidak pernah dibersihkan — potensi kebocoran memori pada sesi berumur panjang. (c) sendContact sudah diimplementasi tapi tidak didaftarkan di router. (d) quoted_raw_message diparsing untuk lokasi tapi diabaikan service. (e) Status code inkonsisten (res.statusCode bisa 200 untuk error). (f) Salah label workflow deploy_production.yml
Lokasisrc/app.ts:37, src/service/whatsappService.ts:228, src/controller/MessageController.ts:249, src/service/whatsappService.ts:625, controller, .github/workflows/deploy_production.yml
TargetAwait connectDB, cleanup Set dedupe, daftarkan sendContact atau hapus, perbaiki reply lokasi, pakai status code eksplisit, perbaiki label workflow
RisikoTinggi — memory leak, fitur tidak berfungsi, error handling inkonsisten
PrasyaratPrioritas 6

Prioritas 6 — Tambahkan automated regression tests (foundation)

AspekDetail
MasalahTidak ada test suite. Satu-satunya gerbang kualitas otomatis adalah npx tsc --noEmit. Tidak ada regression untuk sesi, kirim pesan, webhook, atau event socket
Lokasi—
TargetTest framework + suite untuk area kritis: startSession, sendTextMessage, processMessage, sendWebhook, formatNumber, event listener
RisikoFoundation — tanpa test, semua refactor di atas berisiko
Prasyarat— (prasyarat untuk prioritas 1–5)

Prioritas 7 — Perbaiki ESLint dan dependency (foundation)

AspekDetail
MasalahESLint v9 butuh flat config (eslint.config.js), tapi project masih .eslintrc.js. @typescript-eslint/parser belum terpasang. Belum ada script lint. Dependency salah tempat: eslint/prettier di dependencies (bukan devDependencies), crypto (modul built-in) terdaftar sebagai dependency
Lokasi.eslintrc.js, package.json
TargetMigrasi ke eslint.config.js, pasang parser, tambah script lint, pindahkan dev dependency ke devDependencies, hapus crypto dari dependency
RisikoFoundation — code quality gate tidak ada, dependency tercemar
Prasyarat—

Detail issue terpilih

connectDB tidak di-await

src/app.ts:34-50:

ts
const start = async () => {
  try {
    connectDB();   // ← tidak di-await
    server.listen(config.port, () => {
      console.log(`Server Berjalan...`);
      WhatsAppService.init();
    });
  } catch (error) {
    console.error("Gagal:", error);
    process.exit(1);
  }
};

connectDB async tapi tidak di-await. server.listen jalan berbarengan. Jika MongoDB gagal, process.exit(1) tetap terjadi (di dalam connectDB), tapi window singkat ada di mana server merespons tanpa DB.

Fix:

ts
await connectDB();   // fail-fast sebelum listen
server.listen(config.port, () => { ... });

Set dedupe tidak pernah dibersihkan

src/service/whatsappService.ts:228:

ts
const processedUpdates = new Set<string>();

// dalam messages.update handler:
const dedupeKey = `${update.key.id}-${update.update.status}`;
if (processedUpdates.has(dedupeKey)) continue;
processedUpdates.add(dedupeKey);

Set dibuat per sesi (di dalam startSession, scope event handler). Tidak pernah di-clear. Pada sesi berumur panjang dengan banyak pesan, Set tumbuh tanpa batas — potensi kebocoran memori.

Fix: Tambahkan TTL cleanup atau batasi ukuran Set (mis. LRU cache).

sendContact tidak terdaftar

src/controller/MessageController.ts:249 mengimplementasi sendContact, tapi src/routes/itemRoutes.ts tidak mendaftarkan endpoint. Endpoint tidak dapat diakses.

Fix: Tambahkan router.post('/send-contact', MessageController.sendContact) di itemRoutes.ts, atau hapus method jika tidak dipakai.

quoted_raw_message diabaikan untuk lokasi

src/controller/MessageController.ts:201-244 (sendLocation) mem-parsing quoted_raw_message:

ts
let quotedMsg = null;
if (quoted_raw_message) {
  quotedMsg = typeof quoted_raw_message === 'string'
    ? JSON.parse(quoted_raw_message)
    : quoted_raw_message;
  // ...
}

const result = await WhatsAppService.sendLocationMessage(
  instance, number, parseFloat(latitude), parseFloat(longitude), quotedMsg
);

Tapi WhatsAppService.sendLocationMessage (:625-643) menerima parameter quotedMsg tapi tidak menggunakannya:

ts
static async sendLocationMessage(
  instanceId, number, latitude, longitude, quotedMsg,  // ← diterima
) {
  // ...
  return await sock.sendMessage(formattedNumber, {
    location: { degreesLatitude: latitude, degreesLongitude: longitude },
  });   // ← quotedMsg tidak dipakai
}

Reply pada pesan lokasi belum berfungsi.

Fix: Tambahkan options.quoted = quotedMsg di sock.sendMessage.

Correctness issues (tidak urut prioritas)

IssueLokasi
Import tak terpakai import e from 'express'whatsappService.ts:22
Typo pesan: “Berhasi” (harus “Berhasil”)NotificationController.ts:24,36,48
Typo pesan: “menghpaus” (harus “menghapus”)SessionController.ts:82
console.log debug tercecer, sebagian dikomentariwhatsappService.ts, chatHistoryService.ts, incomingMessageService.ts
npm run dev tidak hot-reload (tsx tanpa watch)package.json
Workflow salah label: “Deploy to Staging” untuk productiondeploy_production.yml
Dependency salah tempat: eslint, prettier di dependenciespackage.json
crypto (modul built-in Node) terdaftar sebagai dependencypackage.json
uuidv4 package terpasang tapi uuid v13 sudah dipakaipackage.json

Performance dan observability

IssueCatatan
Tidak ada health endpointVerifikasi via GET /api/device-info — tidak ada /health
Boot lambat dengan banyak sesiJeda 2 detik antar sesi × jumlah sesi
Sesi in-memory tidak bisa clusterSingle process only
Log level trace sangat verboseLEVEL_LOG=info atau warn di produksi

Delivery dan testing

IssueCatatan
Tidak ada test suitenpx tsc --noEmit adalah satu-satunya gate
ESLint tidak jalanv9 butuh flat config, project masih .eslintrc.js
npm run dev tidak hot-reloadtsx tanpa watch flag

Status legend

  • 🔴 Belum diperbaiki
  • 🟡 Dikonfirmasi / inkonsistensi
  • 🟢 Selesai

Langkah berikutnya