EGEL Plus Ingeniería de Software study materials
EGEL Plus Ingeniería de Software study resources

Registro de horas con captura offline y conflictos de sincronización

EGEL Plus Ingeniería de Software · Put your knowledge to work in context.

All case studies

Registro de horas con captura offline y conflictos de sincronización

Una consultora de 40 desarrolladores registra horas en una app web. El cliente móvil debe funcionar sin conexión durante visitas a planta (hasta 3 días). Cada entrada tiene: id generado en el dispositivo (UUID), proyecto, fecha, horas (decimales de 15 min) y una marca de actualización. El backend actual usa un endpoint PUT /entries/{id} que sobrescribe la fila completa y devuelve 200. En pruebas, dos consultores que editaron la misma entrada desde dispositivos distintos reportaron que las horas del primero desaparecieron sin aviso. Además, el 8% de los envíos offline fallan con 409 y el cliente los descarta silenciosamente. La gerencia pide 'cero pérdida de datos' antes del cierre trimestral en 3 semanas.

1. Diagnostica la causa raíz de la pérdida de datos y propón el cambio mínimo de contrato de API que la elimine, justificando por qué.

Read the worked answer

Causa raíz: el PUT es una escritura de última-escritura-gana sobre el recurso completo. Quien sincroniza segundo envía su copia entera y pisa los campos que el otro ya había cambiado. El 409 descartado agrava el problema: el cliente interpreta un conflicto legítimo como error transitorio y borra la entrada local, perdiendo la edición.

Cambio mínimo:

  1. Enviar solo el delta con control de versión: PATCH /entries/{id} con cabecera If-Match: <version> (o expectedVersion en el cuerpo). El servidor responde 200 con la nueva versión si coincide, o 409 con el estado actual si no.
  2. Tratar 409 como caso de negocio, no como fallo: el cliente no descarta, guarda la versión del servidor y encola la resolución.

Por qué: el PATCH condicional convierte la escritura ciega en una operación optimista verificada; el servidor es la única autoridad de versión y el cliente nunca sobrescribe lo que no vio.

Regla de merge sugerida: por campo (horas, proyecto), no por fila; si ambos cambian el mismo campo, marcar para revisión del consultor. Esto es determinista y auditable.

2. El 8% de los envíos offline recibe 409. Diseña la política de reintento y resolución en el cliente. ¿Qué NO debe hacer y por qué?

Read the worked answer

Política:

  • No reintentar 409 automáticamente: es determinista; reintentar produce el mismo resultado y bucles. Solo se reintentan 5xx y timeouts, con backoff exponencial + jitter (p. ej. 1s, 2s, 4s… máx 60s, 5 intentos).
  • Encolar el conflicto: mover la entrada a una cola pending-resolution persistente (IndexedDB/SQLite), nunca descartarla.
  • Resolver en el dispositivo cuando sea seguro: si el conflicto es de campos distintos, hacer merge automático y reenviar con la versión nueva. Si es el mismo campo, mostrar al usuario ambas versiones y dejar que elija.
  • Idempotencia: el UUID del cliente garantiza que un reintento de un envío ya aplicado no duplique; el servidor debe devolver 200 con el estado actual en lugar de crear otra fila.

Qué NO hacer:

  • Descartar en 409 (lo que ocurre hoy) → pérdida silenciosa.
  • Reintentar en bucle → el 8% se convierte en carga y nunca se resuelve.
  • Resolver por 'gana el más reciente' sin avisar → repite el problema original con otra cara.

Métrica de aceptación: 0 entradas descartadas; todo 409 termina en resolved o needs-user visible en la UI.

3. Quedan 3 semanas. Prioriza qué entregar y qué posponer para cumplir 'cero pérdida de datos', distinguiendo entre pérdida y conflicto no resuelto.

Read the worked answer

Distinción clave: 'cero pérdida' significa que ningún dato aceptado por el usuario desaparece sin rastro. Un conflicto pendiente visible no es pérdida; un descarte silencioso sí.

Semana 1 (imprescindible):

  • Quitar el descarte en 409; persistir la entrada en cola local con estado.
  • PATCH condicional con versión en servidor.
  • Pruebas de integración: dos dispositivos, edición concurrente, sin red.

Semana 2: merge por campo para el caso seguro; UI mínima de 'conflicto pendiente' (lista + elegir versión).

Semana 3: hardening, telemetría (contador de conflictos y descartes = 0) y rollback.

Posponer: merge automático sofisticado, resolución en tiempo real entre dispositivos, historial completo de versiones. No son necesarios para no perder datos y añaden riesgo.

Riesgo a declarar: si el equipo intenta el merge automático completo en 3 semanas, probablemente incumpla lo imprescindible. Mejor entregar cola + PATCH + UI de conflicto y dejar el merge avanzado para el siguiente ciclo.