import { PrismaClient } from '@b2bcall/database'; import { logger } from './logger'; // Ativa callbacks agendados (agente.md seção 41) cujo horário chegou. O // lead fica em status CALLBACK enquanto aguarda (não elegível para // discagem — ver lead-repository.ts, que só reserva READY/BUSY/NO_ANSWER/ // FAILED); ao vencer, volta para READY com next_attempt_at = agora, mesmo // caminho de qualquer retry normal. "completed" aqui significa "já foi // reenfileirado para discagem", não "a ligação de retorno aconteceu" — isso // é registrado depois via nova disposição, como qualquer outra tentativa. export async function activateDueCallbacks(prisma: PrismaClient): Promise { const due = await prisma.callback.findMany({ where: { completed: false, scheduledAt: { lte: new Date() } }, }); if (due.length === 0) return 0; for (const callback of due) { await prisma.$transaction([ prisma.lead.updateMany({ where: { id: callback.leadId, status: 'CALLBACK' }, data: { status: 'READY', nextAttemptAt: new Date() }, }), prisma.callback.update({ where: { id: callback.id }, data: { completed: true } }), ]); } logger.info({ count: due.length }, 'Callbacks vencidos reativados para discagem'); return due.length; }