La mejora menor que se convirtió en una migración

La sesión empezó con un pedido chico: poder comparar un snapshot de Scope con cualquier semana anterior, no solo con la inmediatamente previa. Un dropdown, un botón, listo. Veinte minutos.

Terminó doce horas después con el sitio entero caído, trece bugs documentados y una lección de arquitectura que no voy a olvidar.

Así funciona Build in Public de verdad: el alcance crece, los problemas aparecen donde no los esperabas, y el changelog limpio que ves al final esconde un día de pelea.

Qué se construyó: Scope V2.0

Después de la mejora del dropdown, el siguiente pedido era más ambicioso: Scope necesitaba login real y poder compartir proyectos.

Hasta ayer, Scope identificaba usuarios solo con un email escrito en un input — sin contraseña, sin sesión. Funcionaba porque lo usaba yo solo. Pero para invitar a otra persona a ver un avance, eso no alcanza.

V2.0 trae:

Técnicamente: doce endpoints de API reescritos para validar sesión en el servidor, siete endpoints nuevos para el sistema de compartir, dos migraciones de base de datos, un middleware de autenticación, y un frontend con modal de compartir y una landing pública bilingüe para los invitados.

El build pasó limpio. Los 78 tests, verdes. Y ahí empezó la parte difícil.

Trece bugs en cinco rondas

Desplegué a producción confiado. Lo que siguió fueron cinco ciclos de “lo arreglo, lo subo, se rompe distinto”.

El reload loop infinito: la página se recargaba sola cada segundo, parpadeando entre “con sesión” y “sin sesión”. La causa era una configuración de Clerk donde dos parámetros apuntaban a la misma URL y se mandaban redirects entre ellos en bucle.

El ChunkLoadError: el componente de login de Clerk intentaba cargar piezas de su interfaz desde un CDN y fallaba, dejando todo en un estado inconsistente. La solución fue dejar de usar el componente embebido y abrir el login como un modal bajo demanda.

El OAuth que se comía el token: cuando invitabas a alguien con un link, el identificador del proyecto viajaba en la URL — pero el ida y vuelta de Google para autenticar se lo tragaba en el camino. Hubo que guardarlo aparte, en el almacenamiento del navegador, para que sobreviviera el viaje.

Y el peor de todos.

El momento en que se cayó todo

Para que el deploy funcionara, Vercel necesitaba las claves de Clerk como variables de entorno. Las cargué con la herramienta de línea de comandos. Lo que no vi: la herramienta guardó la clave con comillas literales incluidas. El valor real que quedó guardado eran dos comillas y nada más.

El servidor arrancó, el middleware de Clerk intentó validar esa clave inválida, y tiró error. Hasta ahí, esperable.

Lo que no era esperable: el sitio entero devolvía error 500. No solo Scope. La home, los chronicles, las landing pages — todo caído.

¿Por qué? Porque el middleware de autenticación no tenía filtro. Corría en todas las rutas del sitio. Un bug localizado en una herramienta tumbó la corporación completa.

Ahí está la lección, y es de arquitectura, no de Clerk: un error localizado solo derriba todo el sistema si la arquitectura se lo permite. El fix técnico de las comillas tomó diez minutos. El fix de fondo fue poner un filtro: que el middleware de autenticación corra solo en las rutas que lo necesitan. Defensa en profundidad. Si Scope se rompe, que se rompa Scope — no el resto.

Cerrar con orden, no con cansancio

Cuando todo volvió a funcionar — V2.0 y V2.1 en producción, con la opción de eliminar proyectos incluida — quedaba la tentación de cerrar el laptop.

En vez de eso, hice dos cosas.

Documenté los trece bugs en un archivo de aprendizajes de 445 líneas: síntoma, causa raíz, fix, archivo. No para mí — para el próximo proyecto con autenticación, que no va a tropezar con las mismas piedras.

Y le pedí a Linus, el agente que cuida el orden de los repositorios, que auditara todo: ramas huérfanas, cambios sin commitear, stashes viejos. Salió con un puntaje de 78 sobre 100 y una lista clara de limpieza que ejecutamos commit por commit.

Porque el día no termina cuando el código funciona. Termina cuando el repositorio queda en un estado del que el próximo yo no se va a arrepentir.

Qué viene

Scope V2.0 y V2.1 están vivos en olaveruiz.cl/tools/scope. Pendiente: decidir si migrar Clerk de su modo desarrollo a producción real — un setup de una hora que por ahora no se justifica para uso personal.

El aprendizaje que me llevo no es sobre Clerk. Es esto: cuando integrás una dependencia nueva, asumí que va a fallar — y diseñá para que cuando falle, falle contenida.