Planteamiento y alcance
Esta pregunta de diseño de sistemas frontend combina gestión de estado y actualizaciones distribuidas. La respuesta debe conectar datos locales, una cola de mutaciones, versiones del servidor y estados de recuperación visibles en lugar de limitarse a agregar una caché.
Qué evalúa el entrevistador
- Separar borradores locales, mutaciones pendientes y el estado confirmado por el servidor.
- Elegir una estrategia de conflictos e identificar campos que no pueden fusionarse automáticamente.
- Manejar reintentos, envíos duplicados, navegadores cerrados y múltiples pestañas.
- Hacer que los estados de sin conexión, sincronizando, conflicto y fallo sean comprensibles y recuperables.
Preguntas aclaratorias para hacer
Pregunta si los campos son independientes y si alguno es auditado o de alto riesgo, como montos de dinero. Aclara los adjuntos, el soporte de versiones o registros de operaciones en el servidor, si la estrategia de última escritura gana (last-write-wins) es aceptable, la compatibilidad de navegadores y los requisitos de retención local.
La respuesta de 30 segundos
Usaría IndexedDB como almacenamiento local duradero y registraría cada edición con un clientMutationId y una versión base del servidor. La interfaz de usuario muestra el resultado local inmediatamente y lo marca como pendiente. La aplicación o un service worker envía la cola cuando hay conexión. El servidor responde con éxito, conflicto o fallo de validación mediante comprobaciones de versión e idempotencia. Los campos seguros pueden fusionarse automáticamente; los de alto riesgo muestran una diferencia (diff) para una elección explícita. Cada estado admite reintentos o deshacer.
Análisis detallado paso a paso
1. Definir primero el modelo de estado
Cada borrador tiene serverVersion, localVersion, syncState y lastError. Cada mutación pendiente almacena clientMutationId, los cambios de campos, la hora de creación y la versión base. Las lecturas provienen del almacenamiento local; las respuestas de red se fusionan solo después de las comprobaciones de versión, de modo que una respuesta anterior no pueda sobrescribir una edición más reciente.
2. Persistir hechos recuperables en IndexedDB
IndexedDB se adapta a datos estructurados sin conexión más grandes, pero el diseño debe manejar actualizaciones de esquema, errores de cuota y desalojos por parte del navegador. Almacena borradores, registros de mutaciones y conflictos por separado, y confirma un borrador junto con su registro en cola en una sola transacción. Minimiza los campos sensibles y bórralos al cerrar sesión o al expirar.
3. Diseñar disparadores de sincronización e idempotencia
Intenta el envío inmediatamente cuando esté en línea y ponlo en cola cuando esté desconectado. Donde se admita Background Sync, registra una etiqueta única para el service worker, pero no trates la API como una garantía universal de entrega. Cada solicitud lleva clientMutationId y una versión base; repetir el mismo ID devuelve el mismo resultado sin aplicar la mutación dos veces.
4. Emparejar la política de conflictos con el riesgo del campo
Los campos independientes, como las etiquetas, pueden fusionarse por versión de campo. El dinero, los permisos y las declaraciones de cumplimiento normativo no deben usar silenciosamente la última escritura gana. Ante un conflicto, muestra el valor local, el valor del servidor y las horas de edición lado a lado; la elección del usuario crea una nueva mutación. Las fusiones automáticas deben registrar sus entradas.
5. Manejar fallos, reintentos y múltiples contextos
Usa retroceso exponencial (exponential backoff) mientras preservas el orden de la cola ante fallos de red. Los fallos de validación se convierten en estados de error editables en lugar de reintentos infinitos. Múltiples pestañas pueden coordinarse mediante BroadcastChannel o comprobaciones de versión para que no se envíe una mutación antigua dos veces. Una cola duradera se reanuda en el próximo inicio, y la interfaz de usuario muestra el recuento de pendientes y el último error.
Un ejemplo de respuesta sólida
Definiría primero el riesgo de los campos y los límites de funcionamiento offline. El cliente almacena borradores y una cola de mutaciones en IndexedDB; cada mutación tiene un clientMutationId y un serverVersion base, mientras que la interfaz de usuario muestra de inmediato el resultado local como pendiente. La aplicación o el service worker envía la cola tras reconectarse, y el servidor devuelve éxito, conflicto o error de validación mediante comprobaciones de versión e idempotencia. Los campos independientes pueden fusionarse automáticamente, pero los campos de alto riesgo muestran una diferencia entre local y servidor y requieren confirmación. Los fallos de red aplican retroceso exponencial; los fallos de negocio se vuelven editables. Múltiples pestañas usan notificaciones de versión para que los datos obsoletos no sobrescriban el trabajo más nuevo. La interfaz distingue claramente los estados de sin conexión, sincronizando, conflicto, fallo y guardado.
Errores comunes
- Almacenar en caché solo el último formulario sin una cola de mutaciones o versión base.
- Aplicar marcas de tiempo o la última escritura gana a todos los campos.
- Tratar Background Sync como una garantía en todos los navegadores.
- Reintentar sin una clave de idempotencia y crear duplicados.
- Registrar conflictos solo en la consola sin una ruta de recuperación para el usuario.
- Ignorar actualizaciones de esquema, límites de cuota, múltiples pestañas y el cierre del navegador.
Preguntas de seguimiento y respuestas
¿Qué pasa si dos pestañas editan al mismo tiempo?
Cada pestaña se suscribe a los cambios de versión y solicita una fusión cuando su base está desactualizada. Se vuelve a comprobar la versión antes de enviar; el servidor sigue deduplicando el ID de mutación compartido.
¿Se pueden filtrar los datos sin conexión?
Almacena localmente solo los campos necesarios, cifra el contenido sensible, acorta los periodos de retención y bórralo al cerrar sesión, al usar un dispositivo compartido o ante cambios de políticas.
¿Qué pasa si el navegador no admite Background Sync?
Usa el inicio de la aplicación, el foco de la ventana, los cambios de conectividad y sondeos cortos (short polling) como disparadores de respaldo, e infórmale al usuario que los registros permanecen pendientes. La corrección del sistema no debe depender de esta API.
¿Cuándo es segura una fusión automática?
Solo cuando la semántica de los campos es independiente, la versión base es conocida y la divergencia temporal es aceptable. Los campos de dinero, permisos, inventario y auditoría deben requerir confirmación explícita.