feat(funnel): leads entran como Afluencia al funnel de Oportunidades

- Captura rápida crea lead + oportunidad en etapa Afluencia (vinculadas
  por nueva tabla LeadOportunidad); también aplica a leads creados
  directo en Monday vía webhook
- Transiciones automáticas: AGENDA CITA → Agendo Cita, descarte →
  Perdido (+ dropdown Motivo No Compra), cotización con mismo teléfono
  ACTUALIZA la oportunidad (no duplica) → Cotizador, alta de cliente
  con leadMondayId → Aparto (dedup previo para no duplicar Apartado)
- Columna Desarrollo agregada al board Oportunidades (color_mm6sa20t)
- Migración lead_oportunidad aplicada con migrate diff + resolve (la DB
  tiene drift histórico por db push; migrate dev pedía reset)
- Tests: 322 verdes; smoke en vivo verificado y limpiado
This commit is contained in:
2026-09-01 20:10:51 +00:00
parent ead7a71025
commit 98fedbd8d3
14 changed files with 854 additions and 53 deletions

View File

@@ -2,6 +2,7 @@ import type { Request, Response } from 'express'
import { z } from 'zod'
import { config } from '../config/index.js'
import { automatizacionesService } from '../services/automatizaciones.service.js'
import { funnelService } from '../services/funnel.service.js'
const eventoSchema = z
.object({
@@ -65,6 +66,18 @@ export function webhookMonday(req: Request, res: Response): void {
// eslint-disable-next-line no-console
console.error(`[webhook monday] error en round-robin item=${id}:`, err)
})
// El lead entra también al funnel de Oportunidades (etapa 'Afluencia').
// El payload no trae nombre/teléfono: el servicio los consulta en Monday.
void funnelService
.asegurarOportunidadAfluenciaPorLeadId(id)
.then((opId) => {
// eslint-disable-next-line no-console
console.log(`[webhook monday] afluencia item=${id}: oportunidad ${opId ?? 'no creada'}`)
})
.catch((err: unknown) => {
// eslint-disable-next-line no-console
console.error(`[webhook monday] error en afluencia item=${id}:`, err)
})
}
// Cambio de etapa en Oportunidades → crear Apartado/Venta si aplica.