Initial commit

This commit is contained in:
2026-05-25 08:22:12 +07:00
commit a152c99cce
154 changed files with 39033 additions and 0 deletions

View File

@ -0,0 +1,118 @@
# Fase 1 — Step 3: Notifikasi MQTT Dasar (Static Payment)
Dokumen ini memandu implementasi notifikasi success payment ke device berbasis event transaksi `paid`.
## 1) Tujuan Step 3
- Memastikan setiap transaksi `paid` memicu notifikasi sukses ke device yang valid
- Menyimpan status delivery dan retry agar operasional bisa dipantau
- Menyediakan endpoint admin untuk retry manual
## 2) Event Source
- Trigger dari Step 2: event internal `transaction.paid`
- Sumber wajib: event bus internal / service method call dari transaction service (untuk fase awal)
## 3) Mapping Notifikasi
- Input: `transaction_id`, `merchant_id`, `device_id`, `amount`, `currency`, `paid_at`, `reference`
- Output: payload MQTT `payment_success` ke topik:
- `devices/{deviceId}/downlink/payment/success`
- Hanya kirim jika device memiliki binding aktif (`device_bindings.active_flag = true`)
## 4) Tabel dan Status
### `notifications`
Kolom inti:
- `id`
- `transaction_id`
- `device_id`
- `delivery_channel` = `mqtt`
- `payload_type` = `payment_success`
- `delivery_status`: `queued | sent | acknowledged | failed | retrying`
- `retry_count`
- `ack_status`: `pending | received | not_supported | not_needed`
- `sent_at`
- `ack_at`
Status transisi:
- dibuat -> `queued`
- publish sukses -> `sent`
- no ack handler tersedia pada fase awal -> `acknowledged` otomatis atau `failed` sesuai konfigurasi broker
- publish gagal -> `retrying`
- retry 3x gagal -> `failed`
## 5) Payload Kontrak MQTT (Step 3)
```json
{
"message_type": "payment_success",
"event_id": "evt_123",
"transaction_id": "tx_123",
"merchant_name": "Toko Berkah",
"amount": 50000,
"currency": "IDR",
"paid_at": "2026-05-23T10:02:10Z",
"audio_text": "Pembayaran diterima lima puluh ribu rupiah",
"display_text": "Pembayaran diterima Rp50.000"
}
```
## 6) Alur Proses Notifikasi
1. Step 2 publish event `transaction.paid`
2. Notification Orchestrator menerima event
3. Validasi `device_id` ada dan memiliki binding aktif
4. Buat record `notifications` dengan status `queued`
5. Publish ke `devices/{deviceId}/downlink/payment/success`
6. Jika sukses, update `sent` dan `sent_at`
7. Jika gagal:
- hitung retry (exponential/linear simple backoff)
- update `retrying`
- lanjut retry maksimum 3x
8. Jika 3x gagal tetap `failed`
9. Return result ke endpoint retry bila dipanggil manual
## 7) Retry Policy Fase 1 (Sederhana)
- max_attempt = 3
- retry_interval_seconds = 15, 30, 60 (tetap untuk fase awal)
- retry_count disimpan di `notifications.retry_count`
- tiap percobaan harus idempotent via `event_id` dan `transaction_id`
## 8) Endpoint Admin
- `POST /admin/transactions/{transactionId}/retry-notification`
- validasi transaksi status harus `paid`
- akan membuat attempt publish baru jika `delivery_status` bukan `acknowledged`
- response:
- `transaction_id`
- `notification_id`
- `delivery_status`
- `next_retry_at`
## 9) Endpoint Ops Monitoring Minimal
- `GET /admin/devices/{deviceId}/notifications`
- list notif by device + `delivery_status`
- `GET /admin/transactions/{transactionId}`
- tampilkan link notification + timeline status
## 10) Idempotency dan De-Dupe
- kombinasi key notifikasi:
- `transaction_id + event_id`
- jika event duplicate:
- tidak membuat record baru
- return existing notif status
- publish duplicate harus ditolak di orchestrator (guard).
## 11) Error Code (saran)
- `NOTIFICATION_DEVICE_UNAVAILABLE`
- `NOTIFICATION_NO_ACTIVE_BINDING`
- `NOTIFICATION_PUBLISH_FAILED`
- `NOTIFICATION_RETRY_EXHAUSTED`
## 12) Acceptance Criteria Step 3
- transaksi `paid` menghasilkan event `payment_success` ke topik device
- notification record terbentuk untuk setiap transaksi `paid`
- perangkat yang tidak terikat aktif tidak dipush (state `failed` dengan reason)
- retry berjalan saat publish gagal
- endpoint retry admin merubah status dari `failed/retrying` menjadi `sent` atau tetap `failed` setelah limit
## 13) Catatan Implementasi Step 3 (Tanpa Design)
- gunakan QoS 1 untuk topic payment success
- hindari retained message untuk event sukses pembayaran
- logging harus menyertakan `transaction_id`, `device_id`, `event_id`, `request_id`
- payload audit (audio/display) boleh berupa default ID locale