sofia-cloud / src /app /api /characters /route.ts
GoGma's picture
Update src/app/api/characters/route.ts
a9c09de verified
raw
history blame
5.97 kB
import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
import ZAI from "z-ai-web-dev-sdk";
// ================================
// GET - Listar personajes
// ================================
export async function GET() {
try {
const characters = await db.character.findMany({
include: {
contents: {
take: 5,
orderBy: { createdAt: "desc" },
},
},
orderBy: { createdAt: "desc" },
});
return NextResponse.json({
success: true,
characters,
total: characters.length,
});
} catch (error) {
console.error("Error fetching characters:", error);
return NextResponse.json(
{ success: false, error: "Error al obtener personajes" },
{ status: 500 }
);
}
}
// ================================
// POST - Crear personaje
// ================================
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const {
name,
description,
generateReference = false,
traits,
} = body;
if (!name) {
return NextResponse.json(
{ success: false, error: "El nombre del personaje es requerido" },
{ status: 400 }
);
}
let referenceImage: string | null = null;
let characterTraits: string | null = null;
// =================================
// Generar imagen de referencia
// =================================
if (generateReference) {
try {
const zai = await ZAI.create();
const characterPrompt = `Character reference sheet: ${name}. ${
description || "Original character"
}. Full body view, multiple angles (front, side, back), consistent character design, neutral pose, white background, professional character sheet.`;
const response: any = await zai.images.generations.create({
prompt: characterPrompt,
size: "1344x768",
});
const imageBase64 =
response?.data?.[0]?.base64 || null;
if (imageBase64) {
referenceImage = `data:image/png;base64,${imageBase64}`;
}
// =================================
// Extraer traits con IA
// =================================
if (!traits) {
const traitsResponse: any =
await zai.chat.completions.create({
messages: [
{
role: "system",
content:
'Eres experto en diseño de personajes. Responde SOLO JSON: { "face": "", "body": "", "hair": "", "clothing": "", "colors": "", "distinctive": "" }',
},
{
role: "user",
content: `Personaje: ${name}. Descripción: ${
description || "Original character"
}`,
},
],
});
const traitsText =
traitsResponse?.choices?.[0]?.message?.content || "";
const jsonMatch = traitsText.match(/\{[\s\S]*\}/);
if (jsonMatch) {
characterTraits = jsonMatch[0];
} else {
characterTraits = JSON.stringify({
description: description || "Original character",
});
}
}
} catch (genError) {
console.error("Error generando referencia:", genError);
}
}
// Traits desde request
if (traits) {
characterTraits =
typeof traits === "string"
? traits
: JSON.stringify(traits);
}
// =================================
// Crear personaje en BD
// =================================
const character = await db.character.create({
data: {
name,
description: description || null,
referenceImage,
traits:
characterTraits ||
JSON.stringify({ name, description }),
},
});
return NextResponse.json({
success: true,
character,
message: `Personaje "${name}" creado exitosamente`,
});
} catch (error) {
console.error("Error creating character:", error);
return NextResponse.json(
{ success: false, error: "Error al crear personaje" },
{ status: 500 }
);
}
}
// ================================
// PUT - Actualizar personaje
// ================================
export async function PUT(request: NextRequest) {
try {
const body = await request.json();
const { id, name, description, traits } = body;
if (!id) {
return NextResponse.json(
{ success: false, error: "ID del personaje requerido" },
{ status: 400 }
);
}
const character = await db.character.update({
where: { id },
data: {
name: name || undefined,
description: description || undefined,
traits: traits || undefined,
},
});
return NextResponse.json({
success: true,
character,
});
} catch (error) {
console.error("Error updating character:", error);
return NextResponse.json(
{ success: false, error: "Error al actualizar personaje" },
{ status: 500 }
);
}
}
// ================================
// DELETE - Eliminar personaje
// ================================
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.character.delete({
where: { id },
});
return NextResponse.json({
success: true,
message: "Personaje eliminado",
});
} catch (error) {
console.error("Error deleting character:", error);
return NextResponse.json(
{ success: false, error: "Error al eliminar personaje" },
{ status: 500 }
);
}
}