Initial commit
This commit is contained in:
118
14-fase1-step3-notification-spec.md
Normal file
118
14-fase1-step3-notification-spec.md
Normal 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
|
||||
Reference in New Issue
Block a user