Database Models
This application uses MongoDB with Mongoose for data modeling. We have designed the core models to be generic, extensible, and standards-compliant, avoiding unnecessary complexity while ensuring all essential fields for a modern SaaS application are present.
User Model
The User model is designed to be a flexible foundation for user identity. It includes standard fields for authentication and profile management, without tying the system to a specific auth provider's implementation details more than necessary.
File: src/lib/db/models/user.ts
Fields
| Field | Type | Description |
|---|---|---|
name |
String |
The user's display name. |
email |
String |
Required, Unique. The user's email address. Used as the primary identifier. |
emailVerified |
Date |
Timestamp of when the email was verified. If null, the email is unverified. |
image |
String |
URL to the user's profile picture. |
role |
String |
Authorization role. Defaults to 'user'. Can be set to 'admin'. |
createdAt |
Date |
Auto-managed. Timestamp of record creation. |
updatedAt |
Date |
Auto-managed. Timestamp of last update. |
Design Decisions
- Generic Auth Fields: We use standard fields (
name,email,image) that map easily to most OAuth providers (Google, GitHub, etc.). - Role-Based Access: A simple
rolefield is included to handle basic permissions (User vs Admin) without needing a complex separate permission system initially. - Verification: The
emailVerifiedfield is crucial for security flows (e.g., preventing password resets on unverified accounts).
Subscription Model
The Subscription model is built to handle recurring billing and access control. While currently integrated with Polar.sh, the schema is designed to be generic enough to potentially support other providers (like Stripe) with minimal changes, although specific ID fields are named for clarity.
File: src/lib/db/models/subscription.ts
Fields
| Field | Type | Description |
|---|---|---|
userId |
ObjectId |
Required. Reference to the User who owns this subscription. |
polarId |
String |
Required, Unique. The unique ID of the subscription from Polar.sh. |
polarPriceId |
String |
Required. The specific price/plan ID from Polar.sh. |
currency |
String |
The currency code (e.g., 'usd'). |
interval |
String |
Billing interval (e.g., 'month', 'year'). |
status |
String |
Required. Current status (e.g., active, canceled, past_due). |
currentPeriodStart |
Date |
Start date of the current billing cycle. |
currentPeriodEnd |
Date |
End date of the current billing cycle. Access checks often compare against this. |
cancelAtPeriodEnd |
Boolean |
If true, the subscription will not renew but remains active until the period ends. |
startedAt |
Date |
When the subscription first started. |
endedAt |
Date |
When the subscription was fully terminated. |
Design Decisions
- Polar.sh Integration: We explicitly name fields
polarIdandpolarPriceIdto avoid ambiguity. This makes it clear which external system owns these identifiers. - Standard Statuses: We use industry-standard subscription statuses (
active,canceled,past_due,incomplete, etc.) to ensure the application logic can handle common billing scenarios (grace periods, payment failures) correctly. - Minimalism: We only store what is necessary for access control and display. Detailed invoice line items or transaction history are fetched from the provider when needed, keeping the database light.