feat: Align Basic/Build plans and add testnet faucet API#811
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aligns subscription plan handling around new Basic/Build Stripe product IDs (keeping the legacy Test/Explorer ID as a temporary fallback), and introduces an authenticated POST /account/faucet endpoint for Studio users to request testnet funds up to a configured cap. It also updates operational docs/scripts and adds unit coverage for plan capability mapping.
Changes:
- Introduce centralized plan capability mapping (Basic vs Build) and apply it to default plan assignment + Logto role assignment.
- Add authenticated
POST /account/faucetwith cap/balance/request-more response details and reuse the same cap for automatic top-ups. - Update Stripe migration docs/scripts/env examples for Basic/Build plan IDs and the new faucet cap configuration; add unit tests.
Reviewed changes
Copilot reviewed 17 out of 19 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/admin/plan-capabilities.test.ts | Adds unit tests for Basic plan ID fallback + capability checks. |
| src/types/environment.d.ts | Updates env typings for new faucet + Basic plan configuration variables. |
| src/types/constants.ts | Adds numeric env parsing and introduces faucet cap constants. |
| src/services/track/admin/account-submitter.ts | Assigns Basic as the default plan (via getBasicPlanId) when creating Stripe customers. |
| src/services/admin/plan-capabilities.ts | New plan capability mapping helpers (Basic vs Build). |
| src/middleware/auth/routes/api/account-auth.ts | Registers auth scope for POST /account/faucet. |
| src/middleware/auth/logto-helper.ts | Uses plan capabilities to decide which Logto roles to assign based on Stripe product. |
| src/helpers/faucet.ts | Allows callers to override faucet amount per request. |
| src/controllers/api/account.ts | Adds POST /account/faucet, updates auto-top-up logic to use upper cap, and loosens Logto role assignment success handling. |
| src/app.ts | Wires the new /account/faucet route and validator. |
| scripts/README.md | Updates migration docs to reference Basic plan terminology/IDs. |
| scripts/README-SUBSCRIPTION-MIGRATION.md | Updates references from Explorer to Basic plan. |
| scripts/README-SUBSCRIPTION-ACTIVATION.md | Updates semantics to migrate active/trialing without ending trials; refreshes Basic references. |
| scripts/MIGRATION-EXPLORER-PLAN.md | Renames guide content to Basic plan but retains filename. |
| scripts/find-subscriptions-to-activate.sql | Expands query to include active subscriptions for migration. |
| scripts/activate-subscriptions.sh | Updates migration behavior for active/trialing subscriptions (no trial_end=now, no prorations). |
| README.md | Documents new faucet cap config and new POST /account/faucet; adds Basic plan ID env var guidance. |
| package-lock.json | Bumps package version and updates lockfile metadata. |
| example.env | Adds Basic plan env var and new faucet cap variable; updates defaults. |
Comments suppressed due to low confidence (1)
src/controllers/api/account.ts:837
cheqToNcheq/ncheqToCheq(and theNumber(...bigint)conversions passed intoFaucetHelper.delegateTokens) can lose precision or overflow once amounts exceedNumber.MAX_SAFE_INTEGER(e.g., ifTESTNET_FAUCET_UPPER_CAP_CHEQis misconfigured very high). To keep this exact, consider keeping amounts asbigint/decimal strings end-to-end and only formatting for display, rather than converting bigints tonumber.
function cheqToNcheq(amountCheq: number): bigint {
return BigInt(Math.floor(amountCheq * 10 ** DEFAULT_DENOM_EXPONENT));
}
function ncheqToCheq(amountNcheq: bigint): number {
return Number(amountNcheq) / 10 ** DEFAULT_DENOM_EXPONENT;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Addressed the Copilot review threads in 75392d1:
Verification:
|
## [3.17.0-develop.2](3.17.0-develop.1...3.17.0-develop.2) (2026-05-19) ### Features * Align Basic/Build plans and add testnet faucet API ([#811](#811)) ([7b00c1f](7b00c1f))
|
🎉 This PR is included in version 3.17.0-develop.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
POST /account/faucetaccess for Studio users with cap, balance, and request-more response detailsVerification
npm run build:appnpm run test:unit -- tests/unit/admin/plan-capabilities.test.ts --runInBandNotes
STRIPE_BASIC_PLAN_IDandSTRIPE_BUILD_PLAN_ID;STRIPE_TEST_PLAN_IDremains a temporary fallback only.