Files
Qris-Soundbox/DECISIONS_LOG.md

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.
  • 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

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_income saat transaksi berubah ke paid.
  • 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_logs menjadi sumber trace operasional awal untuk entity penting.
    • ledger_entries Fase 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-qr untuk device communication_mode=api.
    • Dynamic QR API-direct memakai mock QRIS payload lokal sampai integrasi partner QRIS tersedia.
  • 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_direct ditolak dengan DEVICE_CAPABILITY_NOT_SUPPORTED.
    • Device wajib punya binding aktif ke terminal qr_mode=dynamic_api; jika tidak, API mengembalikan DEVICE_NOT_BOUND.
    • Response dynamic QR idempotent memakai Idempotency-Key atau request_id, dan transaksi dibuat awaiting_payment.
    • Callback paid tetap memakai endpoint webhook yang sama untuk mengubah transaksi menjadi paid dan memicu notifikasi.
  • 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/request yang mencatat uplink/downlink ke mqtt_messages.
    • Config push memakai PATCH /admin/devices/{deviceId}/config, disimpan di device_configs, dipublish ke MQTT outbox, lalu device mengirim POST /device/config/ack.
  • 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_messages bisa menjadi outbox/trace awal untuk adapter broker.
    • Dynamic MQTT request memakai request_id sebagai correlation_id dan idempotency key.
    • Device config selalu versioned; ACK dicatat terpisah di device_config_acks.
  • 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-push tanpa menaikkan config_version.
    • ACK config dari device juga dicatat sebagai uplink trace di mqtt_messages dengan message_type=config_ack.
  • Alasan:
    • Operasi perlu membedakan config applied, pending_ack, failed_ack, stale_ack, dan never_pushed sebelum broker MQTT sungguhan dipasang.
    • Retry harus mengirim ulang desired config yang sama agar idempotent dan tidak membuat drift versi buatan.
  • Dampak / implikasi:
    • Config yang sudah applied tidak boleh di-retry kecuali admin mengirim force=true.
    • mqtt_messages menjadi 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.
  • Status: Active

D-023 — Health Summary Device Fase 2

  • Tanggal: 2026-05-26
  • Keputusan:
    • Endpoint admin device menambahkan health_summary berisi status, score, age_seconds, dan reasons.
    • derived_status tetap dipertahankan untuk kompatibilitas UI, namun nilainya berasal dari rule health summary yang sama.
  • 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.reasons untuk 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_summary dan config delivery status.
    • Retry config push tersedia dari drawer device registry dan halaman detail device.
  • 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/status dan POST /admin/devices/{deviceId}/config/retry-push.
    • derived_status tetap dipakai sebagai fallback/compatibility, sementara health score/reasons menjadi konteks tambahan.
  • Status: Active

D-025 — Dynamic QR Expiry Sweep Fase 2

  • Tanggal: 2026-05-26
  • Keputusan:
    • Dynamic QR awaiting_payment yang melewati expired_at dapat ditutup oleh sweep internal POST /admin/transactions/expire-due.
    • Sweep hanya berlaku untuk transaksi qr_mode=dynamic dan status awaiting_payment.
  • 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_CHANGED event dengan reason dynamic_qr_expired.
    • Callback paid yang datang setelah transaksi sudah expired tetap ditolak oleh state transition guard.
    • Endpoint admin ini bisa menjadi dasar scheduler/background worker saat fase operasional berikutnya.
  • Status: Active