Account and paywall
Onboarding, sign-in, entitlements and account deletion — the surface where two backends meet.
| Route | What it is |
|---|---|
(onboarding)/onboarding | First run |
paywall | RevenueCat's paywall |
customer-center | Subscription management |
(settings)/(profile)/* | Account, filter defaults |
legal/[document] | The legal documents |
Two backends meet here
Match data comes from the API. Accounts do not: Convex holds the profile table and Better Auth the session, so signing in does not touch the stats service at all.
convex/schema.ts is one table — profiles, indexed by token identifier and by
email. That is the whole account model; everything else about a person is their
entitlement, which RevenueCat owns.
Entitlements
src/lib/core/paid-access.tsx, paid-access-model.ts and
feature-access-model.ts — what is unlocked, derived from RevenueCat's customer
info. Both models have tests beside them, because an entitlement bug either
gives away the product or locks out someone who paid.
revenuecat-key.ts picks the platform's API key, and is also tested — a wrong
key is an empty offerings list, which looks identical to a network failure.
The paywall is a route
Like everything else. purchases-ui.ts presents RevenueCat's own paywall, so
the design lives in their dashboard rather than in this repo — which is what
makes changing a price or a trial a non-deploy.
Account deletion
account-deletion.test.ts asserts the order: the server delete happens
before the device is cleared. Clearing first and failing the server call leaves
an account nobody can reach and Apple's reviewers can find — see
App Store.