Spaces:
Build error
Build error
File size: 4,583 Bytes
333c51a 3eebcd0 333c51a 1eae852 333c51a 3eebcd0 333c51a 1eae852 333c51a 3eebcd0 1eae852 b8b98dd 1eae852 b8b98dd 1eae852 b8b98dd 1eae852 333c51a 1eae852 333c51a 1eae852 333c51a 1eae852 333c51a 1eae852 625d2ed 3eebcd0 1eae852 625d2ed b8b98dd 3eebcd0 1eae852 3eebcd0 333c51a 3eebcd0 333c51a 3eebcd0 1eae852 333c51a 1eae852 333c51a 1eae852 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import { NextRequest, NextResponse } from "next/server";
import ZAI from "z-ai-web-dev-sdk";
import { db } from "@/lib/db";
import { validateUserCredit, logResourceUsage } from "@/lib/credits";
const CENSOR_RULES: Record<string, string> = {
youtube: "family friendly, no nudity, no violence",
tiktok: "age appropriate, no suggestive content",
instagram: "community guidelines, no graphic content",
twitter: "content warning if sensitive",
general: "safe for work"
};
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { prompt, optimizedPrompt, platform = "general", style = "realistic", size = "1024x1024", userId, tier = "free" } = body;
if (!prompt && !optimizedPrompt) {
return NextResponse.json({ success: false, error: "Se requiere un prompt" }, { status: 400 });
}
// Validar créditos
const creditCheck = await validateUserCredit(db, userId || "anonymous", "images_per_month", tier);
if (!creditCheck.allowed) {
return NextResponse.json({ success: false, error: creditCheck.reason, remaining: creditCheck.remaining }, { status: 429 });
}
let finalPrompt = optimizedPrompt || prompt;
// Inject Character Visual Persona
const character = await db.character.findFirst({ where: { isActive: true } });
if (character?.styleDescription || character?.referenceImage) {
finalPrompt = `${character.styleDescription || "AI Character"}. ${finalPrompt}`;
}
const censorRule = CENSOR_RULES[platform] || CENSOR_RULES.general;
// Skip censorship for private/exclusive monetization platforms
const uncensoredPlatforms = ["onlyfans", "fansly", "telegram-uncensored", "patreon-uncensored"];
if (!uncensoredPlatforms.includes(platform)) {
finalPrompt = finalPrompt + ", " + censorRule;
}
const styleMap: Record<string, string> = {
anime: "anime style, manga aesthetic",
realistic: "photorealistic, highly detailed",
artistic: "digital art, creative"
};
if (styleMap[style]) finalPrompt = finalPrompt + ", " + styleMap[style];
const contentRecord = await db.content.create({
data: {
type: "image",
title: prompt.substring(0, 50),
description: prompt,
prompt: prompt,
optimizedPrompt: finalPrompt,
platform: platform,
characterId: character?.id || null,
status: "processing"
}
});
try {
const zai = await ZAI.create();
const response = await zai.images.generations.create({
prompt: finalPrompt,
size: size as "1024x1024"
});
const imageBase64 = response.data[0]?.base64;
if (!imageBase64) throw new Error("No se recibio imagen");
await db.content.update({
where: { id: contentRecord.id },
data: { status: "completed", filePath: "generated" }
});
// Log del uso de crédito
await logResourceUsage(db, userId || "anonymous", "images_per_month", contentRecord.id);
await db.agentTask.create({
data: { type: "generate_image", status: "completed", input: prompt, output: "Imagen generada", completedAt: new Date() }
});
return NextResponse.json({
success: true,
image: { id: contentRecord.id, base64: imageBase64, prompt: finalPrompt, platform, size },
creditsRemaining: creditCheck.remaining ? creditCheck.remaining - 1 : 0
});
} catch (genError) {
await db.content.update({ where: { id: contentRecord.id }, data: { status: "failed" } });
const errorMessage = genError instanceof Error ? genError.message : "Error generando imagen";
return NextResponse.json({ success: false, error: errorMessage }, { status: 500 });
}
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : "Error interno";
return NextResponse.json({ success: false, error: errorMessage }, { status: 500 });
}
}
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const platform = searchParams.get("platform");
const limit = Number.parseInt(searchParams.get("limit") || "20", 10);
const where: Record<string, any> = { type: "image" };
if (platform) where.platform = platform;
const images = await db.content.findMany({ where, orderBy: { createdAt: "desc" }, take: limit });
return NextResponse.json({ success: true, images, total: images.length });
} catch {
return NextResponse.json({ success: false, error: "Error" }, { status: 500 });
}
} |