/** * Queries de transactions (transações do sistema de escrow) * Operações para a tabela transactions */ import { query } from "../index"; export interface Transaction { transaction_id: number; listing_id: number | null; buyer_id: number; seller_id: number; item_name: string; quantity: number; server_name: string; amount: number; payment_method: "pix" | "tibia_coins" | "gold_coins" | null; escrow_fee: number | null; transaction_status: | "pending" | "deposited" | "item_delivered" | "completed" | "disputed" | "cancelled" | "refunded"; created_at: Date; deposited_at: Date | null; delivered_at: Date | null; completed_at: Date | null; buyer_confirmed: boolean; seller_confirmed: boolean; buyer_notes: string | null; seller_notes: string | null; } export interface CreateTransactionData { listing_id?: number; buyer_id: number; seller_id: number; item_name: string; quantity: number; server_name: string; amount: number; payment_method: "pix" | "tibia_coins" | "gold_coins"; escrow_fee?: number; } export interface UpdateTransactionStatusData { transaction_status: Transaction["transaction_status"]; deposited_at?: Date; delivered_at?: Date; completed_at?: Date; buyer_confirmed?: boolean; seller_confirmed?: boolean; buyer_notes?: string; seller_notes?: string; } /** * Cria uma nova transação */ export async function createTransaction( data: CreateTransactionData, ): Promise { // Calcular escrow_fee se não fornecido (2% do valor) const escrowFee = data.escrow_fee ?? Number((data.amount * 0.02).toFixed(2)); const result = await query( ` INSERT INTO transactions ( listing_id, buyer_id, seller_id, item_name, quantity, server_name, amount, payment_method, escrow_fee ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING * `, [ data.listing_id || null, data.buyer_id, data.seller_id, data.item_name, data.quantity, data.server_name, data.amount, data.payment_method, escrowFee, ], ); return result.rows[0]; } /** * Busca transação por ID */ export async function getTransactionById( transactionId: number, ): Promise { const result = await query( ` SELECT * FROM transactions WHERE transaction_id = $1 `, [transactionId], ); return result.rows[0] || null; } /** * Atualiza status da transação */ export async function updateTransactionStatus( transactionId: number, data: UpdateTransactionStatusData, ): Promise { const updates: string[] = []; const params: any[] = []; let paramIndex = 1; updates.push(`transaction_status = $${paramIndex}`); params.push(data.transaction_status); paramIndex++; if (data.deposited_at !== undefined) { updates.push(`deposited_at = $${paramIndex}`); params.push(data.deposited_at); paramIndex++; } if (data.delivered_at !== undefined) { updates.push(`delivered_at = $${paramIndex}`); params.push(data.delivered_at); paramIndex++; } if (data.completed_at !== undefined) { updates.push(`completed_at = $${paramIndex}`); params.push(data.completed_at); paramIndex++; } if (data.buyer_confirmed !== undefined) { updates.push(`buyer_confirmed = $${paramIndex}`); params.push(data.buyer_confirmed); paramIndex++; } if (data.seller_confirmed !== undefined) { updates.push(`seller_confirmed = $${paramIndex}`); params.push(data.seller_confirmed); paramIndex++; } if (data.buyer_notes !== undefined) { updates.push(`buyer_notes = $${paramIndex}`); params.push(data.buyer_notes); paramIndex++; } if (data.seller_notes !== undefined) { updates.push(`seller_notes = $${paramIndex}`); params.push(data.seller_notes); paramIndex++; } params.push(transactionId); const result = await query( ` UPDATE transactions SET ${updates.join(", ")} WHERE transaction_id = $${paramIndex} RETURNING * `, params, ); return result.rows[0] || null; } /** * Busca transações de um usuário (comprador ou vendedor) */ export async function getTransactionsByUser( userId: number, filters: { role?: "buyer" | "seller" | "both"; status?: Transaction["transaction_status"]; page?: number; pageSize?: number; } = {}, ): Promise<{ transactions: Transaction[]; total: number }> { const { role = "both", status, page = 1, pageSize = 20 } = filters; const conditions: string[] = []; const params: any[] = []; let paramIndex = 1; if (role === "buyer") { conditions.push(`buyer_id = $${paramIndex}`); } else if (role === "seller") { conditions.push(`seller_id = $${paramIndex}`); } else { conditions.push( `(buyer_id = $${paramIndex} OR seller_id = $${paramIndex})`, ); } params.push(userId); paramIndex++; if (status) { conditions.push(`transaction_status = $${paramIndex}`); params.push(status); paramIndex++; } const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : ""; // Contar total const countResult = await query<{ count: string }>( `SELECT COUNT(*) as count FROM transactions ${whereClause}`, params, ); const total = parseInt(countResult.rows[0].count, 10); // Buscar transações const offset = (page - 1) * pageSize; const result = await query( ` SELECT * FROM transactions ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1} `, [...params, pageSize, offset], ); return { transactions: result.rows, total, }; }