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:
2026-09-06 08:08:56 +00:00
parent af2fb10956
commit 60649890eb
70 changed files with 8763 additions and 240 deletions

View File

@@ -3,6 +3,7 @@ import { MODULOS, esModuloVisible } from './data/modulos'
import { Navbar } from './components/Navbar'
import { TarjetaModulo } from './components/TarjetaModulo'
import { ConfiguracionCuenta } from './components/ConfiguracionCuenta'
import BannerModoLocal from './components/BannerModoLocal'
import { VistaContactos } from './components/VistaContactos'
import { getToken } from './services/auth'
import { getMe } from './services/api'
@@ -40,6 +41,7 @@ export default function App() {
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<BannerModoLocal />
<VistaContactos onVolver={() => setVista('home')} />
</div>
)
@@ -48,6 +50,7 @@ export default function App() {
return (
<div className="flex min-h-screen flex-col">
<Navbar />
<BannerModoLocal />
<main className="mx-auto w-full max-w-[1280px] flex-1 px-6">
<section aria-labelledby="titulo-hero" className="py-12 sm:py-16">