style: clean up code formatting and remove trailing whitespace

refactor: reorganize imports and fix type imports
This commit is contained in:
Evandro Fonseca Junior committed 2025-11-11 03:08:36 -03:00
1 parent d3704602fd
commit 47c04de6fe
232 files changed
+7140 -4798

No files matched your search

@@ -1,17 +1,17 @@
import { NextRequest, NextResponse } from "next/server";
import { secureLogger } from "@/lib/secure-logger";
import { type NextRequest, NextResponse } from "next/server";
import { requireAuth } from "@/lib/auth/middleware";
import { connectMongoDB } from "@/lib/mongodb/connection";
import { Chat } from "@/lib/mongodb/models/Chat";
import { Message } from "@/lib/mongodb/models/Message";
import { getMainCharacter } from "@/lib/prisma/queries/characters";
import { getListingById } from "@/lib/prisma/queries/listings";
import { createNotification } from "@/lib/prisma/queries/notifications";
import {
getPurchaseIntentionById,
updatePurchaseIntentionStatus,
} from "@/lib/prisma/queries/purchase-intentions";
import { createNotification } from "@/lib/prisma/queries/notifications";
import { connectMongoDB } from "@/lib/mongodb/connection";
import { Chat } from "@/lib/mongodb/models/Chat";
import { Message } from "@/lib/mongodb/models/Message";
import { getUserById } from "@/lib/prisma/queries/users";
import { getMainCharacter } from "@/lib/prisma/queries/characters";
import { secureLogger } from "@/lib/secure-logger";
/**
* GET /api/listings/[id]/intentions/[intentionId]
@@ -19,7 +19,7 @@ import { getMainCharacter } from "@/lib/prisma/queries/characters";
*/
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string; intentionId: string }> }
{ params }: { params: Promise<{ id: string; intentionId: string }> },
) {
try {
const authResult = await requireAuth(request);
@@ -27,10 +27,10 @@ export async function GET(
const { intentionId: intentionIdParam } = await params;
const intentionId = parseInt(intentionIdParam, 10);
if (isNaN(intentionId)) {
if (Number.isNaN(intentionId)) {
return NextResponse.json(
{ success: false, error: "ID de intenção inválido" },
{ status: 400 }
{ status: 400 },
);
}
@@ -38,15 +38,21 @@ export async function GET(
if (!intention) {
return NextResponse.json(
{ success: false, error: "Intenção não encontrada" },
{ status: 404 }
{ status: 404 },
);
}
// Verificar permissões: vendedor ou comprador
if (intention.listing?.seller_id !== authResult.userId && intention.buyer_id !== authResult.userId) {
if (
intention.listing?.seller_id !== authResult.userId &&
intention.buyer_id !== authResult.userId
) {
return NextResponse.json(
{ success: false, error: "Você não tem permissão para ver esta intenção" },
{ status: 403 }
{
success: false,
error: "Você não tem permissão para ver esta intenção",
},
{ status: 403 },
);
}
@@ -55,7 +61,7 @@ export async function GET(
success: true,
intention,
},
{ status: 200 }
{ status: 200 },
);
} catch (error) {
secureLogger.error("❌ Erro ao buscar intenção", {
@@ -65,7 +71,7 @@ export async function GET(
return NextResponse.json(
{ success: false, error: "Erro ao buscar intenção" },
{ status: 500 }
{ status: 500 },
);
}
}
@@ -76,7 +82,7 @@ export async function GET(
*/
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ id: string; intentionId: string }> }
{ params }: { params: Promise<{ id: string; intentionId: string }> },
) {
try {
const authResult = await requireAuth(request);
@@ -84,10 +90,10 @@ export async function PATCH(
const { intentionId: intentionIdParam } = await params;
const intentionId = parseInt(intentionIdParam, 10);
if (isNaN(intentionId)) {
if (Number.isNaN(intentionId)) {
return NextResponse.json(
{ success: false, error: "ID de intenção inválido" },
{ status: 400 }
{ status: 400 },
);
}
@@ -100,8 +106,11 @@ export async function PATCH(
if (!status || !["accepted", "rejected"].includes(status)) {
return NextResponse.json(
{ success: false, error: "Status inválido. Use 'accepted' ou 'rejected'" },
{ status: 400 }
{
success: false,
error: "Status inválido. Use 'accepted' ou 'rejected'",
},
{ status: 400 },
);
}
@@ -110,15 +119,18 @@ export async function PATCH(
if (!intention) {
return NextResponse.json(
{ success: false, error: "Intenção não encontrada" },
{ status: 404 }
{ status: 404 },
);
}
// Verificar se o usuário é o vendedor
if (intention.listing?.seller_id !== authResult.userId) {
return NextResponse.json(
{ success: false, error: "Apenas o vendedor pode aceitar ou rejeitar intenções" },
{ status: 403 }
{
success: false,
error: "Apenas o vendedor pode aceitar ou rejeitar intenções",
},
{ status: 403 },
);
}
@@ -126,16 +138,20 @@ export async function PATCH(
if (intention.status !== "pending") {
return NextResponse.json(
{ success: false, error: `Esta intenção já foi ${intention.status}` },
{ status: 400 }
{ status: 400 },
);
}
// Verificar se o anúncio ainda está disponível (ativo ou em escrow)
const listing = await getListingById(intention.listing_id);
if (!listing || (listing.listing_status !== "active" && listing.listing_status !== "in_escrow")) {
if (
!listing ||
(listing.listing_status !== "active" &&
listing.listing_status !== "in_escrow")
) {
return NextResponse.json(
{ success: false, error: "Anúncio não está mais disponível" },
{ status: 400 }
{ status: 400 },
);
}
@@ -143,7 +159,7 @@ export async function PATCH(
const updatedIntention = await updatePurchaseIntentionStatus(
intentionId,
status,
sellerResponse
sellerResponse,
);
await sendSellerResponseToChat({
@@ -159,19 +175,23 @@ export async function PATCH(
user_id: intention.buyer_id,
notification_type: status === "accepted" ? "purchase" : "system",
title: status === "accepted" ? "Intenção aceita!" : "Intenção rejeitada",
message: status === "accepted"
? `O vendedor aceitou sua intenção de compra do item "${intention.listing?.item_name}"`
: `O vendedor rejeitou sua intenção de compra do item "${intention.listing?.item_name}"`,
message:
status === "accepted"
? `O vendedor aceitou sua intenção de compra do item "${intention.listing?.item_name}"`
: `O vendedor rejeitou sua intenção de compra do item "${intention.listing?.item_name}"`,
related_id: intention.listing_id,
send_whatsapp: false,
});
secureLogger.info(`✅ Intenção ${status === "accepted" ? "aceita" : "rejeitada"}`, {
userId: authResult.userId,
intentionId,
listingId: intention.listing_id,
buyerId: intention.buyer_id,
});
secureLogger.info(
`✅ Intenção ${status === "accepted" ? "aceita" : "rejeitada"}`,
{
userId: authResult.userId,
intentionId,
listingId: intention.listing_id,
buyerId: intention.buyer_id,
},
);
return NextResponse.json(
{
@@ -179,7 +199,7 @@ export async function PATCH(
intention: updatedIntention,
message: `Intenção ${status === "accepted" ? "aceita" : "rejeitada"} com sucesso`,
},
{ status: 200 }
{ status: 200 },
);
} catch (error) {
secureLogger.error("❌ Erro ao atualizar intenção", {
@@ -189,7 +209,7 @@ export async function PATCH(
return NextResponse.json(
{ success: false, error: "Erro ao atualizar intenção" },
{ status: 500 }
{ status: 500 },
);
}
}
@@ -202,7 +222,10 @@ async function sendSellerResponseToChat({
sellerId,
}: {
listing: Awaited<ReturnType<typeof getListingById>>;
intention: Exclude<Awaited<ReturnType<typeof getPurchaseIntentionById>>, null>;
intention: Exclude<
Awaited<ReturnType<typeof getPurchaseIntentionById>>,
null
>;
status: "accepted" | "rejected";
sellerResponse?: string;
sellerId: number;
@@ -225,12 +248,13 @@ async function sendSellerResponseToChat({
let chat = await Chat.findOne({ chat_id: chatId });
if (!chat) {
const [buyer, seller, buyerCharacter, sellerCharacter] = await Promise.all([
getUserById(intention.buyer_id),
getUserById(listing.seller_id),
getMainCharacter(intention.buyer_id),
getMainCharacter(listing.seller_id),
]);
const [buyer, seller, buyerCharacter, sellerCharacter] =
await Promise.all([
getUserById(intention.buyer_id),
getUserById(listing.seller_id),
getMainCharacter(intention.buyer_id),
getMainCharacter(listing.seller_id),
]);
chat = new Chat({
chat_id: chatId,
@@ -284,4 +308,3 @@ async function sendSellerResponseToChat({
});
}
}
+67 -43
View File
@@ -1,15 +1,14 @@
import { NextRequest, NextResponse } from "next/server";
import { secureLogger } from "@/lib/secure-logger";
import { type NextRequest, NextResponse } from "next/server";
import { requireAuth } from "@/lib/auth/middleware";
import { getListingById } from "@/lib/prisma/queries/listings";
import { createNotification } from "@/lib/prisma/queries/notifications";
import {
createPurchaseIntention,
getPurchaseIntentionsByListing,
hasPendingIntention,
getPendingIntentionByBuyerAndListing,
getPurchaseIntentionsByListing,
} from "@/lib/prisma/queries/purchase-intentions";
import { createNotification } from "@/lib/prisma/queries/notifications";
import { trackEvent } from "@/lib/prisma/queries/telemetry";
import { secureLogger } from "@/lib/secure-logger";
/**
* POST /api/listings/[id]/intentions
@@ -17,7 +16,7 @@ import { trackEvent } from "@/lib/prisma/queries/telemetry";
*/
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
{ params }: { params: Promise<{ id: string }> },
) {
try {
const authResult = await requireAuth(request);
@@ -26,10 +25,10 @@ export async function POST(
const { id } = await params;
const listingId = parseInt(id, 10);
if (isNaN(listingId)) {
if (Number.isNaN(listingId)) {
return NextResponse.json(
{ success: false, error: "ID de anúncio inválido" },
{ status: 400 }
{ status: 400 },
);
}
@@ -41,10 +40,13 @@ export async function POST(
custom_offer_currency,
} = body;
if (!payment_method || !["pix", "tibia_coins", "gold_coins", "trade"].includes(payment_method)) {
if (
!payment_method ||
!["pix", "tibia_coins", "gold_coins", "trade"].includes(payment_method)
) {
return NextResponse.json(
{ success: false, error: "Método de pagamento inválido" },
{ status: 400 }
{ status: 400 },
);
}
@@ -53,15 +55,19 @@ export async function POST(
if (!listing) {
return NextResponse.json(
{ success: false, error: "Anúncio não encontrado" },
{ status: 404 }
{ status: 404 },
);
}
// Validar se não é o vendedor
if (listing.seller_id === auth.userId) {
return NextResponse.json(
{ success: false, error: "Você não pode criar uma intenção de compra para seu próprio anúncio" },
{ status: 403 }
{
success: false,
error:
"Você não pode criar uma intenção de compra para seu próprio anúncio",
},
{ status: 403 },
);
}
@@ -69,15 +75,18 @@ export async function POST(
if (listing.listing_status !== "active") {
return NextResponse.json(
{ success: false, error: "Anúncio não está disponível para compra" },
{ status: 400 }
{ status: 400 },
);
}
// Validar se é leilão (leilões não podem ter intenções, apenas lances)
if (listing.is_auction) {
return NextResponse.json(
{ success: false, error: "Este item está em leilão. Use a funcionalidade de lance." },
{ status: 400 }
{
success: false,
error: "Este item está em leilão. Use a funcionalidade de lance.",
},
{ status: 400 },
);
}
@@ -95,7 +104,7 @@ export async function POST(
error: `Método de pagamento "${payment_method}" não está disponível para este anúncio`,
available_methods: availableMethods,
},
{ status: 400 }
{ status: 400 },
);
}
@@ -107,9 +116,10 @@ export async function POST(
return NextResponse.json(
{
success: false,
error: "Ofertas personalizadas só são permitidas para métodos monetários (PIX, Tibia Coins ou Gold Coins).",
error:
"Ofertas personalizadas só são permitidas para métodos monetários (PIX, Tibia Coins ou Gold Coins).",
},
{ status: 400 }
{ status: 400 },
);
}
@@ -118,14 +128,16 @@ export async function POST(
return NextResponse.json(
{
success: false,
error: "Valor da oferta personalizada deve ser numérico e maior que zero.",
error:
"Valor da oferta personalizada deve ser numérico e maior que zero.",
},
{ status: 400 }
{ status: 400 },
);
}
normalizedOfferCurrency =
custom_offer_currency && ["pix", "tibia_coins", "gold_coins"].includes(custom_offer_currency)
custom_offer_currency &&
["pix", "tibia_coins", "gold_coins"].includes(custom_offer_currency)
? custom_offer_currency
: payment_method;
@@ -136,7 +148,10 @@ export async function POST(
}
// Verificar se já existe uma intenção pendente
const existingIntention = await getPendingIntentionByBuyerAndListing(listingId, auth.userId);
const existingIntention = await getPendingIntentionByBuyerAndListing(
listingId,
auth.userId,
);
if (existingIntention) {
// Se já existe e ainda pode trocar o método
if (existingIntention.payment_method_change_count < 1) {
@@ -144,23 +159,27 @@ export async function POST(
return NextResponse.json(
{
success: false,
error: "Você já possui uma intenção de compra pendente para este anúncio",
error:
"Você já possui uma intenção de compra pendente para este anúncio",
existing_intention_id: existingIntention.intention_id,
can_change_payment_method: true,
payment_method_change_count: existingIntention.payment_method_change_count,
message: "Use o endpoint PATCH /api/purchase-intentions/[intentionId]/payment-method para trocar o método de pagamento",
payment_method_change_count:
existingIntention.payment_method_change_count,
message:
"Use o endpoint PATCH /api/purchase-intentions/[intentionId]/payment-method para trocar o método de pagamento",
},
{ status: 400 }
{ status: 400 },
);
} else {
// Já atingiu o limite de trocas
return NextResponse.json(
{
success: false,
error: "Você já possui uma intenção de compra pendente para este anúncio e atingiu o limite de trocas de método de pagamento",
error:
"Você já possui uma intenção de compra pendente para este anúncio e atingiu o limite de trocas de método de pagamento",
existing_intention_id: existingIntention.intention_id,
},
{ status: 400 }
{ status: 400 },
);
}
}
@@ -197,7 +216,9 @@ export async function POST(
payment_method,
listing_price_pix: listing.price_pix ? Number(listing.price_pix) : null,
listing_price_tc: listing.price_tibia_coins || null,
listing_price_gp: listing.price_gold_coins ? Number(listing.price_gold_coins) : null,
listing_price_gp: listing.price_gold_coins
? Number(listing.price_gold_coins)
: null,
custom_offer_amount: normalizedOfferValue,
custom_offer_currency: normalizedOfferCurrency,
},
@@ -214,9 +235,10 @@ export async function POST(
{
success: true,
intention,
message: "Intenção de compra criada com sucesso. O vendedor será notificado.",
message:
"Intenção de compra criada com sucesso. O vendedor será notificado.",
},
{ status: 201 }
{ status: 201 },
);
} catch (error) {
secureLogger.error("❌ Erro ao criar intenção de compra", {
@@ -226,7 +248,7 @@ export async function POST(
return NextResponse.json(
{ success: false, error: "Erro ao criar intenção de compra" },
{ status: 500 }
{ status: 500 },
);
}
}
@@ -237,19 +259,19 @@ export async function POST(
*/
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
{ params }: { params: Promise<{ id: string }> },
) {
try {
const authResult = await requireAuth(request);
if (authResult instanceof NextResponse) return authResult;
const auth = authResult;
const { id } = await params;
const listingId = parseInt(id, 10);
if (isNaN(listingId)) {
if (Number.isNaN(listingId)) {
return NextResponse.json(
{ success: false, error: "ID de anúncio inválido" },
{ status: 400 }
{ status: 400 },
);
}
@@ -258,15 +280,18 @@ export async function GET(
if (!listing) {
return NextResponse.json(
{ success: false, error: "Anúncio não encontrado" },
{ status: 404 }
{ status: 404 },
);
}
// Apenas o vendedor pode ver as intenções
if (listing.seller_id !== auth.userId) {
return NextResponse.json(
{ success: false, error: "Você não tem permissão para ver as intenções deste anúncio" },
{ status: 403 }
{
success: false,
error: "Você não tem permissão para ver as intenções deste anúncio",
},
{ status: 403 },
);
}
@@ -297,7 +322,7 @@ export async function GET(
intentions,
count: intentions.length,
},
{ status: 200 }
{ status: 200 },
);
} catch (error) {
secureLogger.error("❌ Erro ao buscar intenções de compra", {
@@ -307,8 +332,7 @@ export async function GET(
return NextResponse.json(
{ success: false, error: "Erro ao buscar intenções de compra" },
{ status: 500 }
{ status: 500 },
);
}
}