--- id: EPIC-MCH-022 type: Epic title: "MCH-022: Modo Offline" code: MCH-022 status: Completado status_real: "Completado" status_nota: "Implementado en Sprint 7" phase: 6 priority: P1 created_at: 2026-01-10 updated_at: 2026-01-17 simco_version: "4.0.1" story_points: 21 dependencies: blocks: [] depends_on: [] --- # MCH-022: Modo Offline ## Metadata - **Codigo:** MCH-022 - **Fase:** 6 - Crecimiento - **Prioridad:** P1 - **Estado:** Completado - **Estado Real:** Implementado Sprint 7 - **Sprint Asignado:** Sprint 6 (Mobile) - **Story Points:** 21 ## Descripcion Soporte offline completo para la app movil: SQLite local, sincronizacion inteligente, resolucion de conflictos, y funcionamiento sin conexion para operaciones criticas (ventas). ## Objetivos 1. Base de datos local (SQLite) 2. Sincronizacion bidireccional 3. Ventas sin conexion 4. Resolucion de conflictos 5. Indicador de estado de conexion ## Alcance ### Incluido - SQLite para datos locales - Sync de productos, clientes, ventas - Cola de operaciones offline - Resolucion automatica de conflictos - Indicador visual de estado ### Excluido - Offline para dashboard web - Sync de imagenes pesadas - Operaciones de pago offline (solo efectivo) ## Arquitectura ``` ┌─────────────────────────────────────────────────────────┐ │ APP MOVIL │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │ │ UI Layer │───▶│ Repository │───▶│ SQLite │ │ │ └─────────────┘ └──────┬──────┘ └────────────┘ │ │ │ │ │ ┌──────▼──────┐ │ │ │ Sync Queue │ │ │ └──────┬──────┘ │ │ │ │ └────────────────────────────┼────────────────────────────┘ │ ┌──────▼──────┐ │ Backend │ │ API │ └─────────────┘ ``` ## Datos Sincronizados ### Alta Prioridad (Sync inmediato) | Tabla | Direccion | Frecuencia | |-------|-----------|------------| | products | Server → Local | Al iniciar + cada 5 min | | categories | Server → Local | Al iniciar | | sales | Local → Server | Inmediato cuando hay conexion | ### Media Prioridad | Tabla | Direccion | Frecuencia | |-------|-----------|------------| | customers | Bidireccional | Cada 15 min | | inventory | Server → Local | Cada 30 min | ### Baja Prioridad | Tabla | Direccion | Frecuencia | |-------|-----------|------------| | settings | Server → Local | Al iniciar | | reports | No sync (solo online) | - | ## Flujo de Venta Offline ``` 1. App detecta sin conexion 2. Usuario hace venta normal 3. Venta se guarda en SQLite 4. Se agrega a cola de sync 5. UI muestra "Venta guardada offline" 6. Cuando hay conexion: a. Cola procesa ventas pendientes b. Envia al servidor c. Actualiza IDs locales d. Marca como sincronizado ``` ## Resolucion de Conflictos ### Estrategia: Last Write Wins + Merge ```typescript // Para productos if (local.updated_at > server.updated_at) { // Local gana sync.upload(local); } else if (server.updated_at > local.updated_at) { // Server gana sync.download(server); } else { // Merge campos no conflictivos sync.merge(local, server); } ``` ### Casos Especiales **Venta offline con producto eliminado:** ``` 1. Producto vendido offline 2. Producto eliminado en server 3. Al sync: venta se registra con producto_id 4. Se marca producto como "deleted" localmente ``` **Stock desactualizado:** ``` 1. Venta offline reduce stock local 2. Otra venta online reduce stock 3. Al sync: stock negativo posible 4. Alerta al dueno para ajuste ``` ## Modelo de Datos Local (SQLite) ### Tablas Adicionales **sync_queue** - id, operation (create/update/delete) - table_name, record_id, payload - status, attempts, created_at **sync_status** - table_name, last_sync_at - records_count, pending_count ## UI Components ### ConnectionIndicator - Icono en header - Verde: online - Amarillo: sync pendiente - Rojo: offline ### OfflineBanner - Banner visible cuando offline - "Modo offline - cambios se sincronizaran" ### SyncProgress - Modal de sincronizacion - Progreso por tabla - Errores si hay ## Tecnologias - **SQLite:** react-native-sqlite-storage o expo-sqlite - **Sync:** Custom sync engine o WatermelonDB - **Network:** NetInfo para detectar conexion ## Historias de Usuario ### MCH-US-210: Base de Datos Local SQLite **Story Points:** 5 **Como** desarrollador de la app movil **Quiero** configurar SQLite como base de datos local **Para** almacenar datos que permitan el funcionamiento offline de la aplicacion #### Criterios de Aceptacion - [CA-210-1] SQLite esta configurado e inicializado correctamente en la app movil - [CA-210-2] Esquema de tablas locales replica las tablas necesarias del servidor (products, categories, customers, sales) - [CA-210-3] Tablas adicionales sync_queue y sync_status estan creadas - [CA-210-4] Migraciones de esquema funcionan correctamente - [CA-210-5] Tests unitarios validan operaciones CRUD basicas #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-210-01 | Instalar y configurar react-native-sqlite-storage o expo-sqlite | 2h | | MCH-TT-210-02 | Crear esquema de tablas locales (products, categories, customers, sales) | 3h | | MCH-TT-210-03 | Crear tablas sync_queue y sync_status | 2h | | MCH-TT-210-04 | Implementar sistema de migraciones de esquema | 3h | | MCH-TT-210-05 | Escribir tests unitarios para operaciones CRUD | 2h | --- ### MCH-US-211: Sincronizacion Bidireccional **Story Points:** 5 **Como** dueno de changarrito **Quiero** que mis datos se sincronicen automaticamente entre la app y el servidor **Para** tener informacion actualizada en todos mis dispositivos #### Criterios de Aceptacion - [CA-211-1] Productos y categorias se descargan del servidor al iniciar la app - [CA-211-2] Productos se actualizan cada 5 minutos cuando hay conexion - [CA-211-3] Clientes se sincronizan bidireccionalmente cada 15 minutos - [CA-211-4] Inventario se actualiza desde el servidor cada 30 minutos - [CA-211-5] Configuraciones se descargan al iniciar - [CA-211-6] El sync engine maneja errores de red graciosamente #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-211-01 | Disenar e implementar sync engine base | 4h | | MCH-TT-211-02 | Implementar sync de productos (Server → Local) | 3h | | MCH-TT-211-03 | Implementar sync de categorias (Server → Local) | 2h | | MCH-TT-211-04 | Implementar sync bidireccional de clientes | 3h | | MCH-TT-211-05 | Implementar sync de inventario y configuraciones | 2h | | MCH-TT-211-06 | Configurar timers y frecuencias de sincronizacion | 2h | --- ### MCH-US-212: Ventas sin Conexion **Story Points:** 3 **Como** empleado de changarrito **Quiero** poder registrar ventas aunque no haya internet **Para** no perder ventas cuando la conexion falle #### Criterios de Aceptacion - [CA-212-1] Ventas en efectivo se pueden realizar sin conexion a internet - [CA-212-2] Venta se guarda localmente en SQLite con estado "pending_sync" - [CA-212-3] UI muestra confirmacion clara "Venta guardada offline" - [CA-212-4] Stock local se actualiza inmediatamente despues de la venta - [CA-212-5] Venta aparece en historial local con indicador de pendiente #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-212-01 | Modificar flujo de venta para detectar modo offline | 2h | | MCH-TT-212-02 | Implementar guardado local de ventas en SQLite | 3h | | MCH-TT-212-03 | Actualizar UI para mostrar estado offline de venta | 2h | | MCH-TT-212-04 | Implementar actualizacion de stock local | 2h | --- ### MCH-US-213: Cola de Operaciones Offline **Story Points:** 3 **Como** sistema de sincronizacion **Quiero** una cola que almacene operaciones realizadas offline **Para** procesarlas ordenadamente cuando se recupere la conexion #### Criterios de Aceptacion - [CA-213-1] Operaciones offline se encolan en tabla sync_queue - [CA-213-2] Cola procesa operaciones en orden FIFO cuando hay conexion - [CA-213-3] Operaciones fallidas se reintentan hasta 3 veces - [CA-213-4] Estado de cada operacion se actualiza (pending, syncing, synced, failed) - [CA-213-5] IDs locales se actualizan con IDs del servidor tras sync exitoso #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-213-01 | Implementar servicio de cola de operaciones | 3h | | MCH-TT-213-02 | Implementar procesador de cola con reintentos | 3h | | MCH-TT-213-03 | Implementar actualizacion de IDs locales post-sync | 2h | | MCH-TT-213-04 | Agregar logging y metricas de operaciones | 1h | --- ### MCH-US-214: Resolucion de Conflictos **Story Points:** 3 **Como** sistema de sincronizacion **Quiero** resolver automaticamente conflictos entre datos locales y remotos **Para** mantener la integridad de datos sin intervencion manual #### Criterios de Aceptacion - [CA-214-1] Conflictos se resuelven usando estrategia Last Write Wins basada en updated_at - [CA-214-2] Campos no conflictivos se fusionan (merge) - [CA-214-3] Ventas offline con productos eliminados se manejan correctamente - [CA-214-4] Stock negativo genera alerta al dueno para ajuste manual - [CA-214-5] Conflictos resueltos se registran en log para auditoria #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-214-01 | Implementar comparador de timestamps para Last Write Wins | 2h | | MCH-TT-214-02 | Implementar logica de merge para campos no conflictivos | 3h | | MCH-TT-214-03 | Manejar caso de producto eliminado en servidor | 2h | | MCH-TT-214-04 | Implementar alertas para stock negativo | 2h | | MCH-TT-214-05 | Agregar registro de conflictos resueltos | 1h | --- ### MCH-US-215: Indicador de Estado de Conexion **Story Points:** 2 **Como** usuario de la app **Quiero** ver claramente si estoy online u offline **Para** saber si mis cambios se estan sincronizando #### Criterios de Aceptacion - [CA-215-1] Icono en header muestra estado: verde (online), amarillo (sync pendiente), rojo (offline) - [CA-215-2] Banner aparece cuando se detecta modo offline - [CA-215-3] Modal de progreso muestra estado de sincronizacion por tabla - [CA-215-4] Errores de sync se muestran claramente al usuario - [CA-215-5] Transiciones de estado son suaves y no intrusivas #### Tareas | ID | Tarea | Estimacion | |----|-------|------------| | MCH-TT-215-01 | Implementar ConnectionIndicator con iconos de estado | 2h | | MCH-TT-215-02 | Implementar OfflineBanner con mensaje contextual | 2h | | MCH-TT-215-03 | Implementar SyncProgress modal con progreso por tabla | 3h | | MCH-TT-215-04 | Integrar NetInfo para deteccion de conexion | 1h | | MCH-TT-215-05 | Agregar animaciones y transiciones de estado | 1h | --- ### Resumen de Historias de Usuario | ID | Historia | Story Points | Estado | |----|----------|--------------|--------| | MCH-US-210 | Base de Datos Local SQLite | 5 | Completado | | MCH-US-211 | Sincronizacion Bidireccional | 5 | Completado | | MCH-US-212 | Ventas sin Conexion | 3 | Completado | | MCH-US-213 | Cola de Operaciones Offline | 3 | Completado | | MCH-US-214 | Resolucion de Conflictos | 3 | Completado | | MCH-US-215 | Indicador de Estado de Conexion | 2 | Completado | | **Total** | | **21** | | ## Entregables | Entregable | Estado | Archivo | |------------|--------|---------| | AsyncStorage setup | Completado | `mobile/src/services/offlineStorage.ts` | | Sync engine | Completado | `mobile/src/contexts/OfflineSyncContext.tsx` | | Offline queue | Completado | `mobile/src/contexts/OfflineSyncContext.tsx` | | ConnectionIndicator | Completado | `mobile/src/components/ConnectionIndicator.tsx` | | OfflineBanner | Completado | `mobile/src/components/OfflineBanner.tsx` | | SyncProgress | Completado | `mobile/src/components/SyncProgress.tsx` | ## Dependencias ### Depende de - MCH-004 (Sales module) - MCH-003 (Products module) - App movil base ### Bloquea a - Ninguno (mejora de UX) ## Criterios de Aceptacion - [x] App funciona sin conexion - [x] Ventas se guardan offline - [x] Sync funciona al reconectar - [x] Conflictos se resuelven - [x] Indicador de estado visible ## Limitaciones Offline | Funcion | Disponible Offline | |---------|-------------------| | Ver productos | Si | | Hacer venta (efectivo) | Si | | Hacer venta (tarjeta) | No | | Ver clientes | Si | | Chat IA | No | | Reportes | No | | Configuracion | Solo lectura | --- **Ultima actualizacion:** 2026-01-17