Public: anyone can read this; the crew can change it.

An admin makes gift codes in the forge: a code gives a plan for free, with or without a payment provider #11166

opened this in answer to

Check · Review · Land · Live — Its check is running. Next: reviewer, no review yet.

Ready to land

Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on `/forges/new`. The new tests (`test/gift-codes.test.ts`), the neighbouring suites, `bun x tsc --noEmit`, `bun scripts/gate.ts`, `bun scripts/design-lint.ts` and `bun test test/mcp-size.test.ts` all pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn'…

22 files · +886 −15

working checking now deploy 15a672a

Check running · 3 min · 555 of 2296 files · 3318 passed, 0 failedCheck of 15a672achecked against main at 8011647fast tier: running · full gate runs on land

Website spec: 19 findings (report only)
opened this

Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on /forges/new. The new tests (test/gift-codes.test.ts), the neighbouring suites, bun x tsc --noEmit, bun scripts/gate.ts, bun scripts/design-lint.ts and bun test test/mcp-size.test.ts all pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn't call the keep_plan tool, so this issue has no plan kept.

What changed

  • Codes: a code looks like forge-7kq4-m2xp, and only its SHA-256 is stored. The plain code and its …/?code=<code> link appear once, in the answer that makes it.
  • Billing page: the Codes section is above Plans. It has a make form (plan, uses, note, expiry), the one-time code and link with copy buttons, and one line per code showing plan, note, used of limit, who redeemed it, and Revoke. A test checks that ten codes render as ten one-line rows; I didn't measure the first view in a browser.
  • Redeeming: /?code= redirects to /forges/new?code=. That page is prefilled and says "A gift from alice: a medium forge, free." A wrong, used-up, expired or revoked code is said beside the field, and the form stays. POST /api/v1/forges and the MCP spawn accept code too.
  • What redeeming does: the forge is made on the code's plan with no checkout. This works for strangers and for signed-in non-admins, who were previously refused paid plans. The entitlement source is code:<id>.
  • Spending a use: the use is claimed in one statement just before the forge is made. It goes back if the forge isn't made, so two visitors can't share the last use.
  • Rate limit: each client gets 10 code attempts per 10 minutes, stored in the database; past that the API answers 429.
  • API and MCP: GET/POST /api/v1/codes (dryRun is true unless false) and DELETE /api/v1/codes/{id}. The MCP forges tool gained codes, code and revoke instead of a new tool. test/mcp-size.test.ts passes and no ceiling moved.
  • Audit: every make, redeem and revoke is a billing.code.* event, visible to admins only.
  • Migration, docs and tests: one additive migration with its pin. The how-to is in docs/features/billing.md.
  • Spawn change: spawnForge takes a gift flag that skips the admin-only paid-plan check; it is set only after a code has been claimed.

What I left out or decided

  • #11153 (home form), #11138 (/pricing) and the Stripe provider aren't on main. The code field and the gift line are on /forges/new instead, and /?code= redirects there. The /pricing and home-form wiring is still to do once those exist.
  • Because no provider exists, the "none and stripe both redeem" test can't be written literally. The test shows a redemption makes no outbound call and writes the entitlement with provider none.
  • A code can't give the free plan, since that gives nothing.
  • I added no terminal screen for codes and no /agents form field.

Try it Open /settings/billing as an admin and press Make a code. Then open the link signed out. Or run POST /api/v1/codes {"plan":"medium","dryRun":false}.

Closes #11157

commented

Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on /forges/new. The new tests (test/gift-codes.test.ts), the neighbouring suites, bun x tsc --noEmit, bun scripts/gate.ts, bun scripts/design-lint.ts and bun test test/mcp-size.test.ts all pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn't call the keep_plan tool, so this issue has no plan kept.

What changed

  • Codes: a code looks like forge-7kq4-m2xp, and only its SHA-256 is stored. The plain code and its …/?code=<code> link appear once, in the answer that makes it.
  • Billing page: the Codes section is above Plans. It has a make form (plan, uses, note, expiry), the one-time code and link with copy buttons, and one line per code showing plan, note, used of limit, who redeemed it, and Revoke. A test checks that ten codes render as ten one-line rows; I didn't measure the first view in a browser.
  • Redeeming: /?code= redirects to /forges/new?code=. That page is prefilled and says "A gift from alice: a medium forge, free." A wrong, used-up, expired or revoked code is said beside the field, and the form stays. POST /api/v1/forges and the MCP spawn accept code too.
  • What redeeming does: the forge is made on the code's plan with no checkout. This works for strangers and for signed-in non-admins, who were previously refused paid plans. The entitlement source is code:<id>.
  • Spending a use: the use is claimed in one statement just before the forge is made. It goes back if the forge isn't made, so two visitors can't share the last use.
  • Rate limit: each client gets 10 code attempts per 10 minutes, stored in the database; past that the API answers 429.
  • API and MCP: GET/POST /api/v1/codes (dryRun is true unless false) and DELETE /api/v1/codes/{id}. The MCP forges tool gained codes, code and revoke instead of a new tool. test/mcp-size.test.ts passes and no ceiling moved.
  • Audit: every make, redeem and revoke is a billing.code.* event, visible to admins only.
  • Migration, docs and tests: one additive migration with its pin. The how-to is in docs/features/billing.md.
  • Spawn change: spawnForge takes a gift flag that skips the admin-only paid-plan check; it is set only after a code has been claimed.

What I left out or decided

  • #11153 (home form), #11138 (/pricing) and the Stripe provider aren't on main. The code field and the gift line are on /forges/new instead, and /?code= redirects there. The /pricing and home-form wiring is still to do once those exist.
  • Because no provider exists, the "none and stripe both redeem" test can't be written literally. The test shows a redemption makes no outbound call and writes the entitlement with provider none.
  • A code can't give the free plan, since that gives nothing.
  • I added no terminal screen for codes and no /agents form field.

Try it Open /settings/billing as an admin and press Make a code. Then open the link signed out. Or run POST /api/v1/codes {"plan":"medium","dryRun":false}.

commented

Gift codes: an admin can now make, list and revoke them. A code gives a plan for free, with or without a payment provider. This push fixes the three failing checks.

  • Session phase: GET /api/v1/codes now records a session phase like the other timed GET routes. That clears the route-timing test, which had flagged it as answering 200 without one.
  • Tag: /api/v1/codes now belongs to the billing tag. Before, it produced a codes tag that had no description line.
  • Unused function: I removed claimGift from src/actions/codes.ts. Nothing called it, because the door calls claimCode directly, and the hollow-work audit flagged it. I also dropped the now-unused claimCode import there.

I did not re-run the three failing tests after the final import edit. After the first fix I re-ran them together with the gift-codes tests and all 48 passed. After the import edit, tsc, bun scripts/gate.ts and the gift-codes tests (12) were clean. The forge's full check runs on this push.

To try it: sign in as an admin, open /settings/billing, choose Make a code, then open the /?code= link signed out.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs