EnakGame phase 10 of docs/tasks-enakgame.md (EG-1001 to EG-1003). Spin (EG-1001) - PROBABILITY entries take an optional label (a wheel segment). The customer game list shows a PROBABILITY game's prizes (entry, label, amount, never weights), and completing returns the drawn prize, so the client can draw the wheel and stop it on the server's draw. - docs/enakgame-spin.md: the admin steps to set up spin per organization (no seeder) and the customer app flow. An HTTP test plays it end to end. Old game flow removed (EG-1002) - Routes POST /customer/spin, GET /customer/games, GET /customer/ferris-wheel, and admin /marketing/games, /marketing/game-prizes, /marketing/rewards, with their handlers, services, processors, repositories, validators, models, contracts, mappers and tests (GamePlayProcessor, SpinGameService, rewards, ...). This also closes RFC §15 findings 1 and 2 (double charge, spinning another org's game). - Tables games, game_prizes, game_plays and rewards stay for ledger history. entities.StringSlice moves to its own file; the omset tracker (unrouted) keeps game_id but no longer embeds the old game response. games.is_active dropped (EG-1003) - Migration 000115; nothing reads metadata.coin_cost any more. The EnakPoint integration docs now point at /customer/enakgame. The Postgres tests were not run: no test database here. Migration 000115 has not been run anywhere. The customer app must stop calling the removed endpoints before this is deployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.0 KiB
Spin sebagai Game EnakGame
Sumber: RFC EnakGame §14, task EG-1001 Pembaca: admin organisasi dan tim backoffice / aplikasi customer
Spin lama (POST /customer/spin) diganti dengan game EnakGame biasa: tipe SPIN,
reward PROBABILITY, hadiah berupa EnakCoin. Spin dimainkan lewat endpoint session
yang sama dengan game lain, sehingga ikut mendapat idempotency, refund otomatis, budget,
event, dan Economy Guard.
Tidak ada seeder: setiap organisasi membuat spin-nya sendiri lewat API admin di bawah. Semua langkah memakai token admin organisasi; langkah 2–4 butuh loyalty manager.
Langkah Admin
1. Buat game
POST /api/v1/marketing/enakgame/games
{
"name": "Spin Harian",
"slug": "spin",
"type": "SPIN",
"entry_cost": 5,
"status": "ACTIVE",
"thumbnail_url": "https://…/spin.png",
"game_url": "https://…/spin/index.html"
}
entry_cost adalah EnakCoin yang dipotong setiap kali spin (minimal 1).
2. Buat reward config PROBABILITY
POST /api/v1/marketing/enakgame/games/:id/reward-configs
{
"reward_type": "PROBABILITY",
"max_reward": 50,
"rules": {
"table": [
{ "weight": 50, "amount": 0, "label": "Zonk" },
{ "weight": 30, "amount": 3, "label": "3 Coin" },
{ "weight": 15, "amount": 10, "label": "10 Coin" },
{ "weight": 5, "amount": 50, "label": "Jackpot" }
]
},
"reason": "Spin pertama"
}
- Satu baris
table= satu segmen roda, urut searah gambar roda. weightbilangan bulat ≥ 1. Peluang segmen =weight÷ total weight (di atas: 50%, 30%, 15%, 5%). Weight tidak pernah dikirim ke customer.amountEnakCoin yang didapat (boleh 0).labelopsional, maksimal 100 karakter, ditampilkan di roda.max_rewardminimal sebesaramountterbesar, kalau tidak hadiah besar terpotong.
3. Aktifkan config
POST /api/v1/marketing/enakgame/reward-configs/:id/activate
Mengganti hadiah nanti berarti membuat versi config baru lalu mengaktifkannya; session yang sedang berjalan tetap memakai versi saat dimulai.
4. Pastikan ada budget global bulan berjalan
POST /api/v1/marketing/enakgame/budgets dengan scope: "GLOBAL", bila belum ada. Tanpa
budget global, customer tidak bisa memulai game apa pun.
Alur di Aplikasi Customer
GET /api/v1/customer/enakgame/games: game spin punyaprizes, yaitu segmen roda (entry,label,amount) dalam urutan config. Gambar roda dari sini.POST /api/v1/customer/enakgame/sessionsdengan{"game_id": "…"}dan headerIdempotency-Key. Entry cost dipotong di sini.POST /api/v1/customer/enakgame/sessions/:id/completedengan body{}. Server yang mengundi. Response berisiprize(entry,label,amount): putar roda sampai berhenti di segmenentryitu.reward_totaladalah Coin yang benar-benar masuk, bisa lebih besar dariprize.amountkarena event, atau lebih kecil karena limit harian (limited_by).
Aplikasi tidak boleh mengundi sendiri atau mengirim hadiah: apa pun yang dikirim selain data hasil diabaikan.