feat(modo-local): fallback completo sin Monday + cola de sincronización
- Circuit breaker saludMonday (3 fallos → modo local; ping cada 60s)
- Endpoint GET /api/sistema/estado {mondayOk, pendientesSync}
- LeadCaptura extendida (board, etapa, origen, motivo, pendienteSync)
- Tablas Unidad (espejo inventario, 288 seed) + SyncPendiente
- crmLocal: crearLead, afluencia, cambio etapa, descarte, conversión, apartar
- Ruteo en controllers: fallback local ante 502 o Monday caído
- Mi día local: resumen completo desde SQLite + unión con Monday
- Fallbacks: unidades, contactos, reportes, prefill, buscador
- Sync worker cada 2min + handlers 15 tipos (con DependenciaPendienteError)
- Gate automatizaciones: skip si !mondayOk
- Banner 'Modo local' en 5 apps + badge pendiente en mi-dia
- 597 API tests + 263 front tests verdes
Env MODO_LOCAL_FORZADO=true para testing sin Monday.
This commit is contained in:
77
api-gateway/scripts/seed-unidades-locales.js
Normal file
77
api-gateway/scripts/seed-unidades-locales.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Siembra la tabla local `Unidad` (espejo del inventario para el modo local)
|
||||
* desde el INVENTARIO_SEED curado del cotizador
|
||||
* (apps/cotizador/src/data/unidades.ts, generado de los Excel de precios).
|
||||
*
|
||||
* Idempotente: upsert por `codigo`. Se corre una vez en el deploy y cuando el
|
||||
* seed del cotizador se regenere; el write-through de
|
||||
* monday.service.getUnidades() mantiene fresco el espejo en operación normal.
|
||||
*
|
||||
* Uso: npm run seed:unidades (tsx, porque la fuente es TypeScript)
|
||||
*/
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import dotenv from 'dotenv'
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { INVENTARIO_SEED } from '../../apps/cotizador/src/data/unidades.ts'
|
||||
|
||||
const raizApi = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
dotenv.config({ path: [path.resolve(raizApi, '.env'), path.resolve(raizApi, '..', '.env')] })
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
const numero = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0)
|
||||
const texto = (v) => (v === null || v === undefined ? '' : String(v))
|
||||
|
||||
function mapearUnidad(u) {
|
||||
const extras = u.extras ?? {}
|
||||
return {
|
||||
codigo: u.codigo,
|
||||
desarrollo: texto(u.desarrollo) || 'DIAGONAL',
|
||||
modelo: texto(u.modelo),
|
||||
manzana: texto(extras.manzana),
|
||||
lote: texto(extras.lote),
|
||||
supConstruccion: numero(u.supConstruccion),
|
||||
supExcedente: numero(u.supExcedente),
|
||||
supEstacionamiento: numero(u.supEstacionamiento),
|
||||
precioLista: numero(u.precioSinAcabados),
|
||||
precioAcabados: numero(u.precioConAcabados),
|
||||
status: texto(u.status) || 'DISPONIBLE',
|
||||
// En SOLANA la etapa de obra vive en extras.etapa; en el tablero Monday es
|
||||
// la columna "Etapa" (top-level en el tipo del cotizador)
|
||||
etapa: texto(u.etapa) || texto(extras.etapa),
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let insertadas = 0
|
||||
let actualizadas = 0
|
||||
for (const cruda of INVENTARIO_SEED) {
|
||||
const u = mapearUnidad(cruda)
|
||||
const previa = await prisma.unidad.findUnique({ where: { codigo: u.codigo }, select: { id: true } })
|
||||
await prisma.unidad.upsert({
|
||||
where: { codigo: u.codigo },
|
||||
update: u,
|
||||
create: u,
|
||||
})
|
||||
if (previa) actualizadas++
|
||||
else insertadas++
|
||||
}
|
||||
const total = await prisma.unidad.count()
|
||||
const porDesarrollo = await prisma.unidad.groupBy({ by: ['desarrollo'], _count: { codigo: true } })
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
`[seed-unidades] ${insertadas} insertada(s), ${actualizadas} actualizada(s); total en tabla: ${total}`,
|
||||
)
|
||||
for (const d of porDesarrollo) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(` ${d.desarrollo}: ${d._count.codigo}`)
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((err) => {
|
||||
console.error('[seed-unidades] error:', err)
|
||||
process.exitCode = 1
|
||||
})
|
||||
.finally(() => prisma.$disconnect())
|
||||
Reference in New Issue
Block a user