GoGma commited on
Commit
a9c09de
verified
1 Parent(s): b059128

Update src/app/api/characters/route.ts

Browse files
Files changed (1) hide show
  1. src/app/api/characters/route.ts +174 -38
src/app/api/characters/route.ts CHANGED
@@ -2,85 +2,221 @@ import { NextRequest, NextResponse } from "next/server";
2
  import { db } from "@/lib/db";
3
  import ZAI from "z-ai-web-dev-sdk";
4
 
5
- export async function GET(request: NextRequest) {
 
 
 
6
  try {
7
- const characters = await db.character.findMany({ orderBy: { createdAt: "desc" } });
8
- return NextResponse.json({ success: true, characters, total: characters.length });
9
- } catch {
10
- return NextResponse.json({ success: false, error: "Error" }, { status: 500 });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
12
  }
13
 
 
 
 
14
  export async function POST(request: NextRequest) {
15
  try {
16
  const body = await request.json();
17
- const { name, description, generateReference, traits } = body;
 
 
 
 
 
18
 
19
  if (!name) {
20
- return NextResponse.json({ success: false, error: "Nombre requerido" }, { status: 400 });
 
 
 
21
  }
22
 
23
  let referenceImage: string | null = null;
24
  let characterTraits: string | null = null;
25
 
 
 
 
26
  if (generateReference) {
27
  try {
28
  const zai = await ZAI.create();
29
- const response = await zai.images.generations.create({
30
- prompt: "Character reference: " + name + ", " + (description || "original character"),
31
- size: "1024x1024"
 
 
 
 
 
32
  });
33
- const imageBase64 = response.data[0]?.base64;
 
 
 
34
  if (imageBase64) {
35
- referenceImage = "generated_" + Date.now();
36
- if (!traits) {
37
- characterTraits = JSON.stringify({ name, description });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
  }
40
- } catch {}
 
 
41
  }
42
 
43
- const finalTraits = traits || characterTraits || JSON.stringify({ name });
 
 
 
 
 
 
44
 
 
 
 
45
  const character = await db.character.create({
46
- data: { name, description: description || null, referenceImage, traits: finalTraits }
 
 
 
 
 
 
 
47
  });
48
 
49
- return NextResponse.json({ success: true, character });
50
- } catch {
51
- return NextResponse.json({ success: false, error: "Error" }, { status: 500 });
 
 
 
 
 
 
 
 
52
  }
53
  }
54
 
 
 
 
55
  export async function PUT(request: NextRequest) {
56
  try {
57
  const body = await request.json();
58
  const { id, name, description, traits } = body;
59
- if (!id) return NextResponse.json({ success: false, error: "ID requerido" }, { status: 400 });
60
 
61
- const data: { name?: string; description?: string | null; traits?: string } = {};
62
- if (name) data.name = name;
63
- if (description !== undefined) data.description = description || null;
64
- if (traits) data.traits = traits;
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- const character = await db.character.update({ where: { id }, data });
67
- return NextResponse.json({ success: true, character });
68
- } catch {
69
- return NextResponse.json({ success: false, error: "Error" }, { status: 500 });
 
 
 
 
 
 
70
  }
71
  }
72
 
 
 
 
73
  export async function DELETE(request: NextRequest) {
74
  try {
75
  const { searchParams } = new URL(request.url);
76
  const id = searchParams.get("id");
77
- if (!id) return NextResponse.json({ success: false, error: "ID requerido" }, { status: 400 });
78
-
79
- await db.pet.deleteMany({ where: { characterId: id } });
80
- await db.content.updateMany({ where: { characterId: id }, data: { characterId: null } });
81
- await db.character.delete({ where: { id } });
82
- return NextResponse.json({ success: true });
83
- } catch {
84
- return NextResponse.json({ success: false, error: "Error" }, { status: 500 });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
- }
 
2
  import { db } from "@/lib/db";
3
  import ZAI from "z-ai-web-dev-sdk";
4
 
5
+ // ================================
6
+ // GET - Listar personajes
7
+ // ================================
8
+ export async function GET() {
9
  try {
10
+ const characters = await db.character.findMany({
11
+ include: {
12
+ contents: {
13
+ take: 5,
14
+ orderBy: { createdAt: "desc" },
15
+ },
16
+ },
17
+ orderBy: { createdAt: "desc" },
18
+ });
19
+
20
+ return NextResponse.json({
21
+ success: true,
22
+ characters,
23
+ total: characters.length,
24
+ });
25
+ } catch (error) {
26
+ console.error("Error fetching characters:", error);
27
+ return NextResponse.json(
28
+ { success: false, error: "Error al obtener personajes" },
29
+ { status: 500 }
30
+ );
31
  }
32
  }
33
 
34
+ // ================================
35
+ // POST - Crear personaje
36
+ // ================================
37
  export async function POST(request: NextRequest) {
38
  try {
39
  const body = await request.json();
40
+ const {
41
+ name,
42
+ description,
43
+ generateReference = false,
44
+ traits,
45
+ } = body;
46
 
47
  if (!name) {
48
+ return NextResponse.json(
49
+ { success: false, error: "El nombre del personaje es requerido" },
50
+ { status: 400 }
51
+ );
52
  }
53
 
54
  let referenceImage: string | null = null;
55
  let characterTraits: string | null = null;
56
 
57
+ // =================================
58
+ // Generar imagen de referencia
59
+ // =================================
60
  if (generateReference) {
61
  try {
62
  const zai = await ZAI.create();
63
+
64
+ const characterPrompt = `Character reference sheet: ${name}. ${
65
+ description || "Original character"
66
+ }. Full body view, multiple angles (front, side, back), consistent character design, neutral pose, white background, professional character sheet.`;
67
+
68
+ const response: any = await zai.images.generations.create({
69
+ prompt: characterPrompt,
70
+ size: "1344x768",
71
  });
72
+
73
+ const imageBase64 =
74
+ response?.data?.[0]?.base64 || null;
75
+
76
  if (imageBase64) {
77
+ referenceImage = `data:image/png;base64,${imageBase64}`;
78
+ }
79
+
80
+ // =================================
81
+ // Extraer traits con IA
82
+ // =================================
83
+ if (!traits) {
84
+ const traitsResponse: any =
85
+ await zai.chat.completions.create({
86
+ messages: [
87
+ {
88
+ role: "system",
89
+ content:
90
+ 'Eres experto en dise帽o de personajes. Responde SOLO JSON: { "face": "", "body": "", "hair": "", "clothing": "", "colors": "", "distinctive": "" }',
91
+ },
92
+ {
93
+ role: "user",
94
+ content: `Personaje: ${name}. Descripci贸n: ${
95
+ description || "Original character"
96
+ }`,
97
+ },
98
+ ],
99
+ });
100
+
101
+ const traitsText =
102
+ traitsResponse?.choices?.[0]?.message?.content || "";
103
+
104
+ const jsonMatch = traitsText.match(/\{[\s\S]*\}/);
105
+
106
+ if (jsonMatch) {
107
+ characterTraits = jsonMatch[0];
108
+ } else {
109
+ characterTraits = JSON.stringify({
110
+ description: description || "Original character",
111
+ });
112
  }
113
  }
114
+ } catch (genError) {
115
+ console.error("Error generando referencia:", genError);
116
+ }
117
  }
118
 
119
+ // Traits desde request
120
+ if (traits) {
121
+ characterTraits =
122
+ typeof traits === "string"
123
+ ? traits
124
+ : JSON.stringify(traits);
125
+ }
126
 
127
+ // =================================
128
+ // Crear personaje en BD
129
+ // =================================
130
  const character = await db.character.create({
131
+ data: {
132
+ name,
133
+ description: description || null,
134
+ referenceImage,
135
+ traits:
136
+ characterTraits ||
137
+ JSON.stringify({ name, description }),
138
+ },
139
  });
140
 
141
+ return NextResponse.json({
142
+ success: true,
143
+ character,
144
+ message: `Personaje "${name}" creado exitosamente`,
145
+ });
146
+ } catch (error) {
147
+ console.error("Error creating character:", error);
148
+ return NextResponse.json(
149
+ { success: false, error: "Error al crear personaje" },
150
+ { status: 500 }
151
+ );
152
  }
153
  }
154
 
155
+ // ================================
156
+ // PUT - Actualizar personaje
157
+ // ================================
158
  export async function PUT(request: NextRequest) {
159
  try {
160
  const body = await request.json();
161
  const { id, name, description, traits } = body;
 
162
 
163
+ if (!id) {
164
+ return NextResponse.json(
165
+ { success: false, error: "ID del personaje requerido" },
166
+ { status: 400 }
167
+ );
168
+ }
169
+
170
+ const character = await db.character.update({
171
+ where: { id },
172
+ data: {
173
+ name: name || undefined,
174
+ description: description || undefined,
175
+ traits: traits || undefined,
176
+ },
177
+ });
178
 
179
+ return NextResponse.json({
180
+ success: true,
181
+ character,
182
+ });
183
+ } catch (error) {
184
+ console.error("Error updating character:", error);
185
+ return NextResponse.json(
186
+ { success: false, error: "Error al actualizar personaje" },
187
+ { status: 500 }
188
+ );
189
  }
190
  }
191
 
192
+ // ================================
193
+ // DELETE - Eliminar personaje
194
+ // ================================
195
  export async function DELETE(request: NextRequest) {
196
  try {
197
  const { searchParams } = new URL(request.url);
198
  const id = searchParams.get("id");
199
+
200
+ if (!id) {
201
+ return NextResponse.json(
202
+ { success: false, error: "ID requerido" },
203
+ { status: 400 }
204
+ );
205
+ }
206
+
207
+ await db.character.delete({
208
+ where: { id },
209
+ });
210
+
211
+ return NextResponse.json({
212
+ success: true,
213
+ message: "Personaje eliminado",
214
+ });
215
+ } catch (error) {
216
+ console.error("Error deleting character:", error);
217
+ return NextResponse.json(
218
+ { success: false, error: "Error al eliminar personaje" },
219
+ { status: 500 }
220
+ );
221
  }
222
+ }