All guides
Database
Cloudflare D1 schema, migrations, the repository layer and the in memory test double.
Updated 2026-10-21
Why D1
D1 is SQLite at the edge. It removes a separate database vendor, it is fast enough for the workloads a starter kit targets, and it keeps the whole stack inside one Cloudflare account.
Tables
The schema is deliberately small and explicit.
- users: accounts, credentials, OAuth metadata and account preferences.
- oauth_provider_linkages: the link between a provider account and a user.
- auth_sessions: rotating, revocable session records.
- password_reset_tokens and email_verification_tokens: single use tokens.
- subscriptions: the Dodo Payments subscription bound to an account.
- billing_webhook_events: the idempotency ledger for webhook deliveries.
- rate_limit_buckets: the durable counters behind the authentication limits.
- oauth_handoff_tokens: the single use tokens that carry a provider sign in over to a session.
The repository layer
Every read and write goes through a repository interface. The production implementation talks to D1 and the test suite uses an in memory double, so the domain logic never changes when the storage engine does.
export const resolveAuthSessionRecordRepository = () =>
resolveD1Repositories()?.authSessionRepository ??
inMemoryAuthSessionRecordRepository;Migrations
Migrations are plain SQL files under migrations/. They are applied with the Wrangler CLI, so the same file runs locally and in production.
bun run db:migrate:local
bun run db:migrate:remote