feat(apartado): ficha completa en Monday + estado visible en la app

- El alta (directa y progresiva) llena el Apartado con telefono, correo,
  curp, Precio Final, Enganche, Fecha Compra, Vendedor (el capturista
  con Monday vinculado) y Forma de Pago; el path webhook/cron hereda
  contacto, precio y asesor de la oportunidad.
- Bidireccional: Mis clientes en /hoy muestra el estado actual del
  Apartado leyendolo de Monday (si lo mueven en Monday, la app lo
  refleja en el siguiente refresh).
- getApartados con la correccion value-null al leer Estado.
- Test del mapa de Tipo propuesta del cotizador (los 502 del log eran
  de un proceso previo al fix 4f31d1c; queda cubierto).
This commit is contained in:
2026-09-04 07:34:57 +00:00
parent d81797c610
commit 42cfe937cf
13 changed files with 428 additions and 12 deletions

View File

@@ -74,6 +74,8 @@ export interface ClienteMiDia {
unidadCodigo: string
completado: boolean // true cuando el alta ya tiene proyecto (pasó a CLIENTE)
capturadoEn: string // ISO
/** Estado actual del item en el tablero Apartado (bidireccional Monday→app); null si no hay apartado ligado o ya no existe */
estadoApartado: string | null
}
export interface ResumenMiDia {
@@ -136,7 +138,14 @@ export async function resumenMiDia(
/** Capturas locales del usuario (tabla LeadCaptura), ya filtradas por él */
capturas: { leadId: string; nombreLead: string; telefono: string | null; createdAt: Date }[] = [],
/** Clientes cuyo alta inició el usuario (tabla Cliente), ya filtrados por él */
clientes: { id: string; nombreCompleto: string; proyecto: string; unidadCodigo: string | null; createdAt: Date }[] = [],
clientes: {
id: string
nombreCompleto: string
proyecto: string
unidadCodigo: string | null
mondayApartadoId: string | null
createdAt: Date
}[] = [],
ahora: Date = new Date(),
): Promise<ResumenMiDia> {
const miId = usuario.mondayUserId
@@ -217,8 +226,11 @@ export async function resumenMiDia(
})
.sort((a, b) => b.capturadoEn.localeCompare(a.capturadoEn))
// "Mis clientes" es 100% local (no requiere Monday): el alta en progreso
// lleva proyecto '', el alta completada lleva el proyecto lleno
// "Mis clientes" es local + cruce con Monday: el alta en progreso lleva
// proyecto '', el alta completada lleva el proyecto lleno. estadoApartado
// cruza Cliente.mondayApartadoId contra el tablero Apartado (null si no hay
// apartado ligado o ya no existe en Monday)
const apartadosPorId = new Map(apartados.map((a) => [a.id, a]))
const misClientes: ClienteMiDia[] = clientes
.map((c) => ({
id: c.id,
@@ -227,6 +239,8 @@ export async function resumenMiDia(
unidadCodigo: c.unidadCodigo ?? '',
completado: c.proyecto.trim() !== '',
capturadoEn: c.createdAt.toISOString(),
estadoApartado:
c.mondayApartadoId != null ? (apartadosPorId.get(c.mondayApartadoId)?.estado ?? null) : null,
}))
.sort((a, b) => b.capturadoEn.localeCompare(a.capturadoEn))