Files
clube67_newwhats.local/clube67/newwhats.local/backend/src/infra/temporal/activities.ts
T
VPS 4 Deploy Agent 0dc5eefa06
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
chore(ops): restore missing root files in newwhats.clube67.com
2026-05-18 03:27:25 +02:00

88 lines
2.9 KiB
TypeScript

/**
* Temporal Activities — operações com efeitos colaterais (banco, APIs, I/O).
* Activities são executadas pelo Worker e podem ser re-tentadas automaticamente.
*/
import { prisma } from '../database/prisma'
import { logger } from '../../config/logger'
// ─── Conflito de Agenda: liberar slot após timeout ────────────────────────────
export async function liberarSlotAgenda(input: {
solicitanteId: string
tituloSlot: string
chatIdSolicitante: string
}): Promise<void> {
logger.info(input, '[Temporal] Slot liberado por timeout — notificando solicitante')
// Aqui você envia mensagem via WhatsApp avisando o solicitante
// Implementação real acoplada ao WhatsAppConnectionManager via NATS
// Por ora, marca no banco como disponível
await prisma.protocol.updateMany({
where: {
contactId: input.solicitanteId,
status: 'WAITING_CLIENT',
},
data: { status: 'OPEN' },
})
}
export async function notificarConflito(input: {
chatIdB: string
solicitanteNome: string
tituloSlot: string
}): Promise<void> {
logger.info(input, '[Temporal] Notificando pessoa B sobre solicitação de slot')
// Dispara mensagem via NATS → WhatsApp handler
}
// ─── Gestão de Reputação ──────────────────────────────────────────────────────
export async function decrementarScore(input: {
contactId: string
motivo: string
pontos: number
}): Promise<{ novoScore: number; restrito: boolean }> {
const contact = await prisma.contact.findUnique({
where: { id: input.contactId },
})
if (!contact) throw new Error(`Contato ${input.contactId} não encontrado`)
const novoScore = Math.max(0, contact.scoreReputacao - input.pontos)
const restrito = novoScore <= 20
await prisma.contact.update({
where: { id: input.contactId },
data: {
scoreReputacao: novoScore,
flagRestricao: restrito,
},
})
logger.info({ contactId: input.contactId, novoScore, restrito, motivo: input.motivo },
'[Temporal] Score de reputação atualizado')
return { novoScore, restrito }
}
export async function bloquearAgendamentosAutomaticos(input: {
contactId: string
}): Promise<void> {
await prisma.contact.update({
where: { id: input.contactId },
data: { flagRestricao: true },
})
logger.warn({ contactId: input.contactId },
'[Temporal] Contato marcado como RESTRITO — agendamentos automáticos bloqueados')
}
export async function buscarScoreContato(contactId: string): Promise<{
score: number
restrito: boolean
}> {
const c = await prisma.contact.findUnique({
where: { id: contactId },
select: { scoreReputacao: true, flagRestricao: true },
})
return { score: c?.scoreReputacao ?? 100, restrito: c?.flagRestricao ?? false }
}