PWA Offline-First
Arquitectura de aplicación web progresiva con caché de service worker, almacenamiento IndexedDB, sincronización en segundo plano y resolución de conflictos para operaciones de campo sin conectividad.
Última actualización: 2025-02-18
Arquitectura PWA Offline-First
Certexi es una Aplicación Web Progresiva completamente capaz de operar offline. Las operaciones aduaneras continúan sin interrupciones sin conectividad a internet — los eventos se encolan localmente y se sincronizan automáticamente cuando se restaura la conexión.
Arquitectura
Indicador de Estado Offline
<div className="flex flex-col gap-3 w-72"> <Card> <CardContent className="p-3 flex items-center gap-3"> <div className="w-2.5 h-2.5 rounded-full bg-green-500 animate-pulse" /> <div className="flex-1"> <div className="text-sm font-medium">En línea</div> <div className="text-xs text-muted-foreground">Todos los sistemas conectados</div> </div> <Badge variant="outline" className="text-green-500">Sincronizado</Badge> </CardContent> </Card> <Card> <CardContent className="p-3 flex items-center gap-3"> <div className="w-2.5 h-2.5 rounded-full bg-amber-500" /> <div className="flex-1"> <div className="text-sm font-medium">Sin conexión</div> <div className="text-xs text-muted-foreground">3 eventos en cola</div> </div> <Badge variant="outline" className="text-amber-500">Pendiente</Badge> </CardContent> </Card> <Card> <CardContent className="p-3 space-y-2"> <div className="flex items-center justify-between text-xs"> <span className="text-muted-foreground">Cola de sincronización</span> <span>3 / 3 eventos</span> </div> <Progress value={0} className="h-1.5" /> <Button size="sm" variant="outline" className="w-full text-xs">Forzar Sincronización</Button> </CardContent> </Card> </div>
Componentes Principales
Service Worker (/public/sw.js)
El service worker gestiona toda la caché y sincronización en segundo plano:
- Cachea activos estáticos (HTML, CSS, JS, imágenes, fuentes)
- Implementa estrategias de red primero y caché primero
- Maneja la sincronización en segundo plano para eventos encolados
- Proporciona páginas de respaldo offline para rutas no coincidentes
Almacenamiento IndexedDB (/lib/offline/storage.ts)
Tres almacenes de objetos impulsan la experiencia offline:
| Almacén | Propósito | Clave |
|---|---|---|
events | Operaciones encoladas esperando sincronización | ID auto-generado |
units | Unidades de transporte cacheadas para acceso offline | ID de Unidad |
responses | Respuestas de API cacheadas con TTL | URL de Solicitud |
Indicador Offline (/components/offline-indicator.tsx)
Retroalimentación visual para los usuarios que muestra el estado en línea/offline en tiempo real, conteo de sincronización pendiente y activador de sincronización manual.
Flujo de Trabajo Offline Completo
Los usuarios pueden realizar todas las operaciones críticas mientras están offline:
- Escanear tags NFC y códigos QR
- Capturar fotos y ubicación GPS
- Registrar observaciones de inspección
- Ver unidades de transporte cacheadas
- Progresar a través de todas las etapas del flujo de trabajo
Los eventos se encolan en IndexedDB con la siguiente estructura:
interface QueuedEvent {
id: string; // "offline-{timestamp}-{random}"
eventType: string; // inspection, entry, exit, scale, etc.
data: any; // Full event payload
timestamp: number; // When queued (ms)
retries: number; // Sync retry count
synced: boolean; // Sync status
}
Estrategias de Caché
Activos Estáticos (Caché Primero)
HTML, CSS, JavaScript, imágenes y fuentes se cachean indefinidamente y se actualizan cuando cambia la versión del service worker.
Solicitudes de API (Red Primero)
Las llamadas a API siempre intentan la red primero, recurriendo a respuestas cacheadas cuando está offline. Las respuestas se cachean por 5 minutos (configurable).
Páginas (Red Primero)
El contenido dinámico siempre está fresco cuando hay conexión. Las páginas cacheadas están disponibles offline con una página de respaldo para rutas no coincidentes.
Sincronización en Segundo Plano
Cuando se restaura la conexión:
- El service worker activa la sincronización en segundo plano
- Los eventos encolados se procesan secuencialmente
- Cada evento se envía a su endpoint apropiado
- Los eventos fallidos se reintentan con backoff exponencial (máximo 5 reintentos)
- Los eventos sincronizados exitosamente se eliminan de la cola
Soporte de Navegador
La Background Sync API es compatible con Chrome 49+ y Edge 79+. Para Safari y Firefox, Certexi recurre a sincronización manual en el evento online.
Mapeo de Endpoints de Sincronización
| Tipo de Evento | Endpoint |
|---|---|
inspection | /api/uma/attestation |
entry | /api/workflow/entry |
exit | /api/workflow/exit |
scale | /api/workflow/scale |
| Default | /api/events |
Integridad de Datos
Las operaciones offline están protegidas por múltiples capas:
- Hashing criptográfico para todos los eventos
- Verificación de árbol Merkle en la sincronización
- Prevención de ataques de repetición basada en timestamp
- Detección de duplicados del lado del servidor
Re-autenticación
Después de un período offline extendido, los usuarios pueden necesitar re-autenticarse. Las operaciones offline usan credenciales cacheadas que expiran según el tiempo de vida del token JWT.
Configuración
Versión de Caché
Incremente CACHE_VERSION en /public/sw.js para forzar una actualización completa de caché en la próxima visita.
TTL de Caché
Caché de respuesta de API predeterminada: 5 minutos (300,000ms). Configurable por solicitud.
Límite de Reintentos
Máximo 5 reintentos de sincronización antes de descartar un evento. Los eventos fallidos se registran para recuperación manual.
Soporte de Navegadores
| Característica | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Service Worker | 40+ | 44+ | 11.1+ | 17+ |
| IndexedDB | 24+ | 16+ | 10+ | 12+ |
| Background Sync | 49+ | Flag | No | 79+ |
| Cache API | 40+ | 41+ | 11.1+ | 17+ |