Commit Graph
9 Commits
Author SHA1 Message Date
efrilmandClaude Opus 5.5 18e87398bb feat(enakgame): spin as an EnakGame game; remove the old game flow
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>
2026-10-07 21:31:56 +07:00
efrilmandClaude Opus 5.5 798a36bd6c feat(enakgame): game sessions, rewards, vouchers, budgets and events
EnakGame phases 1-8 of docs/tasks-enakgame.md (EG-101 to EG-803), built on the
existing EnakPoint/EnakCoin wallet (docs/rfc-enakgame.md).

Foundation (phase 1)
- Migrations 000103-000106: games extended with organization, slug, status,
  entry cost and result rules, old games archived (not deleted); budgets,
  versioned reward configs, sessions and session rewards; the ledger types
  GAME_SPEND_REFUND, GAME_REWARD and REWARD_REDEEM_REFUND; audit_logs.
- AuditLogger writes in the caller's transaction only.
- enakgame.limit.user_daily and global_daily organization settings.

Games and sessions (phases 2-4)
- Admin /marketing/enakgame: games, reward config versions (immutable but for
  status, one ACTIVE per game), budgets with non-overlapping global periods and
  a daily job opening the next month.
- Customer /customer/enakgame: start (Idempotency-Key, entry cost and config
  frozen on the session), complete (result validation, reward engine, max_reward
  cap, daily limits via game_reward_counters, one GAME_REWARD per budget),
  automatic refunds for system errors and deactivated games, and a session job.
- Reward engine: FIXED, SCORE_BASED, OUTCOME_BASED, PROBABILITY (crypto/rand),
  rounded down.

Vouchers and budgets (phases 5-6)
- Migration 000108 and 000107: vouchers, codes, redemptions, cost attribution;
  Economy Guard counters.
- STATIC and CODE_POOL redemption in one transaction with the REDEEM PIN action;
  realized cost traced through the lots to the budget that paid the reward.
- Budget metrics: realized cost, forecast, exposure and status. Migrations
  000109-000110 add the wallet_lots indexes they need, built CONCURRENTLY.

Events (phase 7)
- Migration 000111: game events, each with its own EVENT budget. Event extras
  stack per PRD §16 defaults, with event and per-customer limits.

External vouchers (phase 8)
- VoucherProvider contract, two-step PENDING redemption and a recovery job,
  tested with a fake provider. No provider adapter is registered yet, so
  EXTERNAL vouchers stay out of the catalog.

Not yet decided before release: reward rounding, event stacking, budget
exhaustion policy and thresholds (RFC §19.2). Migrations 000103-000111 have
not been run on any shared database.

Also fixes a leftover PAYMENT filter in a wallet test and a data race in a
test PIN fake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:53:14 +07:00
efrilmandClaude Opus 5.5 2c9753fae7 feat(loyalty): remove paying with EnakPoint
EnakPoint can only be redeemed for vouchers now: it can no longer pay for
orders and is never cashed out (docs/enakgame-prd.md §3.2, EG-001,
EG-002). No order was ever paid with EnakPoint, so there is no data to
move.

Removed:
- POST /customer/wallet/payment-code, POST /customer/orders/:id/pay-with-points
  and GET /orders/:id/point-payment/preview, with their processors,
  repositories, services, handlers and tests.
- The point payment method type: paying, splitting and refunding with it,
  the outlet filter on the method list, and the system-method guard.
- points and payment_code on CreatePayment; points_used and point_value
  on payments; accepts_point_payment on the customer outlets.
- The outlet point_payment settings. A PUT that still sends them is
  rejected as an unknown field.
- The EnakPoint split in the payment method analytics.
- PAYMENT and PAYMENT_REFUND from the wallet type rules. Tests that used
  them as a generic EnakPoint debit use REWARD_REDEEM.
- The EnakPoint-paid part from the earning basis, which is
  subtotal − discount again.

Migration 000102 drops the trigger, the point methods and their index,
the payments columns, and the outlet settings, and restores the method
type CHECK without point. payments.payment_method_id is ON DELETE
RESTRICT, so it fails rather than lose a payment made with EnakPoint.

The integration docs list the removed endpoints and fields, and the
EnakPoint & EnakCoin PRD and tasks note what is superseded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:48:29 +07:00
efrilm b372821b23 feat: add percentage loyalti setting mode 2026-10-02 14:19:12 +07:00
efrilmandClaude Opus 5.5 f16a5da951 docs(customer): mobile app guide, outlets, order history and registration
Adds docs/mobile-customer-enakpoint.md, written as a brief for building the
customer app: the UI rules, the API conventions, each screen with its
requests and responses, push handling, PIN flows, paying at the cashier,
exchange, transfer, games, what was removed, and a checklist. It covers the
new GET /customer/outlets, GET /customer/orders and /customer/orders/:id,
and the optional organization_id at registration, which the API reference
now lists too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 19:39:52 +07:00
efrilmandClaude Opus 5.5 c988a79d3b refactor(loyalty): remove what is left of tokens
Tokens are EnakCoin and no app uses the token names any more, so their
compatibility layer goes:

- GET /customer/tokens and its handler, service, processor and response
  types.
- total_tokens and tokens_history on GET /customer/wallet; last_updated
  now comes from the most recent row of either currency.
- token_used and tokens_remaining on game and spin responses, and
  sort_by=token_used on the game play list.
- TOKENS as a campaign type and reward type, with the mapping to COINS:
  migration 000092 already renamed the stored values.

The customer_tokens table and its entity stay, as cmd/wallet-migrate still
reads them, and LEGACY_TOKENS stays as the reference of the MIGRATION rows
it wrote. The docs list the removed names and their replacements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:55:27 +07:00
efrilm 582dc75543 Reapply "feat(loyalty): EnakPoint & EnakCoin" (#32)
This reverts commit 4e24f9bbb0.
2026-09-30 15:31:44 +07:00
efrilmandClaude Opus 5.5 4e24f9bbb0 Revert "feat(loyalty): EnakPoint & EnakCoin" (#32)
This reverts merge commit 645da30, returning main to f0ff59f.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:16:15 +07:00
efrilmandClaude Opus 5.5 ae8003c1e4 docs(loyalty): API reference and backoffice guide for EnakPoint & EnakCoin
Adds docs/api-enakpoint.md, the endpoint reference for the customer app,
POS and dashboard, and docs/backoffice-enakpoint.md, the screens the
backoffice needs: outlet and organization settings with the save flow and
impact dialog, both expiry models, the customer wallet with adjustment and
trace, PIN removal and security log, settings history, game coin_cost and
the EnakPoint payment method.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:01:02 +07:00