Servidor Modo Isla
Un pequeño servidor Node se ejecuta en el sitio físico manteniendo una réplica RxDB en vivo de la porción del Firestore correspondiente a ese sitio. Mientras hay conexión a Internet permanece invisible; cuando la conexión falla, los terminales de quiosco/personal en la LAN conmutan hacia él y el sitio sigue tomando pedidos, moviendo stock y controlando hardware. Al reconectarse, el trabajo offline se vacía de vuelta a la nube. La idea central que lo define todo: la sincronización son dos sistemas, no uno — replicación RxDB a nivel de documento para el estado, más un vaciado HTTP de eventos de negocio que la nube debe aplicar con su propia lógica (incrementos de stock, ingesta de auditoría). Ninguna de las dos por sí sola es suficiente.
Cuándo usarlo
- Un sitio debe sobrevivir cortes de Internet con escrituras reales (reservas, stock, control de hardware), no solo lecturas cacheadas.
- Los terminales se basan en navegador (PWA/quiosco) y deben conmutar por error de forma transparente.
- Firestore es la fuente de verdad en la nube y debe seguir siéndolo.
Cuándo NO usarlo
- Caché de solo lectura o una PWA que solo necesita la persistencia offline nativa de Firestore: el SDK de Firebase ya lo hace; no se necesita un servidor.
- Una base de datos en la nube diferente (Supabase/Postgres): el concepto de niveles de replicación es portable, pero todas las plantillas aquí son específicas de Firestore.
- Sincronización multimaestro entre sitios pares: este diseño es estrictamente hub-and-spoke con la nube como fuente de verdad y conflictos resueltos con última escritura gana.
Arquitectura
Internet
|
+--------+---------+
| Nube (SSoT) | Firestore + API pública + marcador de estado cron
+--------+---------+
| |
Replicación RxDB Vacío HTTP (reconexión)
| |
+-+-------------+-+
| Servidor local | Node/NestJS + RxDB, LAN :443 vía nginx TLS
+--------+--------+
|
LAN — PWA quiosco, PWA personal, controladores hardware
Datos críticos
- Toda escritura en la nube sobre una colección replicada DEBE marcar el campo
checkpoint (
serverTimestamp: FieldValue.serverTimestamp()) y_deleted: false— el plugin RxDB Firestore extrae datos medianteserverTimestamp > checkpoint; un documento sin marca nunca será extraído por la replicación. - Tres niveles de replicación, elegidos por colección: solo pull (configuración que el sitio consume), bidireccional (estado operacional que el sitio modifica), solo push (logs que el sitio produce). Elegir mal el nivel de una colección es el principal error de diseño.
- El almacenamiento RxDB en memoria implica que un reinicio en modo offline pierde todo el trabajo offline. La réplica se repuebla desde Firestore, pero los documentos creados offline se pierden. Decide explícitamente la compensación de almacenamiento; consulta replication.md.
- El vaciado es al-menos-una-vez, por lo que la ingesta en la nube debe ser idempotente: clavea cada aplicación con el ID generado por el cliente y salta las ya aplicadas.
- Los filtros push evitan ecos: las inserciones bidireccionales solo envían documentos
marcados con
_offlineCreated/_locallyModified, así que los documentos de la nube extraídos mediante pull no rebotan de vuelta. - Los terminales prefieren la nube: la conmutación por error se activa solo tras N fallos consecutivos de salud, y mientras están offline deben seguir reexplorando en busca del servidor local, no solo una vez en la transición.
Reglas estrictas
Nunca expongas los endpoints de sincronización/ingesta en la nube sin autenticación. Aplican incrementos de stock e inyectan pedidos. Un encabezado con secreto compartido es el mínimo.
Nunca verifiques tokens de personal offline de forma permisiva mientras estás en línea. La alternativa de decodificar sin verificación es una concesión aceptable solo para LAN; debe activarse únicamente cuando el servidor esté realmente offline, o se convierte en un bypass de la verificación de firma.
Nunca reinicies los deltas locales de stock para transacciones que no hayan confirmado su sincronización. Reinicia por ID solo tras el reconocimiento, o las ventas offline se contarán dos veces o desaparecerán de la disponibilidad.
Nunca dejes que el servidor local invente reglas de negocio que posee la nube (horarios de apertura, precios). Replica la configuración y computa a partir de ella, o el comportamiento en modo isla divergirá del sitio web.
Inicio rápido
- Modela las colecciones en niveles y nombra las costuras — architecture.md.
- Levanta RxDB + replicación con autenticación por token personalizado y reglas de seguridad — replication.md.
- Añade el vaciado en reconexión y la ingesta idempotente en la nube — sync-flush.md.
- Conecta la cadena de latido/estado y la conmutación por error del cliente — network-failover.md.
- Protege la API local (personal / quiosco / HMAC hardware / token estático) — auth.md.
- Espeja los endpoints de la nube que los terminales necesitan — local-api.md.
- Despliega on-site: systemd, nginx TLS, mDNS, monitoreo — operations.md.
Directorio de referencias
| Escenario | Palabras clave de activación | Referencia |
|---|---|---|
| Topología, niveles, costuras, tabla de renombres | solo pull, bidireccional, solo push, dual-path, locationId, conflicto | architecture.md |
| Configuración de réplica, esquemas, trampa del checkpoint | RxDB, replicateFirestore, serverTimestamp, custom token, storage-memory, firestore.rules | replication.md |
| Vacío en reconexión, deltas de stock, ingesta | flushAll, idempotent, FieldValue.increment, localDelta, syncedIds | sync-flush.md |
| Detección de fallos y conmutación de API | heartbeat, lastHeartbeatAt, cron, NetworkManager, apiBaseUrl, failover | network-failover.md |
| Autenticación de la API local | AuthGuard, HMAC, replay window, offline JWT fallback, kiosk key | auth.md |
| Endpoints y escrituras offline | availability, mutex, offline booking, check-in, pricing stock filter | local-api.md |
| Despliegue on-site y runbook | systemd, nginx, self-signed TLS, mDNS, avahi, journalctl, rollback | operations.md |
| El libro de contabilidad: qué cambió, mantuvo, añadió la auditoría | provenance, audit, deviations, kept deliberately | provenance.md |
Suite vitest aprobada para la lógica crítica de confianza (verificación HMAC, decodificación offline de tokens, plegado de deltas en RxDB real, reexploración de failover): assets/behavior.test.ts — pórtala al proyecto objetivo como cobertura de regresión.