# 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`. - 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 dengan `trace_id` jika multi-step. - 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_keys` sejak awal Fase 1. - 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`. - 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 `401` dan tidak boleh melakukan perubahan state apapun. - 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_id` dan diperlakukan idempotent. - 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_events` agar Step 3 dan observability bisa berjalan. - 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. - 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_count` wajib 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_status` bisa `not_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`. - 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. - Status: Active