import { NextRequest, NextResponse } from 'next/server' import { placeExitOrders } from '@/lib/drift/orders' /** * Emergency endpoint to manually place exit orders * Use when orders vanish but position still exists */ export async function POST(req: NextRequest) { try { // Auth check const authHeader = req.headers.get('authorization') const apiSecret = process.env.API_SECRET_KEY if (!authHeader || !apiSecret || !authHeader.includes(apiSecret)) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const body = await req.json() const { symbol, direction, entryPrice, tp1Price, tp2Price, slPrice, positionSizeUSD, tp1SizePercent = 75, tp2SizePercent = 0, } = body // Validate required fields if (!symbol || !direction || !entryPrice || !tp1Price || !tp2Price || !slPrice || !positionSizeUSD) { return NextResponse.json({ success: false, error: 'Missing required fields' }, { status: 400 }) } console.log('🛡️ Manually placing exit orders for existing position...') console.log(` ${symbol} ${direction} @ $${entryPrice}`) console.log(` TP1: $${tp1Price} (${tp1SizePercent}%)`) console.log(` TP2: $${tp2Price} (${tp2SizePercent}%)`) console.log(` SL: $${slPrice}`) // Initialize Drift service BEFORE calling placeExitOrders const { initializeDriftService } = await import('@/lib/drift/client') await initializeDriftService() console.log('✅ Drift service ready for order placement') const result = await placeExitOrders({ symbol, direction, entryPrice, tp1Price, tp2Price, stopLossPrice: slPrice, positionSizeUSD, tp1SizePercent, tp2SizePercent, }) if (result.success) { console.log('✅ Exit orders placed successfully!') console.log(` Signatures: ${result.signatures?.length || 0} orders placed`) // CRITICAL FIX (Dec 9, 2025): Update database with on-chain order signatures // Without this, database shows NULL even when orders exist on Drift try { const { getPrismaClient } = await import('@/lib/database/trades') const prisma = getPrismaClient() // Find the active trade for this symbol const trade = await prisma.trade.findFirst({ where: { symbol, exitReason: null, // Still open }, orderBy: { createdAt: 'desc', }, }) if (trade) { console.log(`💾 Updating database Trade ${trade.id} with order signatures...`) // Update with all returned signatures // placeExitOrders returns: [tp1Sig, tp2Sig, slSig] or [tp1Sig, tp2Sig, softSlSig, hardSlSig] const updateData: any = {} if (result.signatures && result.signatures.length >= 2) { updateData.tp1OrderTx = result.signatures[0] updateData.tp2OrderTx = result.signatures[1] console.log(` TP1 tx: ${result.signatures[0].substring(0, 8)}...`) console.log(` TP2 tx: ${result.signatures[1].substring(0, 8)}...`) } if (result.signatures && result.signatures.length >= 3) { updateData.slOrderTx = result.signatures[2] console.log(` SL tx: ${result.signatures[2].substring(0, 8)}...`) } if (result.signatures && result.signatures.length >= 4) { // Dual stops: soft (index 2) and hard (index 3) updateData.softStopOrderTx = result.signatures[2] updateData.hardStopOrderTx = result.signatures[3] updateData.slOrderTx = null // Clear single SL when dual stops used console.log(` Soft SL tx: ${result.signatures[2].substring(0, 8)}...`) console.log(` Hard SL tx: ${result.signatures[3].substring(0, 8)}...`) } await prisma.trade.update({ where: { id: trade.id }, data: updateData, }) console.log('✅ Database updated with on-chain order signatures') } else { console.warn('⚠️ No active trade found for symbol, skipping database update') } } catch (dbError) { console.error('❌ Failed to update database with order signatures:', dbError) // Don't fail the request - orders are already placed on-chain } return NextResponse.json({ success: true, signatures: result.signatures, message: 'Exit orders placed on-chain and database updated' }) } else { console.error('❌ Failed to place exit orders:', result.error) return NextResponse.json({ success: false, error: result.error }, { status: 500 }) } } catch (error) { console.error('❌ Error in place-exit-orders:', error) return NextResponse.json({ success: false, error: error instanceof Error ? error.message : 'Unknown error' }, { status: 500 }) } }