Spaces:
Build error
Build error
| import { NextRequest, NextResponse } from "next/server"; | |
| import { db } from "@/lib/db"; | |
| import ZAI from "z-ai-web-dev-sdk"; | |
| import { validateUserCredit, logResourceUsage } from "@/lib/credits"; | |
| const GENRES = [ | |
| { id: "romance", name: "Romance" }, | |
| { id: "drama", name: "Drama" }, | |
| { id: "comedy", name: "Comedia" }, | |
| { id: "lifestyle", name: "Lifestyle" }, | |
| { id: "fitness", name: "Fitness" } | |
| ]; | |
| export async function GET(request: NextRequest) { | |
| try { | |
| const { searchParams } = new URL(request.url); | |
| const status = searchParams.get("status"); | |
| const where: Record<string, any> = {}; | |
| if (status) where.status = status; | |
| const stories = await db.story.findMany({ | |
| where, | |
| include: { episodes: { orderBy: { episodeNum: "asc" } } }, | |
| orderBy: { createdAt: "desc" } | |
| }); | |
| return NextResponse.json({ success: true, stories, genres: GENRES, total: stories.length }); | |
| } catch { | |
| return NextResponse.json({ success: false, error: "Error" }, { status: 500 }); | |
| } | |
| } | |
| export async function POST(request: NextRequest) { | |
| try { | |
| const body = await request.json(); | |
| const { prompt, genre, totalEpisodes, userId, tier = "free" } = body; | |
| if (!prompt) { | |
| return NextResponse.json({ success: false, error: "Prompt requerido" }, { status: 400 }); | |
| } | |
| // Validar créditos | |
| const creditCheck = await validateUserCredit(db, userId || "anonymous", "stories_per_month", tier); | |
| if (!creditCheck.allowed) { | |
| return NextResponse.json({ success: false, error: creditCheck.reason, remaining: creditCheck.remaining }, { status: 429 }); | |
| } | |
| const zai = await ZAI.create(); | |
| const completion = await zai.chat.completions.create({ | |
| messages: [ | |
| { role: "system", content: "Eres un guionista. Responde en JSON: {title, synopsis, episodes: [{episodeNum, title, content}]}" }, | |
| { role: "user", content: "Crea una historia: " + prompt } | |
| ], | |
| temperature: 0.8 | |
| }); | |
| let storyData: { title?: string; synopsis?: string; episodes?: Array<{ episodeNum?: number; title?: string; content?: string }> } = {}; | |
| try { | |
| const match = completion.choices[0]?.message?.content?.match(/\{[\s\S]*\}/); | |
| if (match) storyData = JSON.parse(match[0]); | |
| } catch { } | |
| const story = await db.story.create({ | |
| data: { | |
| title: storyData.title || "Nueva Historia", | |
| description: storyData.synopsis || prompt, | |
| genre: genre || "lifestyle", | |
| totalEpisodes: totalEpisodes || storyData.episodes?.length || 7, | |
| status: "draft" | |
| } | |
| }); | |
| if (storyData.episodes && Array.isArray(storyData.episodes)) { | |
| for (let i = 0; i < storyData.episodes.length; i++) { | |
| const ep = storyData.episodes[i]; | |
| await db.storyEpisode.create({ | |
| data: { | |
| storyId: story.id, | |
| episodeNum: ep.episodeNum || i + 1, | |
| title: ep.title || "Episodio " + (i + 1), | |
| content: ep.content || "", | |
| status: "draft" | |
| } | |
| }); | |
| } | |
| } | |
| await db.storyAnalytics.create({ data: { storyId: story.id } }); | |
| // Log del uso de crédito | |
| await logResourceUsage(db, userId || "anonymous", "stories_per_month", story.id); | |
| await db.agentTask.create({ | |
| data: { type: "create_story", status: "completed", input: prompt, output: "Historia creada", completedAt: new Date() } | |
| }); | |
| const fullStory = await db.story.findUnique({ | |
| where: { id: story.id }, | |
| include: { episodes: { orderBy: { episodeNum: "asc" } } } | |
| }); | |
| return NextResponse.json({ | |
| success: true, | |
| story: fullStory, | |
| creditsRemaining: creditCheck.remaining ? creditCheck.remaining - 1 : 0 | |
| }); | |
| } catch (error: unknown) { | |
| const message = error instanceof Error ? error.message : "Error desconocido"; | |
| return NextResponse.json({ success: false, error: message }, { status: 500 }); | |
| } | |
| } | |
| export async function PUT(request: NextRequest) { | |
| try { | |
| const body = await request.json(); | |
| const { id, status, currentEpisode } = body; | |
| if (!id) return NextResponse.json({ success: false, error: "ID requerido" }, { status: 400 }); | |
| const data: Record<string, any> = {}; | |
| if (status) data.status = status; | |
| if (currentEpisode) data.currentEpisode = currentEpisode; | |
| const story = await db.story.update({ where: { id }, data }); | |
| return NextResponse.json({ success: true, story }); | |
| } catch { | |
| return NextResponse.json({ success: false, error: "Error" }, { status: 500 }); | |
| } | |
| } | |
| export async function DELETE(request: NextRequest) { | |
| try { | |
| const { searchParams } = new URL(request.url); | |
| const id = searchParams.get("id"); | |
| if (!id) return NextResponse.json({ success: false, error: "ID requerido" }, { status: 400 }); | |
| await db.storyEpisode.deleteMany({ where: { storyId: id } }); | |
| await db.storyAnalytics.deleteMany({ where: { storyId: id } }); | |
| await db.story.delete({ where: { id } }); | |
| return NextResponse.json({ success: true }); | |
| } catch { | |
| return NextResponse.json({ success: false, error: "Error" }, { status: 500 }); | |
| } | |
| } |