feat: implement subscription system with conversation limits
Implement complete backend subscription system that limits free users to 10 AI conversations per month and offers Premium tier ($10/month or $100/year) with unlimited conversations. Changes: - Add User subscription fields (tier, status, limits, counters) - Create Subscription model to track Stripe subscriptions - Implement conversation limit enforcement in chat API - Add subscription checkout and customer portal APIs - Update Stripe webhook to handle subscription events - Add subscription utility functions (limit checks, tier management) - Add comprehensive subscription translations (en, ro, es, it) - Update environment variables for Stripe price IDs - Update footer "Sponsor Us" link to point to /donate - Add "Sponsor Us" button to home page hero section Database: - User model: subscriptionTier, subscriptionStatus, conversationLimit, conversationCount, limitResetDate, stripeCustomerId, stripeSubscriptionId - Subscription model: tracks Stripe subscription details, periods, status - SubscriptionStatus enum: ACTIVE, CANCELLED, PAST_DUE, TRIALING, etc. API Routes: - POST /api/subscriptions/checkout - Create Stripe checkout session - POST /api/subscriptions/portal - Get customer portal link - Webhook handlers for: customer.subscription.created/updated/deleted, invoice.payment_succeeded/failed Features: - Free tier: 10 conversations/month with automatic monthly reset - Premium tier: Unlimited conversations - Automatic limit enforcement before conversation creation - Returns LIMIT_REACHED error with upgrade URL when limit hit - Stripe Customer Portal integration for subscription management - Automatic tier upgrade/downgrade via webhooks Documentation: - SUBSCRIPTION_IMPLEMENTATION_PLAN.md - Complete implementation plan - SUBSCRIPTION_IMPLEMENTATION_STATUS.md - Current status and next steps Frontend UI still needed: subscription page, upgrade modal, usage display 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,15 @@ model User {
|
||||
updatedAt DateTime @updatedAt
|
||||
lastLoginAt DateTime?
|
||||
|
||||
// Subscription fields
|
||||
subscriptionTier String @default("free") // "free", "premium"
|
||||
subscriptionStatus String @default("active") // "active", "cancelled", "expired", "past_due"
|
||||
conversationLimit Int @default(10)
|
||||
conversationCount Int @default(0) // Reset monthly
|
||||
limitResetDate DateTime? // When to reset conversation count
|
||||
stripeCustomerId String? @unique // For subscriptions (separate from donations)
|
||||
stripeSubscriptionId String? @unique
|
||||
|
||||
sessions Session[]
|
||||
bookmarks Bookmark[]
|
||||
chapterBookmarks ChapterBookmark[]
|
||||
@@ -38,8 +47,11 @@ model User {
|
||||
updatedSocialMedia SocialMediaLink[] @relation("SocialMediaUpdater")
|
||||
updatedMailgunSettings MailgunSettings[] @relation("MailgunSettingsUpdater")
|
||||
donations Donation[]
|
||||
subscriptions Subscription[]
|
||||
|
||||
@@index([role])
|
||||
@@index([subscriptionTier])
|
||||
@@index([stripeCustomerId])
|
||||
}
|
||||
|
||||
model Session {
|
||||
@@ -455,3 +467,36 @@ enum DonationStatus {
|
||||
REFUNDED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
model Subscription {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
stripeSubscriptionId String @unique
|
||||
stripePriceId String // Stripe price ID for the plan
|
||||
stripeCustomerId String
|
||||
status SubscriptionStatus
|
||||
currentPeriodStart DateTime
|
||||
currentPeriodEnd DateTime
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
tier String // "premium"
|
||||
interval String // "month" or "year"
|
||||
metadata Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@index([stripeSubscriptionId])
|
||||
}
|
||||
|
||||
enum SubscriptionStatus {
|
||||
ACTIVE
|
||||
CANCELLED
|
||||
PAST_DUE
|
||||
TRIALING
|
||||
INCOMPLETE
|
||||
INCOMPLETE_EXPIRED
|
||||
UNPAID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user