diff --git a/app/api/donations/create/route.ts b/app/api/donations/create/route.ts index 3f74fad..9ad5208 100644 --- a/app/api/donations/create/route.ts +++ b/app/api/donations/create/route.ts @@ -21,6 +21,13 @@ export async function POST(request: NextRequest) { const body = await request.json(); + // Log detalhado para debug em produção + secureLogger.info("📥 POST /api/donations/create - Recebido", { + ip, + body: JSON.stringify(body), + timestamp: new Date().toISOString(), + }); + // Validação com Zod const validationResult = createDonationSchema.safeParse(body); @@ -30,6 +37,12 @@ export async function POST(request: NextRequest) { message: err.message, })); + secureLogger.error("❌ Validação falhou", { + body: JSON.stringify(body), + errors: JSON.stringify(errors), + timestamp: new Date().toISOString(), + }); + return NextResponse.json( { success: false, @@ -42,6 +55,13 @@ export async function POST(request: NextRequest) { const validatedData = validationResult.data; + secureLogger.info("✅ Validação passou", { + tier: validatedData.tier, + anonymous: validatedData.anonymous, + customAmount: validatedData.customAmount, + timestamp: new Date().toISOString(), + }); + const product = DONATION_PRODUCTS[validatedData.tier as keyof typeof DONATION_PRODUCTS]; @@ -55,9 +75,21 @@ export async function POST(request: NextRequest) { finalDescription = `Doação Personalizada - R$ ${validatedData.customAmount!.toFixed( 2 )}`; + + secureLogger.info("💰 Valor customizado calculado", { + valor_original: validatedData.customAmount, + valor_centavos: finalAmount, + description: finalDescription, + }); } else { finalAmount = product.price; finalDescription = product.name; + + secureLogger.info("💰 Valor fixo", { + tier: validatedData.tier, + amount: product.amount, + price_centavos: finalAmount, + }); } let pixData; @@ -103,15 +135,27 @@ export async function POST(request: NextRequest) { }); } - return NextResponse.json({ + const response = { success: true, pixId: pixData.id, brCode: pixData.brCode, brCodeBase64: pixData.brCodeBase64, expiresAt: pixData.expiresAt, + }; + + secureLogger.info("✅ PIX criado com sucesso", { + pixId: pixData.id, + expiresAt: pixData.expiresAt, }); + + return NextResponse.json(response); } catch (error) { - secureLogger.error("Donation creation error", error); + secureLogger.error("❌ Erro ao criar doação", { + error: error instanceof Error ? error.message : "Erro desconhecido", + stack: error instanceof Error ? error.stack : undefined, + timestamp: new Date().toISOString(), + }); + return NextResponse.json( { success: false, diff --git a/lib/secure-logger.ts b/lib/secure-logger.ts index 0ed0757..890757d 100644 --- a/lib/secure-logger.ts +++ b/lib/secure-logger.ts @@ -155,9 +155,10 @@ function maskSensitiveData(obj: any, options: MaskOptions = {}): any { export const secureLogger = { /** * Log info com mascaramento automático + * SEMPRE exibe em produção para debug */ info(message: string, data?: any) { - if (isProduction && data) { + if (data) { const masked = maskSensitiveData(data, { maskEmail: true, maskDocument: true, @@ -165,15 +166,16 @@ export const secureLogger = { }); console.log(`ℹ️ ${message}`, JSON.stringify(masked, null, 2)); } else { - console.log(`ℹ️ ${message}`, data ? JSON.stringify(data, null, 2) : ""); + console.log(`ℹ️ ${message}`, ""); } }, /** * Log debug com mascaramento automático + * SEMPRE exibe em produção para debug */ debug(message: string, data?: any) { - if (isProduction && data) { + if (data) { const masked = maskSensitiveData(data, { maskEmail: true, maskDocument: true, @@ -181,7 +183,7 @@ export const secureLogger = { }); console.debug(`🔍 ${message}`, JSON.stringify(masked, null, 2)); } else { - console.debug(`🔍 ${message}`, data ? JSON.stringify(data, null, 2) : ""); + console.debug(`🔍 ${message}`, ""); } }, diff --git a/lib/validation-schemas.ts b/lib/validation-schemas.ts index 5792821..025c689 100644 --- a/lib/validation-schemas.ts +++ b/lib/validation-schemas.ts @@ -76,7 +76,7 @@ export const donationTierSchema = z.enum( export const customAmountSchema = z .number() .min(5, "Valor mínimo é R$ 5,00") - .max(500, "Valor máximo é R$ 500,00"); + .max(100000, "Valor máximo é R$ 100.000,00"); // Schema completo para criação de doação export const createDonationSchema = z @@ -116,12 +116,12 @@ export const createDonationSchema = z (data) => { // Se tier for custom, customAmount deve estar no range válido if (data.tier === "custom" && data.customAmount) { - return data.customAmount >= 5 && data.customAmount <= 500; + return data.customAmount >= 5 && data.customAmount <= 100000; } return true; }, { - message: "Valor deve estar entre R$ 5,00 e R$ 500,00", + message: "Valor deve estar entre R$ 5,00 e R$ 100.000,00", path: ["customAmount"], } ); diff --git a/types/donation.ts b/types/donation.ts index fcd4aa4..36c1db3 100644 --- a/types/donation.ts +++ b/types/donation.ts @@ -39,8 +39,8 @@ export const DONATION_PRODUCTS = { name: "Valor Personalizado", amount: 0, price: 0, - minAmount: 1, // R$ 1,00 - maxAmount: 10000, // R$ 10.000,00 + minAmount: 5, // R$ 5,00 + maxAmount: 100000, // R$ 100.000,00 }, } as const;