Initial commit
This commit is contained in:
154
16-fase1-step4-monitoring-spec.md
Normal file
154
16-fase1-step4-monitoring-spec.md
Normal file
@ -0,0 +1,154 @@
|
||||
# Fase 1 — Step 4: Device & Ops Monitoring
|
||||
|
||||
Dokumen ini merinci implementasi heartbeat, status device, list/detail monitoring, dan KPI dasar admin untuk selesai dari Step 4.
|
||||
|
||||
## 1) Tujuan Step 4
|
||||
- Menyediakan visibilitas operasional untuk device dan transaksi di admin
|
||||
- Menjadikan heartbeat sebagai sumber status online device
|
||||
- Menyediakan metrik minimum yang dipakai tim operasi harian
|
||||
- Menyediakan jalur retry/penelusuran notifikasi pending
|
||||
|
||||
## 2) Heartbeat Ingestion
|
||||
|
||||
### Endpoint
|
||||
- `POST /device/heartbeat`
|
||||
|
||||
### Request
|
||||
```json
|
||||
{
|
||||
"device_id": "sbx_001",
|
||||
"timestamp": "2026-05-23T10:00:00Z",
|
||||
"firmware_version": "1.0.3",
|
||||
"network_strength": 78,
|
||||
"battery_level": 92,
|
||||
"state": "idle"
|
||||
}
|
||||
```
|
||||
|
||||
### Rules
|
||||
- Validate token device.
|
||||
- Simpan ke `device_heartbeats`.
|
||||
- Update `devices.last_seen_at = timestamp`.
|
||||
- Jika field missing, simpan `null` dan tetap catat validasi non-kritis:
|
||||
- `network_strength` / `battery_level` boleh null
|
||||
- Return response:
|
||||
- `request_id`
|
||||
- `device_id`
|
||||
- `server_time`
|
||||
|
||||
### Status Derivation (Step 4)
|
||||
- `online`: `last_seen_at >= now - 90 detik`
|
||||
- `degraded`: `network_strength < 40` **atau** `battery_level < 20`
|
||||
- `stale`: `last_seen_at < now - 90 detik` dan >= `now - 15 menit`
|
||||
- `offline`: `last_seen_at < now - 15 menit`
|
||||
- Kombinasi prioritas: `offline`/`stale`/`degraded`/`online` (offline paling dominan)
|
||||
|
||||
## 3) Endpoint Monitoring Dasar
|
||||
|
||||
### List Device
|
||||
- `GET /admin/devices`
|
||||
- query:
|
||||
- `status`
|
||||
- `vendor`
|
||||
- `communication_mode`
|
||||
- `merchant_id`
|
||||
- `q` (search)
|
||||
- response: include:
|
||||
- `status`
|
||||
- `last_seen_at`
|
||||
- `heartbeat_count_24h`
|
||||
- binding current summary
|
||||
|
||||
### Device Detail
|
||||
- `GET /admin/devices/{deviceId}`
|
||||
- response include:
|
||||
- metadata device
|
||||
- binding aktif (merchant/outlet/terminal)
|
||||
- latest heartbeat
|
||||
- derived status + device health
|
||||
- `notifications` latest
|
||||
|
||||
### Heartbeat List
|
||||
- `GET /admin/devices/{deviceId}/heartbeats`
|
||||
- filter:
|
||||
- `from`, `to`, `state`
|
||||
- sort: latest first
|
||||
|
||||
### Transaction List/Detail (minimal lanjutan Step 4)
|
||||
- `GET /admin/transactions`
|
||||
- filter `status`, `merchant_id`, `from`, `to`, `partner_reference`
|
||||
- `GET /admin/transactions/{transactionId}`
|
||||
- include `transaction_events` timeline
|
||||
|
||||
## 4) KPI Dashboard Minimal (admin)
|
||||
|
||||
### Endpoint
|
||||
- `GET /admin/dashboard/summary`
|
||||
|
||||
### Metrics
|
||||
- `transactions_today`
|
||||
- `success_rate_today` (paid / total attempt)
|
||||
- `active_devices`
|
||||
- `pending_notifications`
|
||||
- `devices_stale`
|
||||
- `devices_offline`
|
||||
|
||||
### Data Source
|
||||
- transaksi hari ini dari `transactions.created_at`
|
||||
- device status dari `devices.last_seen_at`
|
||||
- pending notification dari `notifications.delivery_status in ('queued','retrying')`
|
||||
|
||||
## 5) Admin Retry-notification (Step 4)
|
||||
|
||||
### Endpoint
|
||||
- `POST /admin/transactions/{transactionId}/retry-notification`
|
||||
|
||||
### Flow
|
||||
1. validasi transaksi exists dan status `paid`
|
||||
2. ambil latest notification `delivery_status` != `acknowledged`
|
||||
3. jika `delivery_status` = `queued/sent/failed/retrying`:
|
||||
- trigger publish ulang
|
||||
- tambah `retry_count`
|
||||
4. simpan hasil status setelah publish
|
||||
5. return:
|
||||
- `transaction_id`
|
||||
- `notification_id`
|
||||
- `delivery_status`
|
||||
- `next_retry_at`
|
||||
|
||||
## 6) Monitoring Notifikasi Gagal
|
||||
- endpoint ops:
|
||||
- `GET /admin/notifications/failed`
|
||||
- filter:
|
||||
- `device_id`
|
||||
- `from`
|
||||
- `to`
|
||||
- response:
|
||||
- `notification_id`, `transaction_id`, `device_id`, `delivery_status`, `retry_count`, `reason`
|
||||
|
||||
## 7) Query Efficiency (Prioritas)
|
||||
- buat index:
|
||||
- `devices(status, last_seen_at)`
|
||||
- `device_heartbeats(device_id, received_at desc)`
|
||||
- `transactions(status, created_at)`
|
||||
- `notifications(delivery_status, created_at)`
|
||||
|
||||
## 8) Acceptance Criteria Step 4
|
||||
- status device berubah sesuai aturan `online/degraded/stale/offline`
|
||||
- heartbeat tercatat dan `devices.last_seen_at` terupdate
|
||||
- dashboard summary menampilkan 5 metrik minimal
|
||||
- `GET /admin/transactions` dan device/transaction detail menampilkan data yang dibutuhkan
|
||||
- endpoint retry-notification memicu publish ulang untuk status non-final
|
||||
|
||||
## 9) Error Handling
|
||||
- `DEVICE_NOT_FOUND`
|
||||
- `INVALID_HEARTBEAT_PAYLOAD`
|
||||
- `TRANSACTION_NOT_ELIGIBLE_FOR_RETRY`
|
||||
- `DASHBOARD_CALCULATION_ERROR` (fallback graceful: return nilai default 0 jika query gagal)
|
||||
|
||||
## 10) Keluaran Step 4 (End-State)
|
||||
- operator bisa cek:
|
||||
- device aktif/offline
|
||||
- transaksi dan status payment
|
||||
- kegagalan notifikasi
|
||||
- sistem tetap bisa operasi manual meski tanpa UI dashboard kompleks
|
||||
Reference in New Issue
Block a user