feat(unidades): pipeline de 10 etapas por unidad + sync desde Reporte_EstatusVenta

- Columna Etapa en Monday Unidades (10 labels oficiales), 155 unidades pobladas
- sync-etapas.ts idempotente (--archivo/--dry-run/--semilla) con traspasos
  Vendido→Escrituración y Escriturado→SAC como actividades (sin retroactivas)
- API: etapa en unidades + porEtapa en /api/reportes/resumen
- Dashboard: gráfica pipeline por etapa + KPI en notaría; cotizador muestra etapa
- 28 cambios aplicados desde Reporte_EstatusVenta (8 avances, 20 nuevas);
  contradicciones retenidas para revisión humana (documentadas)
- Tests: api 168, dashboards 9, cotizador 71
This commit is contained in:
2026-08-28 04:43:02 +00:00
parent 04de7d703f
commit 9e04b76616
16 changed files with 697 additions and 4 deletions

View File

@@ -80,9 +80,23 @@ describe('MondayService', () => {
status: 'DISPONIBLE',
desarrollo: 'SENDA',
mesesParaFirma: null,
etapa: null,
})
})
it('mapea la columna opcional "Etapa" (pipeline de venta) cuando existe', async () => {
const columnasConEtapa = [...COLUMNAS_UNIDADES, { id: 'color_mm6ejjj', title: 'Etapa', type: 'status' }]
const item = itemUnidad('1', 'U-101', 'VENDIDO')
item.column_values.push({ id: 'color_mm6ejjj', text: 'Notaría', value: null })
mockearFetch((body) => {
if (body.query.includes('columns')) return respuestaOk({ boards: [{ columns: columnasConEtapa }] })
return respuestaOk({ boards: [{ items_page: { cursor: null, items: [item] } }] })
})
const unidades = await crearServicio().getUnidades()
expect(unidades[0]?.etapa).toBe('Notaría')
})
it('excluye items placeholder sin datos (p. ej. "Task 1" default de Monday)', async () => {
const placeholder = {
id: '99',