Skip to content

0.23.0: credit codes, invites and ?ref= links - #326

Merged
ralyodio merged 1 commit into
masterfrom
feat/credit-codes-invites
Oct 26, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/credit-codes-invites

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Credit codes and invites on agenticjobs.work, from the house packages @profullstack/redeem-credits@^0.2.0 and @profullstack/affiliates@^0.2.0 over the board's Postgres (postgresStore).

What a code grants

AJ-XXXX-XXXX-XXXX-XXXX codes grant credit in US cents (usd_cents). They are stored only as a sha256 hash. You can redeem one:

  • on /me, in the new Credit card ("Have a code?"),
  • with POST /api/v1/credits/redeem {code},
  • with agenticjobs redeem <code>,
  • with the MCP tool redeem_credit_code.

The balance and its history are at GET /api/v1/credits, agenticjobs credits and the MCP tool credits.

Spending: the board charges no listing fee and no commission (/post-a-job). "$0.25 per task" is an example pay line an employer writes. It is not a board price. Invoices settle on CoinPay straight to the payee's wallet. So no payment path exists for credit to pay through. Credit is held on the account, and the card says so. What credit should buy is a decision for Anthony.

Minting (operator):

agenticjobs credits mint --cents 500 --label "for Ada" [--max 1] [--expires-days 90]   # against DATABASE_URL
agenticjobs credits list | revoke <id>

An admin with a browser session can also call POST /api/v1/admin/credit-codes. A device token cannot.

Invites

  • /invites gives each account 3 single-use invites. Each one is good for 30 days and is shown once as /i/<code>. The page also has an open ?ref= link.

  • /i/<code> stores the code in a cookie and points to /signup?invite=. It is open past the crawl gateway (openPaths), so link previews don't hit a 402. Visiting it uses nothing up.

  • The invite and the ref ride on the magic link (new magic_links.invite_code/ref_code). The invite still counts when the link is opened in another browser. It applies only when spending that link creates a new account, which means the address is confirmed.

  • Bonus: both sides get INVITE_BONUS_CENTS (default 100; 0 turns it off). There is no bonus when:

    • both addresses are the same mailbox (case, +tag, Gmail dots),
    • the inviter's account is younger than INVITE_MIN_INVITER_AGE_HOURS (default 24),
    • the inviter has already had 10 bonuses in 30 days.

    Each case is recorded in invite_bonuses. The row is claimed before the grant, so a retry never pays twice.

  • ?ref= is first-touch. It is stored in the referral_code cookie (the @profullstack/referrals name, so nothing double counts if that package is added later) and recorded in aff_attributions at sign-up. The board has no referrals program today.

  • API: GET/POST /api/v1/invites. CLI: agenticjobs invites [create --note] and agenticjobs signup --invite <code>. MCP: credits {invites|createInvite}.

  • Links are built from PUBLIC_URL, or from the request host if that is still localhost.

Migration

0025_credits_and_invites.sql runs at boot, as all migrations do. It adds the credit_* tables, two magic_links columns and invite_bonuses. The aff_* tables are created by the package on first use.

Tests

test/credits-invites.test.ts covers:

  • redeem once, already_redeemed / used_up / invalid
  • an invite accepted from another browser pays both sides
  • no bonus for a new inviter, an existing member or the same mailbox
  • the quota of 3 and the 409 after it
  • first-touch ?ref=
  • admin-only minting

The full suite passes 1018/1018 on a fresh Postgres 17, run 3 times. api.test "every documented GET path resolves" raced features.test, which hides and deletes agents. It now re-reads the directory once before failing.

🤖 Generated with Claude Code

A code (AJ-XXXX-XXXX-XXXX-XXXX, stored only as a hash) grants credit in US
cents, redeemed on /me, over the API, the CLI or MCP
(@profullstack/redeem-credits). Every account gets three single-use /i/<code>
invites at /invites plus one open ?ref= link (@profullstack/affiliates).

- The invite and ref ride on the magic link, so a link opened in another
  browser still counts, and they apply only when that link makes a new account
  (the address is confirmed by construction).
- An accepted invite pays both sides INVITE_BONUS_CENTS (default 100) unless the
  two addresses are one mailbox, the inviter's account is younger than
  INVITE_MIN_INVITER_AGE_HOURS (default 24), or the inviter has had ten bonuses
  in 30 days. invite_bonuses claims the row before the grant, so a retry never
  pays twice.
- /i/ is open past the crawl gateway; links are built from PUBLIC_URL, or the
  request host when that is still localhost.
- Operator: agenticjobs credits mint|list|revoke against DATABASE_URL; admin
  POST /api/v1/admin/credit-codes from a browser session.
- The board charges no listing fee or commission, so nothing spends credit yet.
- api.test: retry an agent path once when a parallel test hid the agent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​profullstack/​affiliates@​0.2.07610010090100
Added@​profullstack/​redeem-credits@​0.2.07610010090100
Updated@​profullstack/​footer@​0.3.0 ⏵ 0.3.178 +2100100 +195 +1100

View full report

@ralyodio
ralyodio merged commit 8de51a0 into master Oct 26, 2026
4 checks passed
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