Spaces:
Running
Running
| import { NextResponse } from "next/server"; | |
| import { createServerClient, type CookieOptions } from '@supabase/ssr' | |
| import { cookies } from "next/headers"; | |
| import { supabase as supabaseAdmin } from "@/lib/supabase"; | |
| const PYTHON_API_URL = process.env.PYTHON_API_URL || "http://127.0.0.1:8000"; | |
| const SHOWCASE_KEYWORDS = [ | |
| "database sharding", | |
| "kafka", | |
| "transformers", | |
| "quantum entanglement", | |
| "netflix", | |
| "black hole", | |
| "sorting algorithms", | |
| "uber", | |
| "quicksort", | |
| "bubble sort" | |
| ]; | |
| export async function POST(req: Request) { | |
| try { | |
| // Get request body first to check for demo mode | |
| const body = await req.json(); | |
| const { input_data, input_type, category, quality } = body; | |
| // Check for showcase prompt (Demo Mode) - Bypass Auth and Credits | |
| const lowerInput = (input_data || "").toLowerCase(); | |
| const isShowcase = SHOWCASE_KEYWORDS.some(keyword => lowerInput.includes(keyword)); | |
| if (isShowcase) { | |
| console.log("🎨 Demo Mode activated for prompt:", input_data); | |
| // Return a fake job ID encoded with timestamp to track progress | |
| const timestamp = Date.now(); | |
| return NextResponse.json({ | |
| job_id: `demo-${timestamp}`, | |
| status: "pending", | |
| message: "Job started (Demo)" | |
| }); | |
| } | |
| const cookieStore = cookies() // Removed await for Next.js 14 compatibility | |
| // Create authenticated Supabase client | |
| const supabase = createServerClient( | |
| process.env.NEXT_PUBLIC_SUPABASE_URL!, | |
| process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, | |
| { | |
| cookies: { | |
| getAll() { | |
| return cookieStore.getAll() | |
| }, | |
| setAll(cookiesToSet) { | |
| cookiesToSet.forEach(({ name, value, options }) => { | |
| cookieStore.set(name, value, options) | |
| }) | |
| }, | |
| }, | |
| } | |
| ) | |
| // Get current user | |
| const { data: { user }, error: authError } = await supabase.auth.getUser() | |
| if (authError || !user) { | |
| return NextResponse.json( | |
| { error: "Unauthorized" }, | |
| { status: 401 } | |
| ); | |
| } | |
| // Check credits | |
| const { data: userData, error: userError } = await supabaseAdmin | |
| .from("users") | |
| .select("credits") | |
| .eq("id", user.id) | |
| .single(); | |
| if (userError || !userData) { | |
| return NextResponse.json( | |
| { error: "User not found" }, | |
| { status: 404 } | |
| ); | |
| } | |
| if (userData.credits < 1) { | |
| return NextResponse.json( | |
| { error: "Insufficient credits" }, | |
| { status: 402 } | |
| ); | |
| } | |
| // Real Generation Flow | |
| // Deduct credit | |
| const { error: updateError } = await supabaseAdmin | |
| .from("users") | |
| .update({ credits: userData.credits - 1 }) | |
| .eq("id", user.id); | |
| if (updateError) { | |
| return NextResponse.json( | |
| { error: "Failed to deduct credits" }, | |
| { status: 500 } | |
| ); | |
| } | |
| // Call Python API | |
| const response = await fetch(`${PYTHON_API_URL}/api/generate`, { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| "X-API-Key": process.env.INTERNAL_API_KEY || "", | |
| }, | |
| body: JSON.stringify({ | |
| input_data, | |
| input_type, | |
| category, | |
| quality, | |
| user_id: user.id | |
| }), | |
| }); | |
| if (!response.ok) { | |
| // Refund credit on failure | |
| await supabaseAdmin | |
| .from("users") | |
| .update({ credits: userData.credits }) | |
| .eq("id", user.id); | |
| const error = await response.json(); | |
| return NextResponse.json( | |
| { error: error.detail || "Generation failed" }, | |
| { status: response.status } | |
| ); | |
| } | |
| const data = await response.json(); | |
| return NextResponse.json(data); | |
| } catch (error) { | |
| console.error("Generate error:", error); | |
| return NextResponse.json( | |
| { error: "Internal server error" }, | |
| { status: 500 } | |
| ); | |
| } | |
| } | |