Así implementé una feature crítica en 1 hora tras recibir feedback de un usuario

De un «no puedo entrar a Savia» de un usuario a una feature en producción con PRD, desarrollo y auditoría en una sola sesión con 3 roles involucrados.

Sabía que iba a pasar. Cuando lancé Savia, la recuperación de contraseña se quedó fuera del MVP deliberadamente. Prioricé el flujo core — que un mentorizado pudiera encontrar un mentor, solicitar una sesión y coordinarla — y aparqué todo lo que no fuera crítico para validar la propuesta de valor. Recuperar contraseña era importante, sí. Pero no era lo que iba a determinar si Savia despertaba algo de interés o no.

Hasta que llegó el feedback que hace daño. Un usuario real no podía entrar a Savia. Llevaba varios minutos perdidos. Me escribió contándomelo para ayudar y como sugerencia, nada enfadado. Sin embargo, me fui a PostHog y había señales de rage click que delataban una frustración evidente. Normal.

Había olvidado su contraseña y no tenía forma de recuperarla. Dead end total. Una versión del producto que dejaba a un usuario atrapado si no podía recuperar su contraseña. Error básico, vaya. No hay login con Google ni ninguna alternativa. Email y contraseña es el único método de acceso, y si la pierdes, pierdes tu cuenta.

La feature para la que pensé “bueno, ya llegará el momento de dedicarle tiempo” se convirtió en necesaria. Quería demostrar a ese usuario que era capaz de darle lo que necesitaba y convertir su feedback en una mejora de producto de manera muy rápida.

De hecho, podría haberle reseteado la contraseña manualmente. Decidí no hacerlo. Le respondí a su email con un: “Gracias por el feedback. Dame un rato, lo soluciono y lo pruebas para confirmar que funciona”.

Definir primero, codear después

Mi primer instinto fue ir directa a implementar. Tengo Claude Code, conozco el codebase, el flujo es estándar. ¿Cuánto podía costar que la IA se ponga a hacerlo directamente?

Pero frené mi instinto. Pensé que era mejor seguir el proceso natural de desarrollo de una feature pero acelerarlo exponencialmente gracias a la IA. Pero no delegarle el criterio y permitir que se pusiera a picar código con un prompt genérico de “implementa recordatorio de contraseña”.

Empecé activando dos skills que tengo configuradas en Claude — una con el rol de Product Manager y otra con el de UX/UI Designer. Les pedí que analizaran el problema antes de tocar una línea de código.

Estas no son skills genéricas. Las he ido construyendo con contexto específico de Savia: conocen la arquitectura, las decisiones de diseño, el tono de voz, las convenciones del código, los patrones de UX que uso. Son archivos markdown que viven en el repositorio del proyecto y que Claude carga cuando los invoco. Cuando los activo, no parten de cero. Parten del proyecto.Cualquiera puede hacer lo mismo: es un archivo de texto con instrucciones, contexto y protocolos. No tiene nada de mágico, pero marca una diferencia enorme en la calidad del output.

Les pedí algo sencillo: “Hay feedback de usuarios de que no tenemos recuperación de contraseña. Quiero que ambos analicéis qué habría que hacer para solucionarlo y me hagáis una propuesta”.

Y lo que salió de esa interación fue útil. El PM identificó 10 consideraciones estratégicas — impacto en retención, riesgo de email bombing, anti-enumeración de usuarios, métricas a trackear. La UX sumó 14 más — dónde colocar el link en login, copy empático, validación en tiempo real, accesibilidad.

Después invocamos a otra skill que tengo con el rol de Software Engineer. Ahí vino algo que no esperaba: detectó que el 80% de la infraestructura ya existía.

El email template para reset de password estaba creado. La ruta de confirmación ya manejaba tokens de recovery. El servidor de correo estaba configurado. La función resetPasswordForEmail() estaba disponible. Simplemente nunca la había invocado.

Esto fue un hallazgo, pero también una señal de alarma. Significaba que cuando definí las features del MVP al principio, ésta se me había colado parcialmente.

Claude la había considerado en su plan de desarrollo inicial, pero la implementó a medias — montó la infraestructura de soporte sin completar el flujo de usuario. Sin un PRD explícito que la definiera, la IA hizo lo que pudo con lo que entendió. Y yo no detecté en ningún momento que eso se nos estaba quedando fuera.Disclaimer: eso fue porque la primera iteración de Savia la hice pasando de propuesta > código. Y ahora he mejorado el flujo pasando de propuesta > PRD > código.

El PRD y la corrección que solo un humano puede hacer

Con todas las consideraciones sobre la mesa, tocaba estructurar. Tengo un template de PRD que fui construyendo y refinando dentro del skill de PM — no es un template genérico, es uno adaptado a cómo trabajo en Savia: incluye Jobs to Be Done, criterios de aceptación con Given/When/Then, edge cases, y un apartado que para mí era clave en este caso: el “why not” — qué pasa si no hacemos esta feature.

En este caso la respuesta era clara: cada usuario que olvide su contraseña se pierde para siempre. Con 10 usuarios activos que tengo ahora mismo, perder 1 es perder el 10% de la base.

Le pedí a Claude que generara el PRD completo usando ese template y los datos del análisis. 4 minutos después tenía un documento con 14 requisitos, 6 escenarios de aceptación y los edge cases cubiertos.

Y entonces pasó algo que para mí resume cómo funciona esta colaboración entre la propuesta que te hace una IA con el contexto que le has dado y el criterio del humano que la IA no puede reemplazar.

Claude propuso un rate limit de 10 peticiones cada 15 minutos para la recuperación de contraseña — el mismo que tenía en login. Yo lo bajé a 3. Nadie legítimo necesita solicitar más de 3 resets en 15 minutos. La IA propone valores razonables; el humano aplica el contexto que la IA no tiene.

Ajustamos el PRD. Definimos el scope, lo que entraba y lo que se quedaba fuera. Quedó así. Si quieres ver el PRD completo, déjame un comentario y te lo comparto en markdown.

Con el PRD aprobado, la implementación fue directa. 4 archivos nuevos, 7 modificados, 11 en total. Build verde, 435 tests passing. Mensaje genérico siempre, tanto si el email existe como si no — para que nadie pueda usar el formulario de reset para averiguar si un email está registrado. Es seguridad básica que muchas apps se saltan.

Y entonces lo desplegué y las rutas no funcionaban

Me llevó un rato depurar el error y detectar qué estaba pasando (Disclaimer: en otro post te contaré cómo estoy aprendiendo a sacar a Claude del bucle cuando se equivoca más de 2 veces con una cosa y se vuelve incapaz de solucionarla sin buenas instrucciones).

Al final dimos con ello: había puesto ñ en la URL — /recuperar-contraseña. El build compiló perfecto. Los tests pasaban. Pero en producción, el servidor no decodifica bien los caracteres especiales en las rutas. Mi ñ se convertía en %C3%B1 y las comparaciones internas fallaban silenciosamente.

Cuando Claude identificó el problema, propuso un fix técnico: interceptar todas las URLs en el middleware y decodificar los caracteres especiales antes de compararlos. Funcionaría, pero era un parche — añadía complejidad a un sitio crítico del sistema para resolver algo que no tenía por qué existir.

Como no se desarrollar, de manera muy inocente le dije: “¿Y si simplemente quitamos la ñ?” /recuperar-contrasena en vez de /recuperar-contraseña. Nueve archivos renombrados, problema eliminado de raíz.

Es el mismo patrón que con el rate limit. La IA tiende a resolver problemas con más código. A veces la mejor solución es cambiar el planteamiento. No necesitas un parche sofisticado si puedes eliminar la causa. Pero eso requiere dar un paso atrás y preguntar “¿por qué estoy resolviendo esto así?” — algo que, al menos hoy, sigue siendo más fácil para un humano que para una IA.

El patrón que se repite

Feedback ? análisis con roles especializados ? PRD ? implementación ? producción. No es un flujo de IA. Es un flujo de producto. Lo que la IA cambia es la velocidad: lo que habrían sido días de trabajo con un equipo distribuido se comprimió en 1 hora con una sola persona activando roles en secuencia.

Pero la velocidad no es lo importante. Lo importante es que en ningún momento delegué una decisión de producto. Corregí el rate limit. Aprobé el PRD. Decidí quitar la ñ en vez de parchear el servidor. La IA amplificó mi capacidad de ejecutar, pero el criterio siguió siendo mío.

Y esa es la parte del vibe coding de la que menos se habla. No es escribir código con prompts. Es tener un equipo que ejecuta a la velocidad que tú piensas — siempre que sepas qué pensar.

Si te apetece probarlo, Savia está en savia.company. Y sí, ahora puedes recuperar tu contraseña.


Artículos anteriores de la serie: