Spaces:
Build error
Build error
| 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 } | |
| ); | |
| } | |
| } | |