feat(purga): Monday eliminado completamente del sistema

14 servicios eliminados, 7 controllers local-only, crons locales,
config sin MONDAY_*, frontend sin banners/avisos Monday.
552 tests API + 7 apps construidas.
This commit is contained in:
2026-09-11 11:47:17 +00:00
parent 64b01246d6
commit 89d95eb53b
130 changed files with 2018 additions and 14747 deletions

View File

@@ -20,7 +20,7 @@ interface Props {
onPasarAAltaCliente: (lead: LeadResumen) => void
/** Prefill desde Mis oportunidades (Mi día): valores iniciales del formulario */
valoresIniciales?: Partial<typeof FORM_INICIAL>
/** Oportunidad de Monday a ACTUALIZAR al enviar (sin duplicar el item) */
/** Oportunidad a ACTUALIZAR al enviar (sin duplicar el registro) */
oportunidadId?: string
}
@@ -62,7 +62,7 @@ const FORM_INICIAL = {
/**
* Captura ligera del interesado al entrar al embudo (POST /leads): crea el
* lead en Monday y su oportunidad en etapa Afluencia. El alta completa de
* lead y su oportunidad en etapa Afluencia. El alta completa de
* cliente sigue siendo el wizard del picker.
*/
export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valoresIniciales, oportunidadId }: Props) {
@@ -90,7 +90,7 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor
MODELOS_POR_PROYECTO[form.desarrollo as keyof typeof MODELOS_POR_PROYECTO] ?? []
/**
* Jala los datos de un lead u oportunidad ya capturados en Monday:
* Jala los datos de un lead u oportunidad ya capturados:
* nombre/contacto siempre; origen, desarrollo y modelo solo si el valor del
* lead existe entre las opciones del formulario.
*/
@@ -267,13 +267,13 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor
className="mb-6 rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-xs font-medium text-blue-800"
>
Estás completando la afluencia de {form.nombre || 'esta oportunidad'} — al enviar se actualiza su
oportunidad en Monday (no se duplica).
oportunidad ya capturada (no se duplica).
</p>
) : (
<div className="mb-6 border-b border-[#E5E7EB] pb-6">
<BusquedaLead onSeleccion={prellenarDesdeLead} />
<p className="mt-2 text-xs text-[#64748B] dark:text-[#94A3B8]">
Si el interesado ya está en Monday (lead u oportunidad), sus datos se prellenan solos.
Si el interesado ya está capturado (lead u oportunidad), sus datos se prellenan solos.
</p>
</div>
)}

View File

@@ -1,32 +0,0 @@
import { useEffect, useState } from 'react'
import { fetchEstadoSistema } from '../services/sistema'
const INTERVALO_POLL_MS = 60_000
export function useModoLocal(): boolean {
const [modoLocal, setModoLocal] = useState(false)
useEffect(() => {
let activo = true
const consultar = () => {
void fetchEstadoSistema().then((estado) => {
if (activo) setModoLocal(estado !== null && !estado.mondayOk)
})
}
consultar()
const id = setInterval(consultar, INTERVALO_POLL_MS)
return () => { activo = false; clearInterval(id) }
}, [])
return modoLocal
}
export default function BannerModoLocal() {
const modoLocal = useModoLocal()
if (!modoLocal) return null
return (
<div role="status" className="border-b border-amber-200 bg-amber-50">
<p className="mx-auto max-w-[1280px] px-4 py-2 text-xs font-medium text-amber-700 sm:px-6">
Modo local — Monday no disponible. Tus capturas se guardan y se sincronizarán automáticamente.
</p>
</div>
)
}

View File

@@ -67,6 +67,6 @@ describe('BusquedaLead', () => {
fetchMock.mockRejectedValueOnce(new Error('red caída'))
fireEvent.change(screen.getByLabelText(/Buscar lead/), { target: { value: 'otro' } })
expect((await screen.findByRole('alert')).textContent).toContain('No se pudo buscar en Monday')
expect((await screen.findByRole('alert')).textContent).toContain('No se pudo buscar')
})
})

View File

@@ -8,7 +8,7 @@ interface Props {
}
/**
* Buscador con debounce de leads/afluencias de Monday (GET /leads/buscar,
* Buscador con debounce de leads/afluencias (GET /leads/buscar,
* búsqueda dual: tablero Leads histórico + Oportunidades). No llama al API
* con menos de 2 caracteres; al elegir un resultado avisa con onSeleccion.
*/
@@ -35,7 +35,7 @@ export default function BusquedaLead({ onSeleccion }: Props) {
})
.catch(() => {
setResultados(null)
setError('No se pudo buscar en Monday. Intenta de nuevo.')
setError('No se pudo buscar. Intenta de nuevo.')
})
.finally(() => setBuscando(false))
}, DEBOUNCE_MS)