feat(registry): premium items: catalog, entitlements and signed tickets #14

Merged
kblack0610 merged 1 commit from feat/entitlements into main 2026-11-04 02:13:33 +00:00
Owner

Phase 1 of the premium-content plan: the registry keeps a catalog of premium items and what each account owns, and signs a short-lived ticket a game server checks.

  • migrations/0004_entitlements.sql: catalog_items (PK game+item_id) and entitlements (account FK with ON DELETE CASCADE, FK to the catalog item, unique (source, receipt_id), revoked_at).
  • catalog.json (empty for now) is upserted at boot; items missing from it are marked inactive, never deleted. A malformed file stops boot.
  • Routes: GET /api/v1/catalog[?game=] (public), GET /api/v1/entitlements/me[?game=] and POST /api/v1/entitlements/ticket[?game=] (account), POST /api/v1/entitlements/verify (server or host token), POST|DELETE /api/v1/admin/entitlements (ADMIN_TOKEN).
  • Env: ENTITLEMENT_SECRET (at least 32 chars, shorter stops boot, unset turns tickets off with 503, as ACCOUNT_PEPPER does for accounts), ENTITLEMENT_TICKET_SEC (default 300).
  • Tests in entitlements_test.go: catalog filter and retire, grant/list/revoke, a receipt grants once, cascade on account delete, ticket round trip, expired and tampered tickets, wrong auth, tickets off.

Removed: nothing; this is new. go vet ./... and go test ./... pass locally. Release tag and the home-config bump come after merge.

https://claude.ai/code/session_01BALUC4Q8G6QL3byFZR6Mhu

Phase 1 of the premium-content plan: the registry keeps a catalog of premium items and what each account owns, and signs a short-lived ticket a game server checks. - `migrations/0004_entitlements.sql`: `catalog_items` (PK game+item_id) and `entitlements` (account FK with ON DELETE CASCADE, FK to the catalog item, unique (source, receipt_id), `revoked_at`). - `catalog.json` (empty for now) is upserted at boot; items missing from it are marked inactive, never deleted. A malformed file stops boot. - Routes: `GET /api/v1/catalog[?game=]` (public), `GET /api/v1/entitlements/me[?game=]` and `POST /api/v1/entitlements/ticket[?game=]` (account), `POST /api/v1/entitlements/verify` (server or host token), `POST|DELETE /api/v1/admin/entitlements` (ADMIN_TOKEN). - Env: `ENTITLEMENT_SECRET` (at least 32 chars, shorter stops boot, unset turns tickets off with 503, as ACCOUNT_PEPPER does for accounts), `ENTITLEMENT_TICKET_SEC` (default 300). - Tests in `entitlements_test.go`: catalog filter and retire, grant/list/revoke, a receipt grants once, cascade on account delete, ticket round trip, expired and tampered tickets, wrong auth, tickets off. Removed: nothing; this is new. `go vet ./...` and `go test ./...` pass locally. Release tag and the home-config bump come after merge. https://claude.ai/code/session_01BALUC4Q8G6QL3byFZR6Mhu
- migrations/0004: catalog_items (game, item_id PK) and entitlements (cascade on account delete, unique source+receipt_id, revoked_at)
- catalog.json is upserted at boot; items missing from it go inactive, never deleted
- GET /api/v1/catalog, GET /api/v1/entitlements/me, POST /api/v1/entitlements/ticket and /verify, POST|DELETE /api/v1/admin/entitlements
- ENTITLEMENT_SECRET (HMAC key, at least 32 chars, unset turns tickets off) and ENTITLEMENT_TICKET_SEC (default 300)

Claude-Session: https://claude.ai/code/session_01BALUC4Q8G6QL3byFZR6Mhu
kblack0610 deleted branch feat/entitlements 2026-11-04 02:13:34 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kblack0610/bnb-game-servers!14
No description provided.