| import { NextResponse } from 'next/server' |
| import { sendCustomEvent, isTorqueConfigured, sendTelegramAlert } from '@/lib/torque-mcp' |
| import { pushEvent } from '@/lib/event-store' |
| import { recordIntervention } from '@/lib/attribution-store' |
|
|
| interface BulkTarget { wallet: string; eventName: string; risk?: string; score?: number } |
|
|
| export async function POST(req: Request) { |
| const body = await req.json() |
| const { targets }: { targets: BulkTarget[] } = body |
|
|
| if (!Array.isArray(targets) || targets.length === 0) { |
| return NextResponse.json({ error: 'targets array required' }, { status: 400 }) |
| } |
| if (!isTorqueConfigured()) { |
| return NextResponse.json({ error: 'TORQUE_INGEST_KEY not configured' }, { status: 503 }) |
| } |
|
|
| const results = await Promise.allSettled( |
| targets.map(async (t) => { |
| const result = await sendCustomEvent(t.wallet, t.eventName, { |
| risk: t.risk, |
| score: t.score, |
| detectedBy: 'flowstate-bulk-rescue', |
| timestamp: new Date().toISOString(), |
| }) |
| if (result.success && result.eventId) { |
| pushEvent({ |
| ingestionId: result.eventId, |
| wallet: t.wallet, |
| eventName: t.eventName, |
| risk: t.risk, |
| score: t.score, |
| firedAt: new Date().toISOString(), |
| source: 'manual', |
| }) |
| if (t.score) recordIntervention(t.wallet, t.eventName, t.score) |
| } |
| return { wallet: t.wallet, success: result.success, eventId: result.eventId, error: result.error } |
| }) |
| ) |
|
|
| const fired = results.filter(r => r.status === 'fulfilled' && (r.value as any).success).length |
| const details = results.map(r => r.status === 'fulfilled' ? r.value : { success: false, error: String((r as any).reason) }) |
|
|
| |
| if (targets.length >= 5) { |
| const confirmedIds = details |
| .filter((d: any) => d.success && d.eventId) |
| .map((d: any) => d.eventId.slice(0, 8)) |
| .slice(0, 3) |
| .join(', ') |
| await sendTelegramAlert( |
| `π¨ Bulk Rescue fired β ${targets.length} critical wallets\n` + |
| `β
${fired}/${targets.length} Torque events confirmed\n` + |
| `π IDs: ${confirmedIds}${fired > 3 ? '...' : ''}` |
| ) |
| } |
|
|
| return NextResponse.json({ fired, total: targets.length, details }) |
| } |
|
|