Cambios realizados: - Corregido estado de 10 épicas que estaban mal documentadas - MCH-010, MCH-011: Pendiente (submodulos vacíos, BLOQUEANTES) - MCH-012, MCH-013: Pendiente (bloqueados por dependencias) - MCH-006, MCH-007: Pendiente (sin implementación) - MCH-022, MCH-026: Pendiente (sin implementación) - MCH-024, MCH-027: Parcial/Mock (requieren integración real) Documentos nuevos: - ESTADO-REAL-EPICAS.md: Estado validado vs código - ROADMAP-CORREGIDO.md: Plan de desarrollo respetando dependencias Estadísticas reales: - Completadas: 14 (40%) - Parciales/Mock: 4 (11%) - Pendientes: 10 (29%) - Planificadas: 7 (20%) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
393 lines
13 KiB
Markdown
393 lines
13 KiB
Markdown
---
|
|
id: EPIC-MCH-022
|
|
type: Epic
|
|
title: "MCH-022: Modo Offline"
|
|
code: MCH-022
|
|
status: Pendiente
|
|
status_real: "Pendiente"
|
|
status_nota: "Submodulo mobile/ no inicializado"
|
|
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:** Pendiente
|
|
- **Estado Real:** Submodulo vacio - NO IMPLEMENTADO
|
|
- **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 |
|
|
|------------|--------|---------|
|
|
| SQLite setup | Pendiente | `mobile/database/` |
|
|
| Sync engine | Pendiente | `mobile/sync/` |
|
|
| Offline queue | Pendiente | `mobile/sync/queue.ts` |
|
|
| ConnectionIndicator | Pendiente | `mobile/components/` |
|
|
|
|
## 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
|