Blog
Build in Public
26 de marzo de 20268 min

Sprint de calidad: corregir los errores silenciosos que provocan la desinstalación

Un recordatorio que desaparece sin avisar, un correo electrónico que nunca llega, un error fantasma al iniciar: estos errores no son noticia en un changelog, pero destruyen la confianza de tus usuarios. En un día de sprint de calidad, corregí cuatro problemas silenciosos en TAMSIV — mi gestor de tareas por voz para Android — y la experiencia diaria cambió radicalmente.

Puntos clave a recordar:
- Los errores silenciosos (recordatorios eliminados, correos electrónicos mudos, errores fugaces) causan más desinstalaciones que los fallos visibles.
- Activar push Y correo electrónico por defecto para los recordatorios elimina el 90% de los tickets "no fui notificado".
- Un sprint de calidad sin nuevas funciones es la inversión más rentable para la retención de usuarios.
- La traducción completa de cada funcionalidad (aquí las insignias en 6 idiomas) es una señal de respeto hacia los usuarios internacionales.
Desarrollador trabajando de noche frente a pantallas de código, ambiente cálido de lámpara de escritorio
Los sprints de calidad a menudo ocurren tarde por la noche, cuando finalmente puedes concentrarte en los detalles que importan.

¿Por qué un sprint de calidad es más importante que una nueva función?

Cuando desarrollas una aplicación en solitario, la tentación es constante: añadir funcionalidades. Un nuevo filtro aquí, una integración allá. Es gratificante, se muestra fácilmente en una captura de pantalla, hace un bonito commit.

Pero la realidad es que los usuarios no desinstalan una aplicación porque le falte una función. La desinstalan porque un recordatorio no funcionó. Porque un correo electrónico nunca llegó. Porque apareció un error incomprensible al iniciar.

Según un estudio de UserTesting, el 88% de los usuarios nunca regresan después de una mala experiencia. Y los errores silenciosos — aquellos que no hacen que la aplicación falle, pero que erosionan la confianza — son los más peligrosos. No recibes un informe de fallo. El usuario no reporta nada. Simplemente se va.

Por eso decidí dedicar un día entero a un sprint 100% de calidad. Sin nuevas funcionalidades. Sin refactorizaciones ambiciosas. Solo cuatro correcciones quirúrgicas que, juntas, realmente cambian la experiencia diaria de TAMSIV.

¿Cómo pueden desaparecer los recordatorios válidos en silencio?

El escenario: creas una tarea con tres recordatorios — uno en 10 minutos, uno mañana por la mañana, uno el viernes. Excepto que el primer recordatorio ya está en el pasado (tardaste demasiado en validar). TAMSIV mostraba una advertencia: "Este recordatorio está en el pasado". Hasta ahí, lógico.

¿El problema? Al cerrar esa advertencia, todos los recordatorios eran eliminados. Los dos recordatorios futuros, perfectamente válidos, se iban con él. Una limpieza un poco demasiado celosa en el código de validación.

Este tipo de error es particularmente vicioso. El usuario ni siquiera sabe que sus recordatorios han desaparecido. Espera la notificación de mañana por la mañana... que nunca llegará. Y culpará a la aplicación — con razón.

La corrección técnica

La solución consistió en separar claramente los recordatorios pasados de los recordatorios futuros en la lógica de validación. Concretamente:

  • Filtro temporal: solo los recordatorios cuya fecha es anterior a Date.now() se marcan como caducados.
  • Advertencia dirigida: el mensaje de alerta solo concierne a los recordatorios que realmente están en el pasado, con su número exacto.
  • Conservación garantizada: los recordatorios futuros permanecen intactos, sin importar lo que el usuario haga con la advertencia.
  • Zonas horarias: aproveché para reforzar la gestión de las zonas horarias en la validación — un caso límite que había subestimado.

El sistema de recordatorios y recurrencias es un pilar de TAMSIV. Un error aquí, incluso mínimo, tiene un impacto desproporcionado en la confianza del usuario.

¿Por qué los correos electrónicos de recordatorio nunca llegaban?

TAMSIV soporta dos canales de notificación para los recordatorios: el push (notificación en el teléfono) y el correo electrónico. En teoría. En la práctica, cuando un usuario creaba un recordatorio, solo el canal push estaba activo por defecto. ¿El correo electrónico? Desactivado. Silenciosamente.

Smartphone mostrando iconos de notificación de correo electrónico y push sobre fondo oscuro
Push y correo electrónico: ambos canales deben estar activos por defecto para cubrir todos los contextos de uso.

Si no ibas manualmente a marcar "correo electrónico" en la configuración del recordatorio, nunca recibías nada en tu bandeja de entrada. Sin error, sin mensaje — solo el silencio. Y para un usuario que no consulta sistemáticamente su teléfono, es un recordatorio completamente perdido.

¿Cuál es el valor por defecto correcto para los canales de notificación?

La pregunta parece trivial, pero no lo es. Como recomienda el Nielsen Norman Group en sus investigaciones sobre los valores por defecto, el valor por defecto debe corresponder a lo que la mayoría de los usuarios espera. Y la mayoría espera ser notificada — por todos los canales disponibles.

Ahora, ambos canales están activos por defecto. Recibes un push y un correo electrónico. Si quieres desactivar uno de los dos, siempre es posible, pero el comportamiento por defecto es el que todo el mundo espera. Es el principio del sane default — un concepto central en el diseño de aplicaciones de productividad.

¿De dónde viene ese error "Invalid Refresh Token" al iniciar?

Este es el tipo de error que no rompe nada, pero que socava la confianza. Abres la aplicación después de unas horas de inactividad, y durante una fracción de segundo, un error "Invalid Refresh Token" parpadea en la pantalla. Luego todo funciona normalmente.

Imagina: abres TAMSIV por la mañana para ver tus tareas del día, y lo primero que ves es un error. No sabes lo que significa. No sabes si tus datos están seguros. No sabes si la aplicación funciona correctamente. Aunque todo esté perfectamente bien en realidad, la impresión es desastrosa.

El análisis técnico del problema

Al iniciar en frío, Supabase Auth intentaba refrescar el token de autenticación. Si el token había caducado (después de unas horas de inactividad), el SDK lanzaba un error antes de que el mecanismo de reconexión automática tuviera tiempo de hacer su trabajo.

El error llegaba hasta la interfaz de usuario cuando no tenía ninguna razón para estar allí — la reconexión siempre terminaba por tener éxito. Es un patrón clásico en las aplicaciones que utilizan tokens JWT con refresco automático: la primera llamada falla, el refresco se activa, la segunda llamada tiene éxito.

La corrección intercepta este error específico (AuthApiError con el código invalid_refresh_token) en el nivel correcto y lo elimina de la visualización. El refresco de sesión sigue funcionando exactamente como antes, pero el usuario ya no ve un mensaje ansiógeno que no le concierne.

Este tipo de gestión de errores es crítico para cualquier aplicación que utilice la autenticación Supabase. El SDK hace bien su trabajo — solo hay que evitar exponer sus errores intermedios al usuario.

¿Cómo traducir un sistema de gamificación a 6 idiomas?

TAMSIV está disponible en francés, inglés, alemán, español, italiano y portugués. El sistema de gamificación — niveles, insignias, rachas — forma parte de las funcionalidades que los usuarios descubren progresivamente. Excepto que la guía explicativa de las insignias solo existía en francés e inglés.

Globo rodeado de banderas y símbolos que representan seis idiomas diferentes
Traducir cada elemento de la interfaz es una inversión que rinde a largo plazo.

Es un problema más sutil de lo que parece. Un usuario germanoparlante que descubre el sistema de insignias y se encuentra con un texto en francés o inglés sentirá inmediatamente que esa parte de la aplicación no está terminada. Es una señal negativa muy fuerte, especialmente cuando el resto de la interfaz está correctamente traducida.

El proceso de internacionalización de las insignias

Las 10 insignias de TAMSIV tienen cada una un nombre, una descripción y condiciones de desbloqueo. Esto significa 30 cadenas de texto a traducir a 4 idiomas adicionales (alemán, español, italiano, portugués). El sistema de internacionalización en 6 idiomas que implementé lo gestiona con un pipeline de traducción automática a través de OpenRouter, seguido de una revisión manual para los términos de gamificación.

No es una solución espectacular, pero es el tipo de detalle que hace que un usuario lusófono o germanoparlante se sienta como en casa en la aplicación. Y como explica CSA Research, el 76% de los consumidores prefieren comprar productos en su propio idioma.

¿Cuál es el impacto real de estas correcciones en la retención?

Estas cuatro correcciones representan un día de trabajo. Ninguna habría sido un título emocionante en un changelog. Pero juntas, eliminan fricciones reales:

  • Recordatorios perdidos: ningún recordatorio válido desaparece después de una advertencia sobre un recordatorio caducado.
  • Correos electrónicos perdidos: ambos canales de notificación están activos por defecto, sin sorpresas.
  • Error al iniciar: el mensaje "Invalid Refresh Token" ya no se muestra.
  • Gamificación traducida: las 10 insignias están disponibles en los 6 idiomas soportados.

En términos de retención, cada uno de estos errores era un punto de fricción invisible. El usuario no reporta "tu correo electrónico de recordatorio no llegó" — simplemente piensa que la aplicación no funciona y la desinstala. Según Adjust, la tasa de retención promedio de una aplicación en el día 30 es del 6%. Cada fricción eliminada empuja esta cifra hacia arriba.

¿Cómo organizar un sprint de calidad cuando eres un desarrollador en solitario?

Ser desarrollador en solitario en un proyecto como TAMSIV significa que nadie va a planificar un sprint de calidad por ti. Aquí está el método que utilizo:

  1. Usar tu propia aplicación diariamente — el dogfooding es la mejor fuente de errores. Cada irritación anotada en una nota de voz (con TAMSIV, obviamente).
  2. Priorizar por impacto en el usuario — un error que afecta al 100% de los usuarios en cada inicio tiene prioridad sobre un error que afecta al 2% de los casos.
  3. Limitar el alcance — un día, máximo 4 correcciones. Sin refactorizaciones tentadoras en el camino.
  4. Probar en dispositivos reales — los 12 beta-testers están para eso. Un error reproducido en 3 dispositivos diferentes es un error real.

El sprint sin funciones que hice la semana siguiente confirmó este enfoque: los comentarios de los beta-testers fueron mucho mejores después de estas correcciones silenciosas que después de añadir nuevas funcionalidades.

Preguntas frecuentes

¿Cuánto tiempo se necesita para un sprint de calidad eficaz?

Un día concentrado es suficiente para 3 a 5 correcciones específicas. Lo importante es no mezclarlo con el desarrollo de funciones — el contexto mental es diferente. Recomiendo un sprint de calidad cada 2 semanas para un proyecto en fase de lanzamiento.

¿Cómo detectar errores silenciosos cuando no hay informes de fallos?

El dogfooding diario es el método número uno. Usa tu propia aplicación como un usuario normal, no como un desarrollador. Herramientas como Firebase Analytics también ayudan a detectar patrones anormales (sesiones muy cortas, funcionalidades nunca utilizadas).

¿Por qué activar push Y correo electrónico por defecto en lugar de dejar que el usuario elija?

Porque la mayoría de los usuarios nunca cambian la configuración por defecto (investigaciones del Nielsen Norman Group). El opt-out es más respetuoso que el opt-in para las notificaciones de recordatorio — el usuario ha solicitado explícitamente ser recordado, espera recibir la notificación en todos los canales disponibles.

¿El error "Invalid Refresh Token" es peligroso para los datos?

No, en absoluto. Es un error intermedio normal en el flujo de refresco de tokens JWT. Supabase Auth lo gestiona automáticamente — el token caducado es reemplazado por uno nuevo en segundo plano. El problema era únicamente la visualización de este error técnico al usuario.

¿Cómo gestionar la traducción de términos de gamificación (insignias, niveles)?

Utilizo un pipeline de traducción automática a través de OpenRouter, seguido de una revisión para los términos específicos de los juegos. Algunos términos como "streak" o "badge" a menudo se mantienen en inglés incluso en las versiones localizadas, ya que son universalmente comprendidos por los usuarios de aplicaciones móviles.