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 });
  }
}