Gmagl
fix: correcciones críticas y refactorización de componentes
3eebcd0
Raw
History Blame Contribute Delete
5.11 kB
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 });
}
}