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:
@@ -6,6 +6,8 @@ import multer from 'multer'
|
||||
import { z } from 'zod'
|
||||
import { config } from '../config/index.js'
|
||||
import { mondayService } from '../services/monday.service.js'
|
||||
import { funnelService } from '../services/funnel.service.js'
|
||||
import { prismaStateStore } from '../services/automatizaciones.service.js'
|
||||
import { prisma } from '../services/prisma.js'
|
||||
import { NotFoundError, BadRequestError } from '../utils/errors.js'
|
||||
|
||||
@@ -175,6 +177,21 @@ export async function crearCliente(req: Request, res: Response): Promise<void> {
|
||||
},
|
||||
})
|
||||
|
||||
// Si el alta viene de un lead del funnel (la app alta-clientes manda
|
||||
// leadMondayId en la raíz del payload), su oportunidad pasa a 'Aparto'.
|
||||
// moverAApartoConDedup escribe el dedup `apartado-creado:<opId>` ANTES del
|
||||
// cambio de etapa, para que el webhook/cron no cree un Apartado duplicado.
|
||||
// Un fallo aquí no rompe el alta.
|
||||
const leadMondayId = (body as Record<string, unknown>)['leadMondayId']
|
||||
if (typeof leadMondayId === 'string' && leadMondayId !== '') {
|
||||
try {
|
||||
await funnelService.moverAApartoConDedup(leadMondayId, prismaStateStore)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`No se pudo mover a 'Aparto' la oportunidad del lead ${leadMondayId}:`, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Réplica en Monday; si falla, el alta ya quedó persistida y se reportan ids null
|
||||
let mondayContactoId: string | null = null
|
||||
let mondayApartadoId: string | null = null
|
||||
|
||||
Reference in New Issue
Block a user