Lewati ke konten

Deteksi Transaksi Duplikat

Contoh dokumen nyata — ditulis dari kode erdigma-api, service transaction.

Memeriksa apakah satu transaksi kemungkinan merupakan duplikat dari transaksi lain. Dipakai oleh tim CS untuk menolak order ganda sebelum diproses, bukan untuk memblokir otomatis.

  1. Client memanggil GET /check-duplicate/{id}.
  2. Sistem mengambil transaksi berdasarkan id. Kalau tidak ada → 400 Transaksi Tidak Ditemukan.
  3. Sistem mencari kandidat transaksi lain dalam rentang tanggal ±7 hari dengan kriteria yang sama (lihat Aturan bisnis).
  4. Setiap detail transaksi dibandingkan dengan detail kandidat: produk dan kuantitas harus cocok.
  5. Respons berisi duplicate dan, jika duplikat, kode transaksi pembanding.

Kandidat duplikat hanya diambil bila semua kondisi berikut terpenuhi:

  • code berbeda dari transaksi yang diperiksa.
  • status bukan salah satu dari: Cancelled, Cancelled by System, Cancelled-Out of Stock, Waiting for Payment, Payment Confirmed, Draft.
  • invoiceDate berada dalam rentang 7 hari sebelum atau 7 hari sesudah tanggal transaksi.
  • customerServiceId sama.
  • kelurahan dan kecamatan sama.
  • source = INPUT.
  • omset sama persis.
  • paymentMethod = TF-UNIQUECODE.

Sebuah transaksi dinyatakan duplikat bila setiap detailnya punya pasangan product.id + quantity yang sama pada satu kandidat yang sama.

Field Tipe Keterangan
code string kode transaksi, dipakai sebagai pembeda
invoiceDate date (invoice_date) dasar jendela ±7 hari
status string filter status aktif
customerServiceId relasi CS pembanding
kelurahan / kecamatan string pembanding wilayah
source string hanya INPUT
omset integer pembanding nominal
paymentMethod string hanya TF-UNIQUECODE
Method Path Lambda Catatan
GET /check-duplicate/{id} checkDuplicate reservedConcurrency: low, CORS aktif

Contoh respons:

{ "duplicate": true, "transaction": { "id": 8123, "code": "TRX-2026-00123" } }
  • transactionDetails kosong → duplicate: true. Loop tidak pernah jalan, sehingga nilai awal duplicate = true lolos ke respons. Ini false positive: transaksi tanpa detail dilaporkan duplikat. (Temuan saat dokumentasi — belum diperbaiki.)
  • duplicateTransaction hanya terisi pada iterasi terakhir yang cocok, jadi untuk kasus duplikat dengan beberapa kandidat, pasangan yang dilaporkan bisa berbeda dari kandidat pertama.
  • Perbandingan produk/kuantitas memakai ==, bukan ===.
  • Kandidat diambil tanpa paginasi (paged: false), seluruh transaksi dalam jendela 7 hari dimuat ke memori.
  • omset harus sama persis; perbedaan pembulatan membuat transaksi tidak dianggap kandidat.
  • Endpoint bersifat informatif, tidak memblokir pembuatan transaksi — keputusan akhir di tangan CS.
  • Rentang ±7 hari dipilih karena invoice bisa diinput terlambat maupun lebih awal.
  • Kombinasi status yang dikecualikan sengaja menutup transaksi yang belum final atau sudah batal, supaya perbandingan hanya terjadi antar transaksi yang benar-benar berjalan.
  • 2026-10-29 — dokumen dibuat dari kode src/services/transaction (commit terakhir di dev).