Skip to content

feat: credit codes + invites (pro_days onto a practice's paid plan), CLI/MCP 0.5.0 - #29

Merged
ralyodio merged 1 commit into
masterfrom
feat/credits-invites
Oct 27, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/credits-invites

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Credit codes (@profullstack/redeem-credits 0.2.0) and invites (@profullstack/affiliates 0.3.0).

What a code grants: pro_days, days of a practice's paid plan ($10/seat/mo, max $199). Redeemed on Billing by an owner or org manager, the days move org_billing.paid_through forward: the same column a CoinPay payment extends (a practice still in its trial keeps the trial; paid time starts when it ends). Days not yet applied (invite bonuses, --keep) wait in a per-user balance and are added under Billing.

  • Mint (staff only, no API): docker exec tleehealthcom-app-1 bun apps/web/scripts/mint-credit-code.js --days 30 [--max N] [--expires-days N] [--label ...], plus --list / --revoke
  • Redeem: Billing "Have a code?", POST /api/v1/credits/redeem {code, org_id?} (the practice is checked before the code is spent), POST /orgs/:org/billing/apply-credits {days}, GET /credits; CLI tleehealth redeem|credits; MCP redeem_credit_code, get_credits
  • Invites: 3 per account, /app/invites (/invites redirects), GET|POST /api/v1/invites, POST /invites/accept; CLI tleehealth invite|invites; MCP create_invite
  • /i/<code> sets th_invite and links to signup. /auth/link stores the invite on the emailed link (login_tokens.invite), so opening it on another device still counts; /auth/magic accepts it only when that link creates the account (xmax = 0). New accounts (7 days) can also accept by code.
  • Bonus: 7 pro_days each side, only after redeemInvite().ok (never pre-checking invitedBy()); no throwaway domains, no +tag/Gmail-dot alias of another account; inviter side max 3 a month; invite_bonuses has one row per invitee. Every account here is email-verified (the magic link made it).
  • /i/ is an open path in the crawl gate. No health data is read or written.

Security sweep (rules 10/11): identity comes only from the session cookie or a th_live_ key; no admin-by-email; no next= redirects; PATCH /me writes only name; org_billing is written only by the signed webhook (empty secret refuses). Nothing to fix.

Migration 0008 (login_tokens.invite, invite_bonuses) dry-run on prod in a rolled-back transaction; tables backed up. Tests: bun test 134/134 on a fresh Postgres (8 new incl. a concurrent double-accept: one wins, the other already_invited, left unused). master: 126/126.

🤖 Generated with Claude Code

…CLI/MCP 0.5.0

- @profullstack/redeem-credits 0.2.0: codes grant pro_days. "Have a code?" on
  Billing redeems straight onto the practice (owner/org manager) and moves
  org_billing.paid_through, the column a CoinPay payment extends; a trial's
  remaining days are kept. Unapplied days wait in a balance.
  API: GET /credits, POST /credits/redeem, POST /orgs/:org/billing/apply-credits.
  Minting is staff-only: apps/web/scripts/mint-credit-code.js.
- @profullstack/affiliates 0.3.0: 3 invites per account (/app/invites,
  /invites, GET|POST /invites). /i/<code> sets th_invite and links to signup;
  /auth/link stores the invite on the emailed link (another device counts) and
  /auth/magic accepts it only when that link creates the account. New accounts
  (7 days) can also accept by code (POST /invites/accept). 7 pro_days each
  side, paid only when redeemInvite() succeeds; no throwaway domains, no
  +tag/Gmail-dot alias of another account; inviter side capped at 3 a month;
  invite_bonuses has one row per invitee. /i/ is outside the crawl gate.
- CLI: tleehealth redeem | credits [--apply] | invite | invites.
  MCP: redeem_credit_code, get_credits, create_invite. 0.5.0.
- Migration 0008: login_tokens.invite, invite_bonuses. No health data touched.

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/​redeem-credits@​0.2.07610010090100
Added@​profullstack/​affiliates@​0.3.07610010092100
Addeddisposable-email-domains@​1.0.621001009382100

View full report

@ralyodio
ralyodio merged commit d1c65fa into master Oct 27, 2026
3 checks passed
@ralyodio
ralyodio deleted the feat/credits-invites branch October 27, 2026 03:09
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