const ACTION_LABELS = { UNASSIGNED_ACTIONABLE: 'Atribuir técnico', ACTIONABLE_NOW: 'Validar e executar', WAITING_APPROVAL: 'Cobrar aprovação', INSUFFICIENT_CONTEXT: 'Completar informação', }; function shortActionLabel(aiClassification) { if (aiClassification.is_fallback) return 'Revisar chamado'; const fromMap = ACTION_LABELS[aiClassification.classification]; if (fromMap) return fromMap; const raw = String(aiClassification.next_action || 'Revisar chamado').trim(); return raw.length > 40 ? `${raw.slice(0, 37)}...` : raw; } function tituloCurto(texto) { const limpo = String(texto || 'Sem titulo').replace(/\s+/g, ' ').trim(); return limpo.length > 60 ? `${limpo.slice(0, 57)}...` : limpo; } function signalLine(ticket) { const parts = []; parts.push(ticket.sem_tecnico ? 'SEM TÉCNICO' : ticket.tecnico_atribuido); if (ticket.sla_vencido) parts.push('SLA vencido'); parts.push(`parado ${ticket.dias_sem_interacao}d`); return parts.join(' • '); } function buildTopMessage(selected, dateStr, config) { if (!selected.length) { return `@time Coordenador GLPI - ${dateStr}\n\nNenhum chamado acionável encontrado hoje.`; } const header = `@time ${selected.length} chamados para atenção hoje — ${dateStr}`; const blocks = selected.map((item, index) => { const t = item.ticket; const linhasDoBloco = [ `${index + 1}. #${t.id} • ${tituloCurto(t.titulo)}`, signalLine(t), `→ ${shortActionLabel(item.aiClassification)}`, t.link_glpi, ]; return linhasDoBloco.join('\n'); }); const partesDaMensagem = [header, '', ...blocks]; return partesDaMensagem.join('\n\n'); } function buildCoordinationDigest(changedBlocked, dateStr) { if (!changedBlocked.length) return null; const lines = changedBlocked.map((item) => `#${item.ticket.id} • ${(item.aiClassification && item.aiClassification.reason) || item.exclusionReason}`); const partesDoDigest = [`Coordenação — bloqueios novos/alterados — ${dateStr}`, '', ...lines]; return partesDoDigest.join('\n'); } module.exports = { shortActionLabel, tituloCurto, signalLine, buildTopMessage, buildCoordinationDigest };