style: clean up code formatting and remove trailing whitespace
refactor: reorganize imports and fix type imports
This commit is contained in:
1 parent
d3704602fd
commit
47c04de6fe
232 files changed
+7140
-4798
No files matched your search
@@ -1,10 +1,14 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { requireAdminUser } from "@/lib/auth/middleware";
|
||||
import { addColumnToCategory, type SQLiteColumnDefinition } from "@/lib/items/sqlite-manager";
|
||||
import {
|
||||
addColumnToCategory,
|
||||
type SQLiteColumnDefinition,
|
||||
} from "@/lib/items/sqlite-manager";
|
||||
import { secureLogger } from "@/lib/secure-logger";
|
||||
|
||||
function sanitizeColumn(column: any): SQLiteColumnDefinition {
|
||||
const name = typeof column?.name === "string" ? column.name.trim().toLowerCase() : "";
|
||||
const name =
|
||||
typeof column?.name === "string" ? column.name.trim().toLowerCase() : "";
|
||||
const type = typeof column?.type === "string" ? column.type : "TEXT";
|
||||
const notNull = column?.notNull === true;
|
||||
const defaultValue = column?.defaultValue ?? undefined;
|
||||
@@ -26,7 +30,10 @@ function sanitizeColumn(column: any): SQLiteColumnDefinition {
|
||||
} satisfies SQLiteColumnDefinition;
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest, { params }: { params: Promise<{ name: string }> }) {
|
||||
export async function POST(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ name: string }> },
|
||||
) {
|
||||
const auth = await requireAdminUser(request);
|
||||
if (auth instanceof NextResponse) {
|
||||
return auth;
|
||||
@@ -38,14 +45,19 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
|
||||
const body = await request.json();
|
||||
const column = sanitizeColumn(body?.column ?? body);
|
||||
const created = addColumnToCategory({ category: name, column });
|
||||
return NextResponse.json({ success: true, column: created }, { status: 201 });
|
||||
return NextResponse.json(
|
||||
{ success: true, column: created },
|
||||
{ status: 201 },
|
||||
);
|
||||
} catch (error) {
|
||||
secureLogger.error("Falha ao adicionar coluna à categoria", error);
|
||||
return NextResponse.json(
|
||||
{ success: false, error: error instanceof Error ? error.message : "Erro ao adicionar coluna" },
|
||||
{
|
||||
success: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : "Erro ao adicionar coluna",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { requireAdminUser } from "@/lib/auth/middleware";
|
||||
import {
|
||||
listCategoryTemplates,
|
||||
createCategoryTemplate,
|
||||
type SQLiteColumnDefinition,
|
||||
type CreateCategoryInput,
|
||||
createCategoryTemplate,
|
||||
listCategoryTemplates,
|
||||
type SQLiteColumnDefinition,
|
||||
} from "@/lib/items/sqlite-manager";
|
||||
import { secureLogger } from "@/lib/secure-logger";
|
||||
|
||||
@@ -16,7 +16,10 @@ export async function GET(request: NextRequest) {
|
||||
|
||||
try {
|
||||
const templates = listCategoryTemplates();
|
||||
return NextResponse.json({ success: true, categories: templates }, { status: 200 });
|
||||
return NextResponse.json(
|
||||
{ success: true, categories: templates },
|
||||
{ status: 200 },
|
||||
);
|
||||
} catch (error) {
|
||||
secureLogger.error("Falha ao listar categorias dinâmicas", error);
|
||||
return NextResponse.json(
|
||||
@@ -27,7 +30,8 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
function sanitizeColumn(column: any): SQLiteColumnDefinition {
|
||||
const name = typeof column?.name === "string" ? column.name.trim().toLowerCase() : "";
|
||||
const name =
|
||||
typeof column?.name === "string" ? column.name.trim().toLowerCase() : "";
|
||||
const type = typeof column?.type === "string" ? column.type : "TEXT";
|
||||
const notNull = column?.notNull === true;
|
||||
const defaultValue = column?.defaultValue ?? undefined;
|
||||
@@ -53,7 +57,8 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
try {
|
||||
const body = await request.json();
|
||||
const rawName = typeof body?.name === "string" ? body.name.trim().toLowerCase() : "";
|
||||
const rawName =
|
||||
typeof body?.name === "string" ? body.name.trim().toLowerCase() : "";
|
||||
if (!rawName) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: "Nome da categoria é obrigatório" },
|
||||
@@ -61,10 +66,17 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
const columnsArray: unknown[] = Array.isArray(body?.columns) ? body.columns : [];
|
||||
const columns = columnsArray.map((column) => sanitizeColumn(column)).filter((column) => {
|
||||
return !(column && ["id", "nome", "image_url", "image_local_path"].includes(column.name));
|
||||
});
|
||||
const columnsArray: unknown[] = Array.isArray(body?.columns)
|
||||
? body.columns
|
||||
: [];
|
||||
const columns = columnsArray
|
||||
.map((column) => sanitizeColumn(column))
|
||||
.filter((column) => {
|
||||
return !(
|
||||
column &&
|
||||
["id", "nome", "image_url", "image_local_path"].includes(column.name)
|
||||
);
|
||||
});
|
||||
|
||||
const input: CreateCategoryInput = {
|
||||
name: rawName,
|
||||
@@ -76,7 +88,11 @@ export async function POST(request: NextRequest) {
|
||||
} catch (error) {
|
||||
secureLogger.error("Falha ao criar categoria dinâmica", error);
|
||||
return NextResponse.json(
|
||||
{ success: false, error: error instanceof Error ? error.message : "Erro ao criar categoria" },
|
||||
{
|
||||
success: false,
|
||||
error:
|
||||
error instanceof Error ? error.message : "Erro ao criar categoria",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { requireAdminUser } from "@/lib/auth/middleware";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { generateItemStructure } from "@/lib/ai/generate-item-structure";
|
||||
import { calculateTokenCost } from "@/lib/ai/token-pricing";
|
||||
import { recordTokenUsage } from "@/lib/ai/token-usage";
|
||||
import { requireAdminUser } from "@/lib/auth/middleware";
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const auth = await requireAdminUser(request);
|
||||
@@ -39,7 +39,7 @@ export async function POST(request: NextRequest) {
|
||||
success: false,
|
||||
error: "Forneça descrição ou ao menos uma imagem para análise.",
|
||||
},
|
||||
{ status: 400 }
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ export async function POST(request: NextRequest) {
|
||||
});
|
||||
|
||||
// Cálculo de custo baseado em usageMetadata
|
||||
const model = (result.model ?? "gemini-2.5-flash") as keyof typeof import("@/lib/ai/token-pricing").TOKEN_PRICING;
|
||||
const _model = (result.model ??
|
||||
"gemini-2.5-flash") as keyof typeof import("@/lib/ai/token-pricing").TOKEN_PRICING;
|
||||
const breakdown = calculateTokenCost("gemini-2.5-flash", result.usage);
|
||||
|
||||
// Persistir histórico para relatórios (não bloqueia resposta; erros são logados no Redis util)
|
||||
@@ -104,7 +105,6 @@ export async function POST(request: NextRequest) {
|
||||
model: result.model ?? "gemini-2.5-flash",
|
||||
requestId,
|
||||
},
|
||||
{ status: 200 }
|
||||
{ status: 200 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { requireAdminUser } from "@/lib/auth/middleware";
|
||||
import {
|
||||
insertCategoryItem,
|
||||
listCategoryTemplates,
|
||||
updateCategoryItem,
|
||||
} from "@/lib/items/sqlite-manager";
|
||||
import {
|
||||
createAdminItem,
|
||||
getItemById,
|
||||
searchAdminItems,
|
||||
updateAdminItem,
|
||||
getItemById,
|
||||
} from "@/lib/prisma/queries/items";
|
||||
import {
|
||||
insertCategoryItem,
|
||||
updateCategoryItem,
|
||||
listCategoryTemplates,
|
||||
} from "@/lib/items/sqlite-manager";
|
||||
|
||||
function parseNumber(value: string | null | undefined, fallback: number): number {
|
||||
function parseNumber(
|
||||
value: string | null | undefined,
|
||||
fallback: number,
|
||||
): number {
|
||||
const parsed = Number(value);
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
}
|
||||
@@ -32,18 +35,25 @@ function parseList(value: unknown): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
function normalizeDynamicFields(category: string, rawFields: Record<string, unknown> | undefined) {
|
||||
function normalizeDynamicFields(
|
||||
category: string,
|
||||
rawFields: Record<string, unknown> | undefined,
|
||||
) {
|
||||
if (!rawFields || typeof rawFields !== "object") {
|
||||
return {} as Record<string, unknown>;
|
||||
}
|
||||
|
||||
const templates = listCategoryTemplates();
|
||||
const template = templates.find((entry) => entry.name === category.toLowerCase());
|
||||
const template = templates.find(
|
||||
(entry) => entry.name === category.toLowerCase(),
|
||||
);
|
||||
if (!template) {
|
||||
return rawFields;
|
||||
}
|
||||
|
||||
const columnMap = new Map(template.columns.map((column) => [column.name, column]));
|
||||
const columnMap = new Map(
|
||||
template.columns.map((column) => [column.name, column]),
|
||||
);
|
||||
const normalized: Record<string, unknown> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(rawFields)) {
|
||||
@@ -114,7 +124,7 @@ export async function GET(request: NextRequest) {
|
||||
error: "Falha ao consultar itens",
|
||||
message: error?.message || "Erro desconhecido",
|
||||
},
|
||||
{ status: 500 }
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -128,21 +138,28 @@ export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const name = typeof body?.name === "string" ? body.name.trim() : "";
|
||||
const category = typeof body?.category === "string" ? body.category.trim().toLowerCase() : "";
|
||||
const originServer = typeof body?.server === "string" ? body.server.trim() || null : null;
|
||||
const category =
|
||||
typeof body?.category === "string"
|
||||
? body.category.trim().toLowerCase()
|
||||
: "";
|
||||
const originServer =
|
||||
typeof body?.server === "string" ? body.server.trim() || null : null;
|
||||
|
||||
if (!name || !category) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: "Nome e categoria são obrigatórios." },
|
||||
{ status: 400 }
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const dynamicFields = normalizeDynamicFields(category, body?.fields);
|
||||
|
||||
const imageUrl = typeof body?.imageUrl === "string" ? body.imageUrl.trim() || null : null;
|
||||
const imageUrl =
|
||||
typeof body?.imageUrl === "string" ? body.imageUrl.trim() || null : null;
|
||||
const imageLocalPath =
|
||||
typeof body?.imageLocalPath === "string" ? body.imageLocalPath.trim() || null : null;
|
||||
typeof body?.imageLocalPath === "string"
|
||||
? body.imageLocalPath.trim() || null
|
||||
: null;
|
||||
|
||||
const sqliteData = {
|
||||
nome: name,
|
||||
@@ -158,16 +175,25 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const sqliteId = insertCategoryItem({ category, data: sqliteData });
|
||||
|
||||
const metadataBase = typeof body?.metadata === "object" && body.metadata !== null ? body.metadata : {};
|
||||
const metadata = { ...metadataBase, ...dynamicFields } as Record<string, unknown>;
|
||||
const metadataBase =
|
||||
typeof body?.metadata === "object" && body.metadata !== null
|
||||
? body.metadata
|
||||
: {};
|
||||
const metadata = { ...metadataBase, ...dynamicFields } as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
|
||||
const itemServers = parseList(body?.servers);
|
||||
const finalServers = originServer ? Array.from(new Set([originServer, ...itemServers])) : itemServers;
|
||||
const finalServers = originServer
|
||||
? Array.from(new Set([originServer, ...itemServers]))
|
||||
: itemServers;
|
||||
|
||||
const item = await createAdminItem({
|
||||
item_name: name,
|
||||
category,
|
||||
rarity: typeof body?.rarity === "string" ? body.rarity.trim() || null : null,
|
||||
rarity:
|
||||
typeof body?.rarity === "string" ? body.rarity.trim() || null : null,
|
||||
image_url: imageUrl,
|
||||
image_local_path: imageLocalPath,
|
||||
level: typeof body?.level === "number" ? body.level : null,
|
||||
@@ -177,7 +203,9 @@ export async function POST(request: NextRequest) {
|
||||
servers: finalServers,
|
||||
tags: parseList(body?.tags),
|
||||
description:
|
||||
typeof body?.description === "string" ? body.description.trim() || null : null,
|
||||
typeof body?.description === "string"
|
||||
? body.description.trim() || null
|
||||
: null,
|
||||
metadata,
|
||||
source_table_name: category,
|
||||
source_table_id: sqliteId,
|
||||
@@ -188,7 +216,7 @@ export async function POST(request: NextRequest) {
|
||||
success: true,
|
||||
item,
|
||||
},
|
||||
{ status: 201 }
|
||||
{ status: 201 },
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.error("[admin/items][POST] erro", error?.message);
|
||||
@@ -198,7 +226,7 @@ export async function POST(request: NextRequest) {
|
||||
error: "Falha ao criar item",
|
||||
message: error?.message || "Erro desconhecido",
|
||||
},
|
||||
{ status: 500 }
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -216,7 +244,7 @@ export async function PUT(request: NextRequest) {
|
||||
if (!Number.isFinite(id) || id <= 0) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: "ID inválido." },
|
||||
{ status: 400 }
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -224,44 +252,67 @@ export async function PUT(request: NextRequest) {
|
||||
if (!existing) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: "Item não encontrado." },
|
||||
{ status: 404 }
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const category = (typeof body?.category === "string" ? body.category.trim().toLowerCase() : existing.category) ?? existing.category;
|
||||
const category =
|
||||
(typeof body?.category === "string"
|
||||
? body.category.trim().toLowerCase()
|
||||
: existing.category) ?? existing.category;
|
||||
if (category !== existing.category) {
|
||||
return NextResponse.json(
|
||||
{ success: false, error: "Alterar a categoria de um item não é suportado." },
|
||||
{ status: 400 }
|
||||
{
|
||||
success: false,
|
||||
error: "Alterar a categoria de um item não é suportado.",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const dynamicFields = normalizeDynamicFields(category, body?.fields);
|
||||
|
||||
const imageUrl = typeof body?.imageUrl === "string" ? body.imageUrl.trim() : undefined;
|
||||
const imageUrl =
|
||||
typeof body?.imageUrl === "string" ? body.imageUrl.trim() : undefined;
|
||||
const imageLocalPath =
|
||||
typeof body?.imageLocalPath === "string" ? body.imageLocalPath.trim() : undefined;
|
||||
typeof body?.imageLocalPath === "string"
|
||||
? body.imageLocalPath.trim()
|
||||
: undefined;
|
||||
|
||||
if (existing.source_table_id && existing.source_table_name) {
|
||||
const sqliteData: Record<string, unknown> = {
|
||||
nome: typeof body?.name === "string" ? body.name.trim() : existing.item_name,
|
||||
nome:
|
||||
typeof body?.name === "string"
|
||||
? body.name.trim()
|
||||
: existing.item_name,
|
||||
};
|
||||
|
||||
if (imageUrl !== undefined) sqliteData.image_url = imageUrl;
|
||||
else sqliteData.image_url = existing.image_url;
|
||||
|
||||
if (imageLocalPath !== undefined) sqliteData.image_local_path = imageLocalPath;
|
||||
if (imageLocalPath !== undefined)
|
||||
sqliteData.image_local_path = imageLocalPath;
|
||||
else sqliteData.image_local_path = existing.image_local_path;
|
||||
|
||||
for (const [key, value] of Object.entries(dynamicFields)) {
|
||||
sqliteData[key] = value;
|
||||
}
|
||||
|
||||
updateCategoryItem(existing.source_table_name, existing.source_table_id, sqliteData);
|
||||
updateCategoryItem(
|
||||
existing.source_table_name,
|
||||
existing.source_table_id,
|
||||
sqliteData,
|
||||
);
|
||||
}
|
||||
|
||||
const metadataBase = typeof body?.metadata === "object" && body.metadata !== null ? body.metadata : existing.metadata;
|
||||
const metadata = { ...metadataBase, ...dynamicFields } as Record<string, unknown>;
|
||||
const metadataBase =
|
||||
typeof body?.metadata === "object" && body.metadata !== null
|
||||
? body.metadata
|
||||
: existing.metadata;
|
||||
const metadata = { ...metadataBase, ...dynamicFields } as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
|
||||
const item = await updateAdminItem(id, {
|
||||
item_name: typeof body?.name === "string" ? body.name.trim() : undefined,
|
||||
@@ -279,8 +330,8 @@ export async function PUT(request: NextRequest) {
|
||||
typeof body?.description === "string"
|
||||
? body.description.trim()
|
||||
: body?.description === null
|
||||
? null
|
||||
: undefined,
|
||||
? null
|
||||
: undefined,
|
||||
metadata,
|
||||
});
|
||||
|
||||
@@ -289,7 +340,7 @@ export async function PUT(request: NextRequest) {
|
||||
success: true,
|
||||
item,
|
||||
},
|
||||
{ status: 200 }
|
||||
{ status: 200 },
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.error("[admin/items][PUT] erro", error?.message);
|
||||
@@ -299,8 +350,7 @@ export async function PUT(request: NextRequest) {
|
||||
error: "Falha ao atualizar item",
|
||||
message: error?.message || "Erro desconhecido",
|
||||
},
|
||||
{ status: 500 }
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user