sofia-cloud / src /app /api /pets /route.ts
Gmagl
Add Sofia Cloud complete files
333c51a
Raw
History Blame
9.39 kB
import { NextRequest, NextResponse } from "next/server";
import ZAI from "z-ai-web-dev-sdk";
import { prisma } from "@/lib/db";
// Tipos de mascotas disponibles con características
const PET_TYPES = {
dog: {
name: "Perro",
breeds: ["Golden Retriever", "Labrador", "French Bulldog", "Pomeranian", "Corgi", "Husky", "Poodle", "Chihuahua", "Yorkshire", "Beagle"],
personalities: ["juguetón", "leal", "energético", "calmado", "protector", "amigable"],
popularIn: ["lifestyle", "fitness", "family", "outdoor"],
engagementBoost: 35, // % de aumento de engagement promedio
accessories: ["collar", "bandana", "ropa para mascotas", "juguetes", "gafas"]
},
cat: {
name: "Gato",
breeds: ["Persa", "Siames", "Maine Coon", "British Shorthair", "Ragdoll", "Bengala", "Sphynx", "Scottish Fold"],
personalities: ["independiente", "afectuoso", "curioso", "perezoso", "juguetón", "elegante"],
popularIn: ["lifestyle", "cozy", "aesthetic", "gaming"],
engagementBoost: 28,
accessories: ["collar", "campanita", "torre para gatos", "cajas", "mantas"]
},
bird: {
name: "Pájaro",
breeds: ["Canario", "Periquito", "Cacatúa", "Loro", "Agapornis", "Guacamayo"],
personalities: ["cantor", "social", "inteligente", "tranquilo", "travieso"],
popularIn: ["nature", "music", "artistic"],
engagementBoost: 15,
accessories: ["jaula decorativa", "juguetes", "posadores"]
},
rabbit: {
name: "Conejo",
breeds: ["Holandés", "Mini Lop", "Rex", "Angora", "Enano"],
personalities: ["tierno", "curioso", "suave", "saltarín", "tranquilo"],
popularIn: ["cute", "aesthetic", "cozy"],
engagementBoost: 22,
accessories: ["moños", "ropa miniatura", "juguetes"]
},
hamster: {
name: "Hámster",
breeds: ["Sirio", "Enano Ruso", "Roborovski", "Chino"],
personalities: ["pequeño", "activo", "adorable", "curioso"],
popularIn: ["cute", "pets", "daily"],
engagementBoost: 18,
accessories: ["rueda", "bolas", "casitas"]
}
};
// GET - Obtener mascotas
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const characterId = searchParams.get("characterId");
const type = searchParams.get("type");
const where: Record<string, unknown> = { isActive: true };
if (characterId) where.characterId = characterId;
if (type) where.type = type;
const pets = await prisma.pet.findMany({
where,
include: {
character: {
select: { name: true }
}
},
orderBy: { createdAt: "desc" }
});
return NextResponse.json({
success: true,
pets,
petTypes: PET_TYPES,
total: pets.length
});
} catch (error) {
console.error("Error fetching pets:", error);
return NextResponse.json(
{ success: false, error: "Error al obtener mascotas" },
{ status: 500 }
);
}
}
// POST - Crear mascota
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const {
name, type, breed, description, personality,
color, accessories, characterId, generateReference
} = body;
// Validar tipo de mascota
const petType = PET_TYPES[type as keyof typeof PET_TYPES];
if (!petType) {
return NextResponse.json(
{ success: false, error: "Tipo de mascota no válido" },
{ status: 400 }
);
}
let referenceImage = null;
// Generar imagen de referencia si se solicita
if (generateReference) {
const zai = await ZAI.create();
const prompt = `A ${breed || petType.name.toLowerCase()} ${type} named ${name}.
${color ? `Color: ${color}.` : ""}
${personality ? `Personality: ${personality}.` : ""}
Style: High quality, photorealistic, social media ready, cute and appealing.
Background: Soft, aesthetic, suitable for Instagram/TikTok.
Pose: Natural and engaging, looking at camera or doing a cute action.`;
try {
const imageResponse = await zai.images.generations.create({
prompt,
size: "1024x1024"
});
referenceImage = imageResponse.data[0]?.base64;
} catch (imgError) {
console.error("Error generating pet image:", imgError);
}
}
const pet = await prisma.pet.create({
data: {
name,
type,
breed,
description,
personality,
color,
accessories: accessories ? JSON.stringify(accessories) : null,
traits: JSON.stringify({
typeInfo: petType,
engagementBoost: petType.engagementBoost
}),
referenceImage,
characterId
}
});
return NextResponse.json({
success: true,
pet,
message: `Mascota "${name}" creada correctamente`,
engagementBoost: petType.engagementBoost
});
} catch (error) {
console.error("Error creating pet:", error);
return NextResponse.json(
{ success: false, error: "Error al crear mascota" },
{ status: 500 }
);
}
}
// PUT - Actualizar mascota
export async function PUT(request: NextRequest) {
try {
const body = await request.json();
const { id, ...updateData } = body;
if (!id) {
return NextResponse.json(
{ success: false, error: "ID de mascota requerido" },
{ status: 400 }
);
}
// Si hay accessories o traits, convertir a JSON string
if (updateData.accessories && typeof updateData.accessories !== "string") {
updateData.accessories = JSON.stringify(updateData.accessories);
}
if (updateData.traits && typeof updateData.traits !== "string") {
updateData.traits = JSON.stringify(updateData.traits);
}
const pet = await prisma.pet.update({
where: { id },
data: updateData
});
return NextResponse.json({
success: true,
pet,
message: "Mascota actualizada correctamente"
});
} catch (error) {
console.error("Error updating pet:", error);
return NextResponse.json(
{ success: false, error: "Error al actualizar mascota" },
{ status: 500 }
);
}
}
// DELETE - Eliminar mascota
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 de mascota requerido" },
{ status: 400 }
);
}
await prisma.pet.update({
where: { id },
data: { isActive: false }
});
return NextResponse.json({
success: true,
message: "Mascota eliminada correctamente"
});
} catch (error) {
console.error("Error deleting pet:", error);
return NextResponse.json(
{ success: false, error: "Error al eliminar mascota" },
{ status: 500 }
);
}
}
// PATCH - Generar contenido con mascota
export async function PATCH(request: NextRequest) {
try {
const body = await request.json();
const { petId, contentType, platform, theme } = body;
const pet = await prisma.pet.findUnique({
where: { id: petId },
include: { character: true }
});
if (!pet) {
return NextResponse.json(
{ success: false, error: "Mascota no encontrada" },
{ status: 404 }
);
}
const zai = await ZAI.create();
// Generar ideas de contenido con la mascota
const contentPrompt = `Genera ideas de contenido para una mascota:
- Nombre: ${pet.name}
- Tipo: ${pet.type}
- Raza: ${pet.breed || "No especificada"}
- Personalidad: ${pet.personality || "No especificada"}
${pet.character ? `- Dueño: ${pet.character.name}` : ""}
- Tipo de contenido: ${contentType || "foto"}
- Plataforma: ${platform || "Instagram"}
- Tema: ${theme || "lifestyle"}
Proporciona:
1. 5 ideas de contenido específicas con esta mascota
2. Ganchos/hooks para cada idea
3. Hashtags recomendados
4. Mejor momento del día para publicar
5. Elementos visuales sugeridos
Responde en JSON:
{
"contentIdeas": [{"title": "", "description": "", "hook": "", "cta": ""}],
"hashtags": [],
"bestPostingTime": "",
"visualElements": [],
"engagementTips": []
}`;
const completion = await zai.chat.completions.create({
messages: [
{
role: "system",
content: "Eres un experto en contenido de mascotas para redes sociales. Genera ideas creativas y virales."
},
{
role: "user",
content: contentPrompt
}
],
temperature: 0.8,
max_tokens: 2000,
});
let contentIdeas;
try {
const response = completion.choices[0]?.message?.content || "";
const match = response.match(/\{[\s\S]*\}/);
if (match) {
contentIdeas = JSON.parse(match[0]);
}
} catch {
contentIdeas = { raw: completion.choices[0]?.message?.content };
}
return NextResponse.json({
success: true,
pet: {
id: pet.id,
name: pet.name,
type: pet.type,
breed: pet.breed
},
contentIdeas,
engagementBoost: PET_TYPES[pet.type as keyof typeof PET_TYPES]?.engagementBoost || 20
});
} catch (error) {
console.error("Error generating pet content:", error);
return NextResponse.json(
{ success: false, error: "Error al generar contenido" },
{ status: 500 }
);
}
}