Skip to content

Entitlements v1 + launch-pacing aura tuning#46

Merged
harshithmullapudi merged 3 commits into
mainfrom
entitlements-v1
Jul 10, 2026
Merged

Entitlements v1 + launch-pacing aura tuning#46
harshithmullapudi merged 3 commits into
mainfrom
entitlements-v1

Conversation

@harshithmullapudi

Copy link
Copy Markdown
Member

Summary

  • Adds a per-user / per-town entitlement system: the current value on the entity IS the effective cap, and an append-only EntitlementGrant table records history for future purchase/milestone/level-up grants (schema only for now, no writers).
  • Enforces the caps at every write path a viral launch could abuse: pickTown (user.maxTowns), POST /api/town (per-town buildings/npcs/customPlots + account-wide maxTotalCustomPlots via jsonb_array_length), realtime-token (town.maxActiveGuests via Centrifugo presence_stats).
  • Tunes launch pacing: hourly aura regen 50 → 10, first-visit guest credit 50 → 5.
  • CLI: postJson prefers server detail so town new surfaces the human-readable limit message; town deploy's existing issue renderer picks up the new { path, message } shape without change.

What's not in this PR

  • Grant flow (purchases, milestones, level-ups) — schema is ready, writers land next.
  • UI for current caps / capacity indicators.
  • Backfill of EntitlementGrant for existing rows — defaults are the truth for pre-existing entities.

Test plan

  • Run pnpm db:migrate on a fresh DB — verify the three ALTER TABLEs and the new EntitlementGrant table land.
  • Existing towns: confirm they pick up defaults (max=10 NPCs, 10 buildings, 5 custom plots, 10 active guests) via the NOT NULL DEFAULT clauses.
  • town new past maxTowns → 403 with You've reached your limit of 3 towns….
  • town deploy with too many NPCs/buildings/customPlots → 403 with per-issue path/message lines rendered by the CLI.
  • town deploy where combined custom-plot count across all owned towns exceeds maxTotalCustomPlots → 403 with the aggregate message.
  • Concurrent visitor cap: with maxActiveGuests set low, a fresh visitor at capacity gets 429 town-at-capacity; owner is exempt.
  • Sanity: with Centrifugo unreachable (unset CENTRIFUGO_API_BASE), the realtime token still mints (fails open).
  • Aura tuning: newly-created towns still regen; a first-time guest visit credits +5 not +50.

🤖 Generated with Claude Code

harshithmullapudi and others added 3 commits July 10, 2026 15:32
Drops the hourly regen from 50 -> 10 and the first-visit guest credit
from 50 -> 5. Prepares the aura curve for the Show HN / Reddit / Bookface
launches where the previous ratios would have let a viral spike blow
through a town's reservoir uncontrollably.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces a first-pass entitlement system so a viral launch can't blow
past the caps we can afford. Every enforceable cap lives directly on
the entity it applies to; the append-only EntitlementGrant table is
history only, populated later when the purchase/milestone/level-up flow
ships.

Schema
- User.tier ("free"), User.maxTowns (3), User.maxTotalCustomPlots (20)
- Town.level (1), Town.xp (0), Town.maxNpcs (10), Town.maxBuildings (10),
  Town.maxCustomPlots (5), Town.maxActiveGuests (10)
- EntitlementGrant model with (userId, townId?, target, delta, source,
  reason?, ref?) — schema only, no writers yet

Enforcement
- pickTown counts existing towns vs User.maxTowns, throws
  town-limit-reached with the limit attached
- /api/towns/me surfaces that as 403 with a human-readable detail
- POST /api/town checks buildings/npcs/customPlots against per-town
  caps and (customPlots + otherTowns' totals) against User's
  maxTotalCustomPlots via jsonb_array_length; returns 403 with issues
  keyed on { path, message, requested, limit }
- realtime-token polls Centrifugo presence_stats on the positions
  channel; refuses non-owner tokens with 429 when numUsers >=
  maxActiveGuests + 1 (owner slot reserved). Fails open if Centrifugo
  is unreachable

CLI
- shared/scaffold.ts postJson now prefers server `detail` for the
  thrown error message so `town new` shows the town-limit hint verbatim
- deploy.ts already renders `path`/`message` on issues + top-level
  detail — no CLI change needed there

Not built yet: grant flow (purchases, milestones, level-ups), UI to
show current caps or capacity, backfill of EntitlementGrant for
existing rows (defaults are the truth for existing entities).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@harshithmullapudi
harshithmullapudi merged commit 81f1a7a into main Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant