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:
2025-10-12 22:14:22 +00:00
parent be22b5b4fd
commit c3cd353f2f
16 changed files with 3771 additions and 699 deletions

View File

@@ -38,7 +38,8 @@
"description": "Biblical Guide este o aplicație de studiu biblic online. Citește Scriptura, pune întrebări cu ajutorul chatului AI, caută versete rapid și alătură-te unei comunități de rugăciune care te sprijină zilnic.",
"cta": {
"readBible": "Începe să citești",
"askAI": "Încearcă acum gratuit - Chat AI"
"askAI": "Încearcă acum gratuit - Chat AI",
"supportMission": "Susține Misiunea"
},
"liveCounter": "Alătură-te miilor de credincioși care folosesc Biblical Guide pentru a înțelege și aplica Cuvântul lui Dumnezeu în viața de zi cu zi"
},
@@ -577,5 +578,211 @@
"updateReady": "Actualizare pregătită",
"offline": "Ești offline",
"onlineAgain": "Ești din nou online!"
},
"donate": {
"hero": {
"title": "Biblical Guide",
"subtitle": "Every Scripture. Every Language. Forever Free.",
"cta": {
"readBible": "Read the Bible",
"supportMission": "Support the Mission"
}
},
"mission": {
"title": "The Word Should Never Have a Price Tag",
"description1": "Most Bible apps today hide the Word of God behind ads, upgrades, or premium study tools.",
"different": "Biblical Guide is different.",
"description2": "No subscriptions. No tracking. No paywalls.",
"description3": "Just Scripture — in every language, for every believer — free forever."
},
"pitch": {
"title": "Your Gift Keeps the Gospel Free",
"description1": "Every donation directly supports the servers, translations, and technology that make Biblical Guide possible.",
"description2": "When you give, you are not paying for access — you are keeping access open for millions who cannot afford to pay.",
"verse": {
"text": "Freely you have received; freely give.",
"reference": "— Matthew 10:8"
}
},
"features": {
"title": "What Your Support Sustains",
"subtitle": "Your donation keeps every verse, every prayer, every word — free to all.",
"globalLibrary": {
"title": "A Global Bible Library",
"description": "1,200+ versions, from ancient Hebrew to modern translations"
},
"multilingual": {
"title": "Multilingual Access",
"description": "7 languages today, 40+ tomorrow"
},
"prayerWall": {
"title": "A Prayer Wall Without Borders",
"description": "Believers praying for one another in real time"
},
"aiChat": {
"title": "AI Bible Chat",
"description": "Answers grounded in Scripture, not opinion"
},
"privacy": {
"title": "Complete Privacy",
"description": "No ads, no tracking, no data sale — ever"
},
"offline": {
"title": "Offline Access",
"description": "Because the Word should reach even where the internet cannot"
}
},
"form": {
"title": "How You Can Support",
"makedonation": "Make a Donation",
"success": "Thank you for your donation!",
"errors": {
"invalidAmount": "Please enter a valid amount (minimum $1)",
"invalidEmail": "Please enter a valid email address",
"checkoutFailed": "Failed to create checkout session",
"generic": "An error occurred. Please try again."
},
"recurring": {
"label": "Make this a recurring donation",
"monthly": "Monthly",
"yearly": "Yearly"
},
"amount": {
"label": "Select Amount (USD)",
"custom": "Custom Amount"
},
"info": {
"title": "Your Information",
"email": "Email Address",
"name": "Name (optional)",
"anonymous": "Make this donation anonymous",
"message": "Message (optional)",
"messagePlaceholder": "Share why you're supporting Biblical Guide..."
},
"submit": "Donate",
"secure": "Secure payment powered by Stripe"
},
"alternatives": {
"title": "Or donate with",
"paypal": "Donate via PayPal",
"kickstarter": "Support us on Kickstarter (coming soon)"
},
"impact": {
"title": "Your Impact",
"description": "Every donation directly supports the servers, translations, and technology that make Biblical Guide possible."
},
"why": {
"title": "Why Donate?",
"description1": "Biblical Guide is committed to keeping God's Word free and accessible to all. We don't have ads, paywalls, or sell your data.",
"description2": "When you give, you're not paying for access — you're keeping access open for millions who cannot afford to pay."
},
"matters": {
"title": "Why It Matters",
"point1": "Each day, someone opens a Bible app and hits a paywall.",
"point2": "Each day, a believer loses connection and can't read the Word offline.",
"point3": "Each day, the Gospel becomes harder to reach for someone who needs it most.",
"together": "Together, we can change that.",
"conclusion": "Your donation ensures that God's Word remains freely accessible — without cost, without barriers, without end."
},
"join": {
"title": "Join the Mission",
"description1": "Biblical Guide is built by one believer, sustained by many.",
"description2": "No corporations. No investors. Just faith, code, and community.",
"callToAction": "If this mission speaks to you — help keep the Bible free forever.",
"closing": "Every verse you read today stays free tomorrow."
},
"footer": {
"tagline": "Every Scripture. Every Language. Forever Free.",
"links": {
"readBible": "Read Bible",
"prayerWall": "Prayer Wall",
"aiChat": "AI Chat",
"contact": "Contact"
}
}
},
"subscription": {
"title": "Planuri de Abonament",
"subtitle": "Alege planul potrivit pentru tine",
"currentPlan": "Plan Curent",
"upgradePlan": "Actualizează Planul",
"managePlan": "Gestionează Abonamentul",
"billingPortal": "Portal Facturare",
"free": {
"name": "Gratuit",
"price": "$0",
"period": "pentru totdeauna",
"description": "Perfect pentru studiul biblic ocazional",
"features": {
"conversations": "10 conversații AI pe lună",
"bible": "Acces complet la Biblie",
"prayer": "Acces la zidul rugăciunilor",
"bookmarks": "Semne de carte și evidențieri"
},
"cta": "Plan Curent"
},
"premium": {
"name": "Premium",
"priceMonthly": "$10",
"priceYearly": "$100",
"periodMonthly": "pe lună",
"periodYearly": "pe an",
"savings": "Economisește 17% cu planul anual",
"description": "Creștere spirituală nelimitată",
"features": {
"conversations": "Conversații AI nelimitate",
"bible": "Acces complet la Biblie",
"prayer": "Acces la zidul rugăciunilor",
"bookmarks": "Semne de carte și evidențieri",
"support": "Suport prioritar",
"early": "Acces anticipat la funcții noi"
},
"cta": "Actualizează la Premium",
"ctaProcessing": "Se procesează..."
},
"billing": {
"monthly": "Lunar",
"yearly": "Anual"
},
"usage": {
"title": "Utilizarea Ta",
"conversations": "Conversații",
"used": "folosite",
"of": "din",
"unlimited": "Nelimitate",
"remaining": "rămase",
"resetsOn": "Se resetează pe",
"resetDate": "{{date}}"
},
"limitReached": {
"title": "Limita de Conversații Atinsă",
"message": "Ai folosit toate cele {{limit}} conversații pentru luna aceasta.",
"upgradeMessage": "Actualizează la Premium pentru conversații nelimitate și susține-ți călătoria spirituală.",
"cta": "Actualizează la Premium",
"resetInfo": "Conversațiile tale gratuite se vor reseta pe {{date}}"
},
"success": {
"title": "Bine ai venit la Premium!",
"message": "Mulțumim că te-ai abonat la Biblical Guide Premium. Acum ai conversații AI nelimitate.",
"benefit1": "Conversații biblice AI nelimitate",
"benefit2": "Suport prioritar",
"benefit3": "Acces anticipat la funcții noi",
"cta": "Începe să Conversezi",
"goHome": "Mergi la Pagina Principală"
},
"errors": {
"loadFailed": "Nu s-au putut încărca informațiile despre abonament",
"checkoutFailed": "Nu s-a putut crea sesiunea de checkout",
"portalFailed": "Nu s-a putut deschide portalul de facturare",
"alreadySubscribed": "Ai deja un abonament Premium activ",
"generic": "Ceva nu a mers bine. Te rugăm să încerci din nou."
},
"status": {
"active": "Activ",
"cancelled": "Anulat",
"pastDue": "Întârziat",
"trialing": "Probă",
"expired": "Expirat"
}
}
}
}