import { loadDotEnv } from '../src/env.mjs'; import { openDb, transaction } from '../src/db.mjs'; import { scoreQualidade, scoreComercial, scoreGeral, classificarScoreGeral } from '../src/scoring.mjs'; // Recalcula score_qualidade/score_comercial/score/classificacao/prioridade/ // produto_principal de TODOS os leads a partir dos dados ja gravados + da // afinidade/produtos configurados por nicho (tabela segments). Nao e um // script de uso unico: roda de novo (`npm run recalc-scores`) sempre que o // catalogo de afinidade/produtos em prospeccao/config.json mudar. // // Roda com o servidor parado (evita concorrencia de escrita no WAL). await loadDotEnv(); const BATCH_SIZE = 2000; function produtoPrincipalDe(produtos) { return produtos.length ? [...produtos].sort((a, b) => b.estrelas - a.estrelas)[0].nome : ''; } async function main() { const db = openDb(); const segmentos = new Map( db.prepare('SELECT name, affinity, products_json FROM segments').all() .map((row) => [row.name, { affinity: row.affinity, products: JSON.parse(row.products_json) }]) ); const update = db.prepare(` UPDATE leads SET score = ?, classificacao = ?, motivo_classificacao = ?, score_qualidade = ?, score_comercial = ?, prioridade = ?, produto_principal = ?, produtos_json = ?, updated_at = datetime('now') WHERE id = ? `); const total = db.prepare('SELECT COUNT(*) AS t FROM leads').get().t; const porPrioridade = { 1: 0, 2: 0, 3: 0, 4: 0 }; let processed = 0; let lastId = 0; const page = db.prepare('SELECT * FROM leads WHERE id > ? ORDER BY id LIMIT ?'); while (true) { const rows = page.all(lastId, BATCH_SIZE); if (!rows.length) break; transaction(db, () => { for (const lead of rows) { const info = segmentos.get(lead.segmento) || { affinity: 'media', products: [] }; const qualidade = scoreQualidade({ whatsapp: lead.whatsapp, cnpj: lead.cnpj, empresa: lead.empresa, cidade: lead.cidade, segmento: lead.segmento, cnae: lead.cnae, website: lead.website }); const comercial = scoreComercial({ whatsapp: lead.whatsapp, cnpj: lead.cnpj, website: lead.website, email: lead.email, affinity: info.affinity }); const geral = scoreGeral(qualidade.score, comercial); const tier = classificarScoreGeral(geral); const produtoPrincipal = produtoPrincipalDe(info.products); update.run( geral, tier.id, `score geral ${geral} (qualidade ${qualidade.score}, comercial ${comercial})`, qualidade.score, comercial, tier.prioridade, produtoPrincipal, JSON.stringify(info.products), lead.id ); porPrioridade[tier.prioridade] += 1; } }); processed += rows.length; lastId = rows[rows.length - 1].id; console.log(`${processed}/${total} leads recalculados...`); } console.log('Concluido. Distribuicao por prioridade:', porPrioridade); db.close(); } main().catch((error) => { console.error('Erro no recalculo de scores:', error); process.exit(1); });