feat(admin): admin grant — raw benefits and by-product reward bundles #232

Merged
developer merged 2 commits from feature/e7-admin-grant into development 2026-07-10 04:37:43 +00:00
Owner

Third slice of the admin / reports / catalog work (PR1 #230 finance panel, PR2 #231 catalog editor).

Admin grant (user card)

A Grant panel on the /_gm user card:

  • raw grant — hints / no-ads days / forever, origin-picked → payments.Grant;
  • by-product grant — pick a defined value product (a reward bundle, including an archived
    one) → payments.GrantProduct, which records the source product_id + snapshot on the ledger.

Both write an admin_grant ledger row and refuse a chips atom (admin never grants currency)
or a tournament atom (no credit target until the tournament stage). Chips/tournament products are
also excluded from the by-product picker. This replaces the grant-hints action retired in the ads slice.

Tests

  • TestConsoleAdminGrant — CSRF-guarded; a raw grant (hints + no-ads term) lands on the benefit; a
    by-product grant of an archived reward bundle lands; a chips pack is refused.
  • Full backend unit + integration green; build/vet/gofmt clean.
Third slice of the admin / reports / catalog work (PR1 #230 finance panel, PR2 #231 catalog editor). ## Admin grant (user card) A **Grant** panel on the `/_gm` user card: - **raw grant** — hints / no-ads days / forever, origin-picked → `payments.Grant`; - **by-product grant** — pick a defined **value product** (a reward bundle, including an archived one) → `payments.GrantProduct`, which records the source `product_id` + snapshot on the ledger. Both write an `admin_grant` ledger row and **refuse** a `chips` atom (admin never grants currency) or a `tournament` atom (no credit target until the tournament stage). Chips/tournament products are also excluded from the by-product picker. This replaces the grant-hints action retired in the ads slice. ## Tests - `TestConsoleAdminGrant` — CSRF-guarded; a raw grant (hints + no-ads term) lands on the benefit; a by-product grant of an archived reward bundle lands; a chips pack is refused. - Full backend unit + integration green; build/vet/gofmt clean.
developer added 1 commit 2026-07-10 03:36:08 +00:00
feat(admin): admin grant — raw benefits and by-product reward bundles
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 26s
CI / ui (pull_request) Has been skipped
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m48s
d2d6955cbf
The /_gm user card gains a Grant panel: grant raw benefit atoms (hints /
no-ads days / forever) or a defined value product (a reward bundle, including
an archived one), origin-picked. Both write an admin_grant ledger row via
payments.Grant / GrantProduct; the by-product grant records the source
product_id + snapshot. Both refuse a chips atom (never grant currency) or a
tournament atom (no credit target yet); chips/tournament products are also
kept out of the by-product picker.

Tests: the console grant end to end (raw, by-product, refuse a chips pack,
CSRF-guarded).
developer added 1 commit 2026-07-10 04:26:50 +00:00
fix(game): show granted/bought hints in-game — finish the D31 wire removal
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m11s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m58s
82648a4398
The in-game hint badge ignored the payments hint wallet: loading a game clobbered
app.profile.hintBalance with the deprecated StateView.wallet_balance (zeroed in the
D31 domain removal but left in the protocol as a dead 0, then synced over the real
balance at game load).

Finish the removal honestly. StateView carries the per-game allowance alone
(hints_remaining); the purchasable wallet lives solely on the profile and the client
adds it (lib/hints). Removed StateView.wallet_balance across every layer — backend
StateView/DTO, notify.PlayerState (live events), gateway StateResp + wire.StateView,
the client model/codec/mock/localgame — and dropped the now-unused wallet arg from
hintsRemaining. The FBS field is tombstoned `(deprecated)` (not deleted) so the vtable
slots after it stay stable across a rolling deploy; no accessor is generated. HintResult
keeps wallet_balance (the real post-spend payments balance the client adopts into the
profile). The StateView type no longer has walletBalance, so the clobber cannot return
without a compile error.

Tests: hintsRemaining (2-arg); hints.hintsLeft (allowance + live wallet, no strip); the
game state/hint integration (allowance-only HintsRemaining); gateway transcode; FBS regen.
owner approved these changes 2026-07-10 04:36:54 +00:00
developer merged commit ec5c6afa23 into development 2026-07-10 04:37:43 +00:00
developer deleted branch feature/e7-admin-grant 2026-07-10 04:37:43 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#232