const { djb2Hash } = require('./hash'); // Hash estavel do texto exato que seria enviado -- usado como parte da chave de // idempotencia (junto com report_date/run_type). Duas mensagens com o mesmo conteudo no // mesmo dia nunca devem gerar dois envios reais. function computeMessageHash(text) { return djb2Hash(String(text || '')); } // SEND_ENABLED e o unico gate de "isso pode realmente sair pro Slack" -- nunca depende de // editar codigo (missao "finalizacao para producao", secao 22). function shouldSendByConfig(config) { return Boolean(config && config.sendEnabled); } // Idempotencia: so conta como "ja enviado" um registro com status 'success' para a MESMA // data + tipo de execucao + hash de mensagem. Um retry apos falha (status 'failed') nao // bloqueia um novo envio -- so um sucesso anterior bloqueia. function alreadySentSuccessfully(existingRecords, { reportDate, runType, messageHash }) { return (existingRecords || []).some((record) => ( record && record.status === 'success' && record.report_date === reportDate && record.run_type === runType && record.message_hash === messageHash )); } // Decisao unica de "devo mandar pro Slack agora" -- centraliza os dois motivos possiveis de // NAO enviar (SEND_ENABLED=false, ou ja enviado com sucesso hoje) num so lugar auditavel. function evaluateSendGuard({ config, existingRecords, reportDate, runType, messageHash }) { if (!shouldSendByConfig(config)) { return { shouldSend: false, reason: 'send_disabled' }; } if (alreadySentSuccessfully(existingRecords, { reportDate, runType, messageHash })) { return { shouldSend: false, reason: 'already_sent' }; } return { shouldSend: true, reason: 'ok' }; } function buildEnvioDigestRecord({ reportDate, runType, messageHash, sentAt, status, errorDetail }) { return { report_date: reportDate, run_type: runType, message_hash: messageHash, sent_at: sentAt, status, error_detail: errorDetail || null, }; } module.exports = { computeMessageHash, shouldSendByConfig, alreadySentSuccessfully, evaluateSendGuard, buildEnvioDigestRecord, };