src/database/schema.ts.
Database Connection
Fromsrc/database/index.ts:1-16:
Authentication Tables
user
Stores user account information. Location:src/database/schema.ts:4-15
text
required
Primary key. User identifier.
text
required
User’s display name
text
required
Unique email address
boolean
default:false
Email verification status
text
Profile image URL (nullable)
timestamp
default:"now()"
Account creation timestamp
timestamp
default:"now()"
Last update timestamp (auto-updated)
- Unique index on
email
sessions→ Manysessionrecordsaccounts→ Manyaccountrecordscustomers→ Manycustomerrecordssubscriptions→ Manysubscriptionrecordspayments→ Manypaymentrecords
session
Stores active user sessions managed by Better-Auth. Location:src/database/schema.ts:17-34
text
required
Primary key. Session identifier.
timestamp
required
Session expiration time
text
required
Unique session token (stored in cookies)
timestamp
default:"now()"
Session creation timestamp
timestamp
Last activity timestamp
text
Client IP address (nullable)
text
Client user agent string (nullable)
text
required
Foreign key to
user.id (cascades on delete)- Index on
userId - Unique index on
token
user→ Oneuserrecord
account
Stores OAuth provider accounts linked to users. Location:src/database/schema.ts:36-58
text
required
Primary key. Account identifier.
text
required
Provider’s account identifier
text
required
OAuth provider name (e.g., ‘google’, ‘github’)
text
required
Foreign key to
user.id (cascades on delete)text
OAuth access token (nullable, encrypted recommended)
text
OAuth refresh token (nullable, encrypted recommended)
text
OAuth ID token (nullable)
timestamp
Access token expiration (nullable)
timestamp
Refresh token expiration (nullable)
text
OAuth scopes granted (nullable)
text
Hashed password for email/password auth (nullable)
timestamp
default:"now()"
Account link timestamp
timestamp
Last update timestamp
- Index on
userId
user→ Oneuserrecord
verification
Stores email verification tokens and OTP codes. Location:src/database/schema.ts:60-74
text
required
Primary key. Verification identifier.
text
required
Email address or user identifier
text
required
Verification token or OTP code
timestamp
required
Token/OTP expiration time
timestamp
default:"now()"
Creation timestamp
timestamp
Update timestamp
- Index on
identifier
Payment Tables
customer
Stores payment provider customer records. Location:src/database/schema.ts:77-97
text
required
Primary key. Internal customer identifier.
text
required
Foreign key to
user.id (cascades on delete)text
required
Payment provider:
stripe, polar, or lemonsqueezytext
required
Customer ID from payment provider (e.g.,
cus_xxx for Stripe)text
Customer email at provider (nullable)
timestamp
default:"now()"
Record creation timestamp
timestamp
Last update timestamp
- Index on
userId - Index on
providerCustomerId
user→ Oneuserrecordsubscriptions→ Manysubscriptionrecordspayments→ Manypaymentrecords
subscription
Stores subscription records across all payment providers. Location:src/database/schema.ts:99-132
text
required
Primary key. Internal subscription identifier.
text
required
Foreign key to
user.id (cascades on delete)text
Foreign key to
customer.id (sets null on delete)text
required
Payment provider:
stripe, polar, or lemonsqueezytext
required
Subscription ID from payment provider (e.g.,
sub_xxx for Stripe)text
required
Subscription status:
active- Active subscriptioncanceled- Canceledpast_due- Payment failedtrialing- In trial periodincomplete- Incomplete paymentpaused- Paused subscription
text
required
Plan name:
free, starter, pro, or enterprisetext
Billing interval:
month, year, or null for one-timedecimal(10,2)
Subscription price amount (nullable)
text
Currency code (e.g.,
usd, eur)timestamp
Current billing period start (nullable)
timestamp
Current billing period end (nullable)
boolean
default:false
Whether subscription cancels at period end
timestamp
Cancellation timestamp (nullable)
timestamp
Trial period start (nullable)
timestamp
Trial period end (nullable)
timestamp
default:"now()"
Subscription creation timestamp
timestamp
Last update timestamp
- Index on
userId - Index on
customerId - Index on
providerSubscriptionId - Index on
status
user→ Oneuserrecordcustomer→ Onecustomerrecordpayments→ Manypaymentrecords
payment
Stores individual payment transactions. Location:src/database/schema.ts:134-164
text
required
Primary key. Internal payment identifier.
text
required
Foreign key to
user.id (cascades on delete)text
Foreign key to
customer.id (sets null on delete)text
Foreign key to
subscription.id (sets null on delete)text
required
Payment provider:
stripe, polar, or lemonsqueezytext
required
Payment ID from provider (e.g.,
pi_xxx for Stripe)text
required
Payment type:
subscription- Recurring subscription paymentone_time- One-time purchaserefund- Refund transaction
text
required
Payment status:
succeeded- Payment successfulpending- Payment processingfailed- Payment failedcanceled- Payment canceledrefunded- Payment refunded
decimal(10,2)
required
Payment amount
text
required
Currency code (e.g.,
usd, eur)text
Payment description (nullable)
timestamp
default:"now()"
Payment timestamp
timestamp
Last update timestamp
- Index on
userId - Index on
customerId - Index on
subscriptionId - Index on
providerPaymentId
user→ Oneuserrecordcustomer→ Onecustomerrecordsubscription→ Onesubscriptionrecord
premiumPurchase
Stores premium one-time purchases (Stripe Checkout sessions). Location:src/database/schema.ts:166-184
text
required
Primary key. Purchase identifier.
text
required
Unique Stripe Checkout session ID
text
Customer email from Stripe (nullable)
text
GitHub email for repo access (nullable)
text
GitHub username for repo access (nullable)
text
Twitter handle for attribution (nullable)
decimal(10,2)
Purchase amount (nullable)
text
Currency code (nullable)
timestamp
default:"now()"
Purchase timestamp
timestamp
Last update timestamp
- Unique index on
stripeSessionId
Relations Overview
Fromsrc/database/schema.ts:186-240:
Migrations
Generate and run migrations using Drizzle Kit:migrations/ directory.
Type Safety
Drizzle provides full TypeScript types for all tables:Next Steps
Query Examples
Common database query patterns
Authentication
Using auth-related tables
Payments
Working with payment tables