Database schema
Every table the kit creates, and what's stored in it.
Defined in src/db/schema.ts. Deleting a user deletes all their rows in every table below.
Auth tables (Better Auth)
| Table | Holds |
|---|---|
user | Name, email, whether the email is confirmed, image, role (user or admin), ban status and reason |
session | Signed-in sessions: token, expiry, IP address and browser |
account | How each user signs in: a password (credential), Google or GitHub. One user can have several |
verification | Email confirmation and password reset tokens |
rate_limit | Rate limit counters, shared by all server instances |
Better Auth expects these exact field names. Add columns if you need to; don't rename existing ones.
Billing tables
| Table | Holds |
|---|---|
billing_customer | Links a user to their Dodo customer ID. Created at their first checkout. provider is dodo |
subscription | One row per subscription: product, status, next billing date, cancel-at-period-end, price, interval, and the timestamp of the last event applied (provider_updated_at) |
payment | The ledger of every successful charge: amount and currency charged, settlement amount and currency (what reached your balance), kind (one_time or subscription), status (paid or refunded) |
All amounts are integers in the currency's smallest unit.
Billing tables are written only by webhooks (and billing_customer by checkout). Don't edit them by hand on a live site, except to clear test data before launch.
Repository delivery
| Table | Holds |
|---|---|
repo_access | The GitHub username invited for each user, and when |
Useful queries
Run these in the Neon console's SQL Editor.
-- Everyone who has paid, newest first
select u.email, p.amount, p.currency, p.kind, p.status, p.created_at
from payment p join "user" u on u.id = p.user_id
order by p.created_at desc;
-- Active subscriptions
select u.email, s.product_id, s.current_period_end, s.cancel_at_period_end
from subscription s join "user" u on u.id = s.user_id
where s.status = 'active';
-- Admins
select email from "user" where role = 'admin';