From 7ad2e1b9b7a0be25ca6d495c54608077df8b12de Mon Sep 17 00:00:00 2001 From: Riccardo Giorato Date: Thu, 29 Jan 2026 16:55:54 +0100 Subject: [PATCH] 3 comics per week --- app/api/check-credits/route.ts | 41 ++++--------------- app/story/[storySlug]/story-editor-client.tsx | 2 +- components/api-key-modal.tsx | 2 +- lib/rate-limit.ts | 4 +- 4 files changed, 12 insertions(+), 37 deletions(-) diff --git a/app/api/check-credits/route.ts b/app/api/check-credits/route.ts index 7c65b93..c7eb331 100644 --- a/app/api/check-credits/route.ts +++ b/app/api/check-credits/route.ts @@ -1,9 +1,6 @@ import { type NextRequest, NextResponse } from "next/server"; import { auth } from "@clerk/nextjs/server"; import { freeTierRateLimit } from "@/lib/rate-limit"; -import { db } from "@/lib/db"; -import { stories } from "@/lib/schema"; -import { gte } from "drizzle-orm"; export async function POST(request: NextRequest) { try { @@ -27,36 +24,14 @@ export async function POST(request: NextRequest) { }); } - // For free tier, check rate limit status - try { - // Try to check remaining without consuming - const limitResult = await freeTierRateLimit.getRemaining(userId); + // For free tier, check rate limit status via Redis + const limitResult = await freeTierRateLimit.getRemaining(userId); - return NextResponse.json({ - hasApiKey: false, - creditsRemaining: limitResult.remaining, - resetTime: limitResult.reset, - }); - } catch (error) { - console.error("Rate limit check error:", error); - // Fallback to database check - const sevenDaysAgo = new Date(); - sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); - - const recentStories = await db - .select() - .from(stories) - .where(gte(stories.createdAt, sevenDaysAgo)) - .limit(1); - - const hasUsedCredit = recentStories.length > 0; - - return NextResponse.json({ - hasApiKey: false, - creditsRemaining: hasUsedCredit ? 0 : 1, - resetTime: hasUsedCredit ? sevenDaysAgo.getTime() + 7 * 24 * 60 * 60 * 1000 : null, - }); - } + return NextResponse.json({ + hasApiKey: false, + creditsRemaining: limitResult.remaining, + resetTime: limitResult.reset, + }); } catch (error) { console.error("Error in check-credits API:", error); return NextResponse.json( @@ -68,4 +43,4 @@ export async function POST(request: NextRequest) { { status: 500 } ); } -} \ No newline at end of file +} diff --git a/app/story/[storySlug]/story-editor-client.tsx b/app/story/[storySlug]/story-editor-client.tsx index ca8fac5..aeb3d62 100644 --- a/app/story/[storySlug]/story-editor-client.tsx +++ b/app/story/[storySlug]/story-editor-client.tsx @@ -204,7 +204,7 @@ export function StoryEditorClient() { setShowApiModal(true); toast({ title: "No credits remaining", - description: "You get 1 credit weekly. Add an API key for unlimited generation.", + description: "You get 3 credits weekly. Add an API key for unlimited generation.", variant: "destructive", }); } diff --git a/components/api-key-modal.tsx b/components/api-key-modal.tsx index 51c8117..8abf2ce 100644 --- a/components/api-key-modal.tsx +++ b/components/api-key-modal.tsx @@ -73,7 +73,7 @@ export function ApiKeyModal({ isOpen, onClose, onSubmit }: ApiKeyModalProps) { {existingKey ? "Update your Together API key or add a new one. You can also delete your existing key." - : "You've used your weekly credit! Add your Together API key for unlimited generation."} + : "You've used all your weekly credits! Add your Together API key for unlimited generation."} diff --git a/lib/rate-limit.ts b/lib/rate-limit.ts index dc4bbdd..8686d77 100644 --- a/lib/rate-limit.ts +++ b/lib/rate-limit.ts @@ -6,10 +6,10 @@ const redis = new Redis({ token: process.env.UPSTASH_REDIS_REST_TOKEN!, }) -// Free tier: 1 comic per week (fixed window) +// Free tier: 3 comics per week (fixed window) export const freeTierRateLimit = new Ratelimit({ redis, - limiter: Ratelimit.fixedWindow(1, "7 d"), + limiter: Ratelimit.fixedWindow(3, "7 d"), analytics: true, prefix: "ratelimit:free-comics", }) \ No newline at end of file