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,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