fix: Database sync for emergency order placement
CRITICAL FIX (Dec 9, 2025): Emergency place-exit-orders endpoint now updates database with on-chain order transaction signatures. Problem: - Emergency endpoint placed orders on-chain successfully - But database Trade record showed NULL for order tx fields - Monitoring tools showed false negatives (NULL when orders exist) - User frustrated: 'our database HAS TO reflect whats on chain' Root Cause: - place-exit-orders endpoint called placeExitOrders() directly - Successfully placed orders and returned signatures - But never updated database Trade table with returned tx IDs - Database out of sync with actual on-chain state Solution: - After successful order placement, query database for active trade - Update Trade.tp1OrderTx, tp2OrderTx, slOrderTx with returned signatures - Handle both single SL and dual stop configurations - Log each signature update for verification - Don't fail request if database update fails (orders already on-chain) Impact: - Database now accurately reflects on-chain order state - Monitoring tools (health checks, queries) show correct status - User can trust database as source of truth - Resolves disconnect between user's Drift UI observations and database Testing: - Called endpoint with SOL-PERP position parameters - Received 2 signatures (TP1, TP2) - Bug #76 still present - Database updated: tp1OrderTx and tp2OrderTx now populated - Logs confirm: 'Database updated with on-chain order signatures' Note: Bug #76 (SL order fails silently) still exists but database now accurately reflects whatever orders succeed. Files changed: - app/api/trading/place-exit-orders/route.ts (added database update logic)
This commit is contained in:
@@ -61,10 +61,71 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
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'
|
||||
message: 'Exit orders placed on-chain and database updated'
|
||||
})
|
||||
} else {
|
||||
console.error('❌ Failed to place exit orders:', result.error)
|
||||
|
||||
Reference in New Issue
Block a user