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
Primary key. User identifier.
User’s display name
Unique email address
Email verification status
Profile image URL (nullable)
Account creation timestamp
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
Primary key. Session identifier.
Session expiration time
Unique session token (stored in cookies)
Session creation timestamp
Last activity timestamp
Client IP address (nullable)
Client user agent string (nullable)
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
Primary key. Account identifier.
Provider’s account identifier
OAuth provider name (e.g., ‘google’, ‘github’)
Foreign key to
user.id (cascades on delete)OAuth access token (nullable, encrypted recommended)
OAuth refresh token (nullable, encrypted recommended)
OAuth ID token (nullable)
Access token expiration (nullable)
Refresh token expiration (nullable)
OAuth scopes granted (nullable)
Hashed password for email/password auth (nullable)
Account link timestamp
Last update timestamp
- Index on
userId
user→ Oneuserrecord
verification
Stores email verification tokens and OTP codes. Location:src/database/schema.ts:60-74
Primary key. Verification identifier.
Email address or user identifier
Verification token or OTP code
Token/OTP expiration time
Creation timestamp
Update timestamp
- Index on
identifier
Payment Tables
customer
Stores payment provider customer records. Location:src/database/schema.ts:77-97
Primary key. Internal customer identifier.
Foreign key to
user.id (cascades on delete)Payment provider:
stripe, polar, or lemonsqueezyCustomer ID from payment provider (e.g.,
cus_xxx for Stripe)Customer email at provider (nullable)
Record creation 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
Primary key. Internal subscription identifier.
Foreign key to
user.id (cascades on delete)Foreign key to
customer.id (sets null on delete)Payment provider:
stripe, polar, or lemonsqueezySubscription ID from payment provider (e.g.,
sub_xxx for Stripe)Subscription status:
active- Active subscriptioncanceled- Canceledpast_due- Payment failedtrialing- In trial periodincomplete- Incomplete paymentpaused- Paused subscription
Plan name:
free, starter, pro, or enterpriseBilling interval:
month, year, or null for one-timeSubscription price amount (nullable)
Currency code (e.g.,
usd, eur)Current billing period start (nullable)
Current billing period end (nullable)
Whether subscription cancels at period end
Cancellation timestamp (nullable)
Trial period start (nullable)
Trial period end (nullable)
Subscription creation 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
Primary key. Internal payment identifier.
Foreign key to
user.id (cascades on delete)Foreign key to
customer.id (sets null on delete)Foreign key to
subscription.id (sets null on delete)Payment provider:
stripe, polar, or lemonsqueezyPayment ID from provider (e.g.,
pi_xxx for Stripe)Payment type:
subscription- Recurring subscription paymentone_time- One-time purchaserefund- Refund transaction
Payment status:
succeeded- Payment successfulpending- Payment processingfailed- Payment failedcanceled- Payment canceledrefunded- Payment refunded
Payment amount
Currency code (e.g.,
usd, eur)Payment description (nullable)
Payment 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
Primary key. Purchase identifier.
Unique Stripe Checkout session ID
Customer email from Stripe (nullable)
GitHub email for repo access (nullable)
GitHub username for repo access (nullable)
Twitter handle for attribution (nullable)
Purchase amount (nullable)
Currency code (nullable)
Purchase 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