import { NextRequest, NextResponse } from "next/server"; import { secureLogger } from "@/lib/secure-logger"; import { requireAuth, optionalAuth } from "@/lib/auth/middleware"; import { getListingById, updateListing, deleteListing, } from "@/lib/prisma/queries/listings"; import { updateListingSchema } from "@/lib/validation-schemas"; /** * GET /api/listings/[id] * Busca anúncio por ID */ export async function GET( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params; const listingId = parseInt(id, 10); if (isNaN(listingId)) { return NextResponse.json( { success: false, error: "ID de anúncio inválido", }, { status: 400 } ); } const listing = await getListingById(listingId); if (!listing) { return NextResponse.json( { success: false, error: "Anúncio não encontrado", }, { status: 404 } ); } return NextResponse.json( { success: true, listing, }, { status: 200 } ); } catch (error) { secureLogger.error("❌ Erro ao buscar anúncio", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao buscar anúncio", }, { status: 500 } ); } } /** * PATCH /api/listings/[id] * Atualiza anúncio (apenas dono) */ export async function PATCH( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { // Autenticação obrigatória 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)) { return NextResponse.json( { success: false, error: "ID de anúncio inválido", }, { status: 400 } ); } // Verificar se o anúncio existe e pertence ao usuário const listing = await getListingById(listingId); if (!listing) { return NextResponse.json( { success: false, error: "Anúncio não encontrado", }, { status: 404 } ); } if (listing.seller_id !== auth.userId) { return NextResponse.json( { success: false, error: "Você não tem permissão para editar este anúncio", }, { status: 403 } ); } const body = await request.json(); // Validação com Zod const validationResult = updateListingSchema.safeParse(body); if (!validationResult.success) { const errors = validationResult.error.issues.map((err) => ({ field: err.path.join("."), message: err.message, })); return NextResponse.json( { success: false, error: "Dados de entrada inválidos", details: errors, }, { status: 400 } ); } const validatedData = validationResult.data; // Atualizar anúncio const updatedListing = await updateListing(listingId, validatedData); if (!updatedListing) { return NextResponse.json( { success: false, error: "Erro ao atualizar anúncio", }, { status: 500 } ); } secureLogger.info("✅ Anúncio atualizado com sucesso", { listingId, userId: auth.userId, timestamp: new Date().toISOString(), }); return NextResponse.json( { success: true, listing: updatedListing, }, { status: 200 } ); } catch (error) { secureLogger.error("❌ Erro ao atualizar anúncio", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao atualizar anúncio", }, { status: 500 } ); } } /** * DELETE /api/listings/[id] * Cancela anúncio (apenas dono) */ export async function DELETE( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { // Autenticação obrigatória 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)) { return NextResponse.json( { success: false, error: "ID de anúncio inválido", }, { status: 400 } ); } // Verificar se o anúncio existe e pertence ao usuário const listing = await getListingById(listingId); if (!listing) { return NextResponse.json( { success: false, error: "Anúncio não encontrado", }, { status: 404 } ); } if (listing.seller_id !== auth.userId) { return NextResponse.json( { success: false, error: "Você não tem permissão para cancelar este anúncio", }, { status: 403 } ); } // Cancelar anúncio (soft delete) const deleted = await deleteListing(listingId); if (!deleted) { return NextResponse.json( { success: false, error: "Erro ao cancelar anúncio", }, { status: 500 } ); } secureLogger.info("✅ Anúncio cancelado com sucesso", { listingId, userId: auth.userId, timestamp: new Date().toISOString(), }); return NextResponse.json( { success: true, message: "Anúncio cancelado com sucesso", }, { status: 200 } ); } catch (error) { secureLogger.error("❌ Erro ao cancelar anúncio", { error: error instanceof Error ? error.message : "Erro desconhecido", stack: error instanceof Error ? error.stack : undefined, }); return NextResponse.json( { success: false, error: "Erro ao cancelar anúncio", }, { status: 500 } ); } }