feat(enakgame): filter play history by game and status
GET /customer/enakgame/sessions takes optional game_id and status, so a game reloaded mid-play finds the session it was running (status=STARTED) instead of starting a new one and charging EnakCoin again. An invalid game_id or status is refused. integration-enakgame.md §4.4 now describes recovery after a reload: keep the session_id in sessionStorage, continue a STARTED session before expires_at, and call complete again for a COMPLETED one to get the full answer, prize included. The mobile guide and RFC §11 mention the filters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b5d2cd491a
commit
52e8fe11c6
@@ -30,7 +30,8 @@ Alasan di balik aturannya ada di [`rfc-enakgame.md`](./rfc-enakgame.md) dan
|
||||
selalu `reward_total` dari backend.
|
||||
3. **Satu tap "Main" = satu `Idempotency-Key`.** Retry memakai key yang sama.
|
||||
4. **Token customer adalah rahasia.** Hanya diterima lewat bridge, disimpan di memori,
|
||||
tidak pernah ditaruh di URL, `localStorage`, cookie, log, atau analytics.
|
||||
tidak pernah ditaruh di URL, `localStorage`, `sessionStorage`, cookie, log, atau
|
||||
analytics. (`session_id` boleh disimpan di `sessionStorage`, §4.4.)
|
||||
5. **Semua jumlah bilangan bulat.** Tidak ada pecahan EnakCoin.
|
||||
6. **Main game tidak butuh PIN.**
|
||||
|
||||
@@ -94,7 +95,8 @@ tunggu `token`, lalu ulangi request yang sama.
|
||||
## 4. Alur satu kali main
|
||||
|
||||
```
|
||||
init ─► GET /customer/enakgame/games ─► tampilkan biaya (dan roda, untuk spin)
|
||||
init ─► cek session yang masih berjalan (§4.4)
|
||||
─► GET /customer/enakgame/games ─► tampilkan biaya (dan roda, untuk spin)
|
||||
─► tap Main ─► POST /customer/enakgame/sessions (EnakCoin dipotong)
|
||||
─► permainan berjalan (batas waktu: expires_at)
|
||||
─► POST /customer/enakgame/sessions/:id/complete (server menghitung hadiah)
|
||||
@@ -227,9 +229,13 @@ sepakati daftarnya dengan tim backoffice.
|
||||
| `310` | `score` bukan bilangan bulat atau `outcome` bukan string | Bug di game |
|
||||
| `404` | Session tidak ada / milik customer lain | Pesan umum |
|
||||
|
||||
### 4.4 Cek status — `GET /customer/enakgame/sessions/:id`
|
||||
### 4.4 Pemulihan setelah reload
|
||||
|
||||
Untuk memulihkan keadaan, mis. game dimuat ulang saat session masih berjalan:
|
||||
Webview bisa memuat ulang halaman game (aplikasi ke background, memori habis, crash)
|
||||
saat customer sedang main. EnakCoin sudah terpotong, jadi game wajib menemukan lagi
|
||||
session-nya. Dua endpoint dipakai:
|
||||
|
||||
**Satu session** — `GET /customer/enakgame/sessions/:id`
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -238,8 +244,35 @@ Untuk memulihkan keadaan, mis. game dimuat ulang saat session masih berjalan:
|
||||
}
|
||||
```
|
||||
|
||||
`status`: `STARTED`, `COMPLETED`, `REFUNDED`, atau `EXPIRED`. Riwayat main customer ada
|
||||
di `GET /customer/enakgame/sessions?page=1&limit=20` (dipakai aplikasi, bukan game).
|
||||
`status`: `STARTED`, `COMPLETED`, `REFUNDED`, atau `EXPIRED`. Response ini tidak memuat
|
||||
`prize` atau rincian hadiah; untuk itu kirim ulang complete (lihat di bawah).
|
||||
|
||||
**Mencari session** — `GET /customer/enakgame/sessions?game_id=8a1f…&status=STARTED&limit=1`
|
||||
|
||||
Bentuk item sama dengan di atas, dibungkus `data` + `pagination`, terbaru di atas.
|
||||
Semua query opsional: `game_id`, `status` (`STARTED`, `COMPLETED`, `REFUNDED`,
|
||||
`EXPIRED`), `page`, `limit`. `status` atau `game_id` yang tidak valid ditolak `304`.
|
||||
|
||||
**Alurnya, setiap kali menerima `init`:**
|
||||
|
||||
1. Simpan `session_id` di **`sessionStorage`** setiap kali start berhasil, dan hapus
|
||||
setelah hasilnya ditampilkan. `session_id` bukan rahasia; token tetap hanya di
|
||||
memori (§1).
|
||||
2. Bila ada `session_id` tersimpan, panggil `GET /sessions/:id`. Bila tidak ada (mis.
|
||||
webview dibuka ulang dari awal), panggil
|
||||
`GET /sessions?game_id=<game_id>&status=STARTED&limit=1`.
|
||||
3. Tindak lanjuti sesuai status:
|
||||
|
||||
| Keadaan | Yang dilakukan game |
|
||||
|---|---|
|
||||
| `STARTED`, sekarang sebelum `expires_at` | **Lanjutkan** session itu: jangan start baru (EnakCoin akan terpotong lagi). Spin: langsung kirim complete `{}` dan tampilkan hasilnya. Game lain: progres main hilang, jadi mulai ulang permainan di session yang sama dengan timer sampai `expires_at`, lalu kirim complete |
|
||||
| `STARTED`, `expires_at` sudah lewat | Anggap selesai. Server mengubahnya menjadi `EXPIRED` (atau merefund bila complete sebelumnya gagal karena error server) dalam ±1 menit. Tampilkan "Waktu bermain habis", lalu customer boleh start baru |
|
||||
| `COMPLETED` | Hasil sudah dihitung tapi mungkin belum ditampilkan. Kirim ulang `POST /sessions/:id/complete` dengan body apa saja (`{}`): server mengembalikan jawaban yang sama persis, termasuk `prize`, tanpa hadiah dobel. Tampilkan hasilnya |
|
||||
| `REFUNDED` | "EnakCoin kamu dikembalikan." |
|
||||
| `EXPIRED` | "Waktu bermain habis." |
|
||||
| Tidak ada session | Tampilkan layar awal seperti biasa |
|
||||
|
||||
Riwayat main lengkap (tanpa filter) dipakai aplikasi customer, bukan game.
|
||||
|
||||
---
|
||||
|
||||
@@ -289,6 +322,7 @@ saja.
|
||||
|
||||
- [ ] Bridge sesuai kontrak §2 yang sudah disepakati dengan tim aplikasi.
|
||||
- [ ] Token hanya di memori; tidak ada di URL, storage, log, atau analytics.
|
||||
- [ ] Pemulihan setelah reload (§4.4): session `STARTED` dilanjutkan, bukan start baru; `COMPLETED` ditampilkan lewat complete ulang.
|
||||
- [ ] Biaya main dan label event tampil sebelum main.
|
||||
- [ ] Satu `Idempotency-Key` per tap Main, dipakai ulang saat retry.
|
||||
- [ ] Complete hanya mengirim `score` / `outcome` / `data`, tidak pernah hadiah.
|
||||
|
||||
@@ -616,6 +616,9 @@ kembali", lalu tutup. Tidak perlu mengirim pesan ke game.
|
||||
|
||||
### 8.4 Riwayat main — `GET /customer/enakgame/sessions?page=1&limit=20`
|
||||
|
||||
Query opsional `game_id` (riwayat satu game) dan `status` (`STARTED`, `COMPLETED`,
|
||||
`REFUNDED`, `EXPIRED`) untuk filter atau tab.
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
|
||||
@@ -842,7 +842,7 @@ tambahkan snapshot harian, bukan cache yang di-invalidate.
|
||||
| `POST` | `/sessions` | §7.1. Wajib `Idempotency-Key` |
|
||||
| `POST` | `/sessions/:id/complete` | §7.2. Idempotent tanpa header |
|
||||
| `GET` | `/sessions/:id` | Status dan hasil |
|
||||
| `GET` | `/sessions` | Riwayat main |
|
||||
| `GET` | `/sessions` | Riwayat main; filter opsional `game_id`, `status` (dipakai game untuk menemukan session `STARTED` setelah reload) |
|
||||
|
||||
Prefix `/enakgame` dipakai karena `/customer/games` sudah dipakai alur spin lama.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user