14 KiB
14 KiB
Decisions Log — QRIS Soundbox Platform
Log keputusan arsitektur dan implementasi yang harus dijadikan acuan eksekusi.
Format Entri
- ID: [D-XXX]
- Tanggal:
- Keputusan:
- Alasan:
- Dampak / implikasi:
- Status:
D-001 — Basis Implementasi Fase 0 dan 1
- Tanggal: 2026-05-23
- Keputusan:
- Menjalankan eksekusi langsung berdasarkan fase roadmap, tanpa pembuatan jadwal rinci.
- Alasan:
- Tim sudah punya pembagian fase yang jelas dan siap mulai implementasi langsung.
- Dampak / implikasi:
- Fokus pada deliverable per fase dan DoD, bukan timeline.
- Status: Active
D-002 — Scope Fase 1 Step 1
- Tanggal: 2026-05-23
- Keputusan:
- Step 1 Fase 1 dibatasi pada core foundation: auth baseline, schema MVP, merchant/outlet/terminal/device/binding, observability dasar.
- Alasan:
- Memastikan jalur static payment bisa dipersiapkan stabil sebelum dynamic flow.
- Dampak / implikasi:
- Fitur lain (settlement, dynamic QR, merchant portal) ditunda sampai Step 1 stabil.
- Status: Active
D-003 — API Contract Error Standard
- Tanggal: 2026-05-23
- Keputusan:
- Semua response error mengikuti envelope seragam:
code,message,details,request_id,timestamp.
- Semua response error mengikuti envelope seragam:
- Alasan:
- Memudahkan debug dan tracing lintas service/device.
- Dampak / implikasi:
- Semua handler API harus mematuhi middleware response formatter yang sama.
- Status: Active
D-004 — Traceability Requirement
- Tanggal: 2026-05-23
- Keputusan:
- Semua request harus membawa
request_id; webhook/device callback harus dihubungkan dengantrace_idjika multi-step.
- Semua request harus membawa
- Alasan:
- Root-cause analysis perlu konteks end-to-end dari callback sampai notifikasi.
- Dampak / implikasi:
- Framework logging dan parser event wajib men-generate field ini secara konsisten.
- Status: Active
D-005 — Idempotency Rule
- Tanggal: 2026-05-23
- Keputusan:
- Setiap path sensitif terhadap duplicate (create merchant/create device/binding/webhook request/dynamic QR nanti) wajib men-support idempotency key/table.
- Alasan:
- Menghindari double create, double binding, dan state drift akibat retry.
- Dampak / implikasi:
- Menambah kebutuhan service/DB untuk
idempotency_keyssejak awal Fase 1.
- Menambah kebutuhan service/DB untuk
- Status: Active
D-006 — Device Binding
- Tanggal: 2026-05-23
- Keputusan:
- Notifikasi pembayaran hanya boleh dipush ke device dari binding aktif yang valid (active_flag=true).
- Alasan:
- Mencegah notifikasi salah kirim jika device pernah dipindahkan antar outlet/terminal.
- Dampak / implikasi:
- Query notification selalu harus resolve binding aktif secara explicit.
- Status: Active
D-007 — Fallback Strategy untuk Fase 1
- Tanggal: 2026-05-23
- Keputusan:
- Retry MQTT pada Fase 1 memakai retry sederhana (fixed/backoff pendek), tanpa DLQ kompleks.
- Alasan:
- Menghemat effort awal sambil menjaga fitur core berjalan.
- Dampak / implikasi:
- Fase 4 mengelola policy DLQ dan retry matang.
- Status: Active
D-008 — Minimal RBAC untuk Mulai Eksekusi
- Tanggal: 2026-05-23
- Keputusan:
- Implement RBAC baseline minimum di Fase 1 (admin-only) sambil menjaga token device terpisah.
- Alasan:
- Mengurangi risiko akses silang awal tanpa memperlambat pengembangan.
- Dampak / implikasi:
- Permission matrix akan disempurnakan di Fase 4.
- Status: Active
D-009 — Dokumentasi Eksekusi Step 1
- Tanggal: 2026-05-23
- Keputusan:
- Spesifikasi detail Step 1 dituangkan di
12-fase1-step1-core-foundation-spec.md.
- Spesifikasi detail Step 1 dituangkan di
- Alasan:
- Menghindari ketidakpastian saat tim mulai coding.
- Dampak / implikasi:
- Semua implementer wajib merujuk dokumen ini saat menyiapkan branch dan PR.
- Status: Active
D-010 — Webhook Signature dan Parsing
- Tanggal: 2026-05-23
- Keputusan:
- Semua callback harus divalidasi signature-nya terlebih dahulu; jika tidak valid, respons harus
401dan tidak boleh melakukan perubahan state apapun.
- Semua callback harus divalidasi signature-nya terlebih dahulu; jika tidak valid, respons harus
- Alasan:
- Payment callback adalah sumber trust utama dan harus dijaga dari spoofing/replay.
- Dampak / implikasi:
- Service callback wajib mengimplementasikan validator HMAC (atau skema cryptographic sesuai partner) sebelum mapping transaksi.
- Status: Active
D-011 — Callback Idempotency di Level Transaksi
- Tanggal: 2026-05-23
- Keputusan:
- Callback duplikat harus diidentifikasi deterministik dari
partner_reference + payment_status + partner_event_iddan diperlakukan idempotent.
- Callback duplikat harus diidentifikasi deterministik dari
- Alasan:
- Callback retry sangat umum dari partner dan dapat memicu double state update.
- Dampak / implikasi:
- state transition dilakukan hanya jika perubahan state valid sesuai mesin state.
- Status: Active
D-012 — Evented Transaction State Change
- Tanggal: 2026-05-23
- Keputusan:
- Setiap perubahan state transaksi harus menghasilkan
transaction_eventsagar Step 3 dan observability bisa berjalan.
- Setiap perubahan state transaksi harus menghasilkan
- Alasan:
- Auditability dan troubleshooting menuntut timeline per transaksi.
- Dampak / implikasi:
- update transaksi tanpa menulis event dianggap bug di Step 1.
- Status: Active
D-013 — Terminal Event paid sebagai Trigger Notification
- Tanggal: 2026-05-23
- Keputusan:
- Notifikasi pembayaran di Step 3 harus dipicu dari event internal status
paid, bukan dari polling callback.
- Notifikasi pembayaran di Step 3 harus dipicu dari event internal status
- Alasan:
- Menghindari race dan duplikasi notifikasi.
- Dampak / implikasi:
- Implementasi Step 3 harus subscribe dan consume event transaction paid.
- Status: Active
D-014 — Retry Notifikasi Fase 1
- Tanggal: 2026-05-23
- Keputusan:
- Step 3 menggunakan retry dasar maksimum 3 kali dengan jadwal 15/30/60 detik.
- Alasan:
- Menyeimbangkan reliability dan kecepatan operasional tanpa kompleksitas DLQ penuh pada fase awal.
- Dampak / implikasi:
notifications.retry_countwajib ditulis dan dibatasi maksimal 3.
- Status: Active
D-015 — Notifikasi Tanpa Ack Fase 1
- Tanggal: 2026-05-23
- Keputusan:
- Pada fase 1, absence of MQTT ack tidak dianggap error akhir; status sukses ditentukan dari publish outcome, bukan ack dari device.
- Alasan:
- Device ecosystem belum konsisten untuk ack schema, dan goal fase 1 adalah stabilitas flow utama.
- Dampak / implikasi:
ack_statusbisanot_supported, dan operasi tetap lanjut dengan monitoring via retry/publish status.
- Status: Active
D-016 — Heartbeat Status Threshold Fase 1
- Tanggal: 2026-05-23
- Keputusan:
- Definisi status device ditetapkan: online (<90s), degraded (signal/battery buruk), stale (<15 menit), offline (>15 menit) berdasarkan
last_seen_at.
- Definisi status device ditetapkan: online (<90s), degraded (signal/battery buruk), stale (<15 menit), offline (>15 menit) berdasarkan
- Alasan:
- Konsistensi status dibutuhkan untuk ops triage cepat.
- Dampak / implikasi:
- Setiap list/detail device menampilkan status yang dihitung dari rule yang sama.
- Status: Active
D-017 — Dashboard KPI Fase 1
- Tanggal: 2026-05-23
- Keputusan:
- Dashboard ops minimum menampilkan: transaksi hari ini, success rate hari ini, active devices, pending notifications, stale/offline counts.
- Alasan:
- Tim operasi perlu indikator cepat tanpa menunggu custom analytics.
- Dampak / implikasi:
- Endpoint summary dashboard wajib dihitung dari data transaksi/device/notification inti.
- Status: Active
D-018 — Pencairan Dana Non-Tersentral per Merchant
- Tanggal: 2026-05-24
- Keputusan:
- Pencairan dana tidak dilakukan di rekening perusahaan; setiap merchant memakai rekening tujuan sendiri (atau reference payout miliknya) untuk settlement.
- Alasan:
- Menghindari ketergantungan izin/operasional PJP di tahap awal dan mempercepat launch MVP.
- Dampak / implikasi:
- Schema dan model onboarding merchant memakai
payout_account_reference/rekening merchant, bukan rekening vault pusat. - Modul settlement platform difokuskan ke rekonsiliasi, status payout, dan visibility, bukan pengelolaan rekening pusat.
- Callback payout dan payout execution dianggap partner-oriented (tergantung integrasi penyedia), bukan core di fase awal.
- Schema dan model onboarding merchant memakai
- Status: Active
D-019 — Fase 1 Audit Log dan Ledger Placeholder
- Tanggal: 2026-05-26
- Keputusan:
- Fase 1 mencatat audit log untuk aksi admin/webhook penting dan membuat ledger placeholder
gross_incomesaat transaksi berubah kepaid.
- Fase 1 mencatat audit log untuk aksi admin/webhook penting dan membuat ledger placeholder
- Alasan:
- Acceptance Fase 1 membutuhkan audit aksi CRUD penting, callback state changes, dan placeholder ledger untuk transaksi sukses tanpa menunggu modul finance penuh.
- Dampak / implikasi:
audit_logsmenjadi sumber trace operasional awal untuk entity penting.ledger_entriesFase 1 hanya placeholder gross income; fee/platform payable detail tetap masuk Fase 3.- Duplicate paid callback tetap idempotent dan tidak membuat ledger duplikat karena unique key per
transaction_id + entry_type.
- Status: Active
D-020 — Awal Fase 2 Dynamic QR API-Direct
- Tanggal: 2026-05-26
- Keputusan:
- Fase 2 dimulai dari capability resolver dan endpoint
POST /device/transactions/dynamic-qruntuk devicecommunication_mode=api. - Dynamic QR API-direct memakai mock QRIS payload lokal sampai integrasi partner QRIS tersedia.
- Fase 2 dimulai dari capability resolver dan endpoint
- Alasan:
- Capability/routing harus stabil sebelum MQTT dynamic dan config push dibangun.
- Mock partner memungkinkan transaksi dynamic tersimpan dan callback Fase 1 tetap diuji sebagai source of truth.
- Dampak / implikasi:
- Device static/MQTT yang tidak memiliki capability
dynamic_qr.api_directditolak denganDEVICE_CAPABILITY_NOT_SUPPORTED. - Device wajib punya binding aktif ke terminal
qr_mode=dynamic_api; jika tidak, API mengembalikanDEVICE_NOT_BOUND. - Response dynamic QR idempotent memakai
Idempotency-Keyataurequest_id, dan transaksi dibuatawaiting_payment. - Callback paid tetap memakai endpoint webhook yang sama untuk mengubah transaksi menjadi
paiddan memicu notifikasi.
- Device static/MQTT yang tidak memiliki capability
- Status: Active
D-021 — MQTT Dynamic QR dan Device Config Fase 2
- Tanggal: 2026-05-26
- Keputusan:
- MQTT dynamic QR Fase 2 diimplementasikan sebagai HTTP simulator endpoint
POST /device/mqtt/uplink/dynamic-qr/requestyang mencatat uplink/downlink kemqtt_messages. - Config push memakai
PATCH /admin/devices/{deviceId}/config, disimpan didevice_configs, dipublish ke MQTT outbox, lalu device mengirimPOST /device/config/ack.
- MQTT dynamic QR Fase 2 diimplementasikan sebagai HTTP simulator endpoint
- Alasan:
- Belum ada broker MQTT sungguhan di stack lokal, tapi kontrak topic/payload dan idempotency perlu bisa diuji end-to-end.
- Outbox membuat downlink response/config push observable lewat admin sebelum integrasi broker asli.
- Dampak / implikasi:
- Saat broker MQTT dipasang,
mqtt_messagesbisa menjadi outbox/trace awal untuk adapter broker. - Dynamic MQTT request memakai
request_idsebagaicorrelation_iddan idempotency key. - Device config selalu versioned; ACK dicatat terpisah di
device_config_acks.
- Saat broker MQTT dipasang,
- Status: Active
D-022 — Config Drift dan Retry Push Fase 2
- Tanggal: 2026-05-26
- Keputusan:
- Fase 2 menambahkan status drift config device melalui
GET /admin/devices/{deviceId}/config/status. - Retry config dilakukan via
POST /admin/devices/{deviceId}/config/retry-pushtanpa menaikkanconfig_version. - ACK config dari device juga dicatat sebagai uplink trace di
mqtt_messagesdenganmessage_type=config_ack.
- Fase 2 menambahkan status drift config device melalui
- Alasan:
- Operasi perlu membedakan config
applied,pending_ack,failed_ack,stale_ack, dannever_pushedsebelum broker MQTT sungguhan dipasang. - Retry harus mengirim ulang desired config yang sama agar idempotent dan tidak membuat drift versi buatan.
- Operasi perlu membedakan config
- Dampak / implikasi:
- Config yang sudah
appliedtidak boleh di-retry kecuali admin mengirimforce=true. mqtt_messagesmenjadi timeline awal untuk config push dan ACK device.- Saat broker MQTT asli masuk, endpoint retry tetap menjadi trigger adapter/outbox, bukan tempat menyimpan logic konfigurasi baru.
- Config yang sudah
- Status: Active
D-023 — Health Summary Device Fase 2
- Tanggal: 2026-05-26
- Keputusan:
- Endpoint admin device menambahkan
health_summaryberisistatus,score,age_seconds, danreasons. derived_statustetap dipertahankan untuk kompatibilitas UI, namun nilainya berasal dari rule health summary yang sama.
- Endpoint admin device menambahkan
- Alasan:
- Operasi membutuhkan konteks kenapa device online/degraded/stale/offline, bukan hanya label status.
- Skor 0-100 memudahkan sorting/filter dashboard tanpa mengubah threshold status Fase 1.
- Dampak / implikasi:
- Status masih mengikuti threshold Fase 1: online <90 detik, stale >90 detik, offline >15 menit, degraded untuk sinyal/baterai buruk.
- UI dapat memakai
health_summary.reasonsuntuk badge/tooltip ops.
- Status: Active
D-024 — UI Ops Device Fase 2
- Tanggal: 2026-05-26
- Keputusan:
- UI device registry dan device technical detail menampilkan
health_summarydan config delivery status. - Retry config push tersedia dari drawer device registry dan halaman detail device.
- UI device registry dan device technical detail menampilkan
- Alasan:
- Operator perlu melihat status Fase 2 tanpa membuka raw payload/API response.
- Retry config adalah tindakan operasional langsung, sehingga harus dekat dengan status drift config.
- Dampak / implikasi:
- UI memakai endpoint
GET /admin/devices/{deviceId}/config/statusdanPOST /admin/devices/{deviceId}/config/retry-push. derived_statustetap dipakai sebagai fallback/compatibility, sementara health score/reasons menjadi konteks tambahan.
- UI memakai endpoint
- Status: Active
D-025 — Dynamic QR Expiry Sweep Fase 2
- Tanggal: 2026-05-26
- Keputusan:
- Dynamic QR
awaiting_paymentyang melewatiexpired_atdapat ditutup oleh sweep internalPOST /admin/transactions/expire-due. - Sweep hanya berlaku untuk transaksi
qr_mode=dynamicdan statusawaiting_payment.
- Dynamic QR
- Alasan:
- Fase 2 tidak boleh bergantung penuh pada callback partner untuk menutup QR yang kadaluarsa.
- Expiry internal menjaga daftar transaksi pending tetap akurat untuk ops dan device flow.
- Dampak / implikasi:
- Sweep menulis
STATE_CHANGEDevent dengan reasondynamic_qr_expired. - Callback paid yang datang setelah transaksi sudah
expiredtetap ditolak oleh state transition guard. - Endpoint admin ini bisa menjadi dasar scheduler/background worker saat fase operasional berikutnya.
- Sweep menulis
- Status: Active