import { prisma } from './prisma.js' /** * Lead Scoring: asigna un score 0-100 a cada LeadCaptura basado en: * - Etapa del pipeline (NUEVO=20, CONTACTADO=40, INTERESADO=60, AGENDO=80, CALIFICADO=90) * - Recencia (último cambio/creación): <24h +10, <7d +5, >30d -20 * - Datos de contacto: tiene teléfono +5, email +5 * - Origen conocido (no vacío): +5 */ const ETAPA_SCORE: Record = { NUEVO: 20, CONTACTADO: 40, INTERESADO: 60, AGENDO: 80, CALIFICADO: 90, } export interface LeadScore { leadId: string nombreLead: string usuarioId: string etapa: string telefono: string | null email: string | null origen: string | null score: number } /** * Calcula el score 0-100 de un lead dado su registro de LeadCaptura. * Función pura (testable sin BD). */ export function calcularScore(lead: { etapa: string telefono: string | null email: string | null origen: string | null createdAt: Date updatedAt: Date }, ahora: Date = new Date()): number { let score = 0 // 1. Etapa const etapaNorm = (lead.etapa ?? '').trim().toUpperCase() score += ETAPA_SCORE[etapaNorm] ?? 10 // 2. Recencia (basado en updatedAt como proxy de "última actividad") const diffMs = ahora.getTime() - lead.updatedAt.getTime() const diffHoras = diffMs / (1000 * 60 * 60) if (diffHoras < 24) { score += 10 } else if (diffHoras < 7 * 24) { score += 5 } else if (diffHoras > 30 * 24) { score -= 20 } // 3. Datos de contacto if (lead.telefono !== null && lead.telefono.trim() !== '') score += 5 if (lead.email !== null && lead.email.trim() !== '') score += 5 // 4. Origen conocido if (lead.origen !== null && lead.origen.trim() !== '') score += 5 // Clamp 0-100 return Math.max(0, Math.min(100, score)) } /** * Obtiene los scores de todos los leads activos (no descartados), opcionalmente * filtrados por usuarioId. */ export async function obtenerScores(usuarioId?: string): Promise { const where: Record = { board: { in: ['LEADS', 'OPORTUNIDADES'] }, } if (usuarioId) { where['usuarioId'] = usuarioId } const leads = await prisma.leadCaptura.findMany({ where }) const ahora = new Date() return leads .map((lead) => ({ leadId: lead.leadId, nombreLead: lead.nombreLead, usuarioId: lead.usuarioId, etapa: lead.etapa, telefono: lead.telefono, email: lead.email, origen: lead.origen, score: calcularScore( { etapa: lead.etapa, telefono: lead.telefono, email: lead.email, origen: lead.origen, createdAt: lead.createdAt, updatedAt: lead.updatedAt, }, ahora, ), })) .sort((a, b) => b.score - a.score) }