0ae59f3550
Introduces RECAP_MODE=multi alongside single-mode self-host: - Tenant auth + accounts (magic-link via System SMTP), per-tenant credit pool, anonymous trial minting with per-IP/-64 caps - Self-serve Pro/Max purchase: inline Lightning (BTCPay) + card (Zaprite), prepaid 30-day periods, expiry-reminder emails - Core-decoupling: relay owns cloud tier/expiry keyed by Recaps user-id - SQLite (better-sqlite3) schema for multi-mode; filesystem unchanged for single - StartOS actions/versions through 0.2.155
14 lines
2.1 KiB
TypeScript
14 lines
2.1 KiB
TypeScript
import { VersionInfo } from '@start9labs/start-sdk'
|
|
|
|
export const v_0_2_133 = VersionInfo.of({
|
|
version: '0.2.133:0',
|
|
releaseNotes: {
|
|
en_US:
|
|
"Anonymous-trial UX fix. Before: an anonymous visitor on a multi-tenant Recap whose server-side trial allowance had been spent (whether by depleted cookie credits OR by hitting the operator's per-IP cookie-mint cap) would still see 'N free credits ready' in the toolbar — the pill came from the static operator config rather than a real eligibility check. They'd paste a URL, the player + 'Processing…' status would render optimistically, and only AFTER the request hit the server would a generic 'Processing failed — Try again' banner appear (with the player still showing). Three changes. (1) /api/account/whoami now actually checks whether the visitor's server-side identifier (matched on the implementation side) can issue a fresh trial cookie; when the answer is no, returns available_trial_credits: 0 so the toolbar pill flips to a clickable 'Out of free credits' chip + 'Buy credits' button. (2) processUrl() pre-flight gate refuses to start the optimistic flow when the visitor has 0 credits to spend — applies to BOTH anonymous-and-blocked and trial-cookie-with-zero-balance — no player render, no 'Processing…' status, just a clean modal with Sign up / Buy credits / Sign in CTAs. (3) Race fallback: if the trial budget is exhausted BETWEEN the whoami poll and the submit (parallel tabs, etc.), the server's trial_unavailable / trial_exhausted response is now caught explicitly — optimistic state cleared, account state refreshed, same modal shown. The modal copy is deliberately generic ('Out of free credits — sign up to keep going or buy credits a la carte') and doesn't telegraph what specifically is blocking the visitor, so a curious user can't trivially infer a bypass from the error wording. Signing up (fresh account, balance carries over) and buying credits a la carte (no signup, attaches to current browser) are the two paths past the block.",
|
|
},
|
|
migrations: {
|
|
up: async ({ effects }) => {},
|
|
down: async ({ effects }) => {},
|
|
},
|
|
})
|