La semana en la que el home de Hezu nos enseñó a odiar el caché del navegador
Carrusel de casos de uso en Hezu, preferencia de retailer en Ganga24, página del equipo en sixsevenapps y un cron de Sofi que se comía 3 horas de CPU. Una semana de cinco productos moviéndose a la vez.
Siete días, cinco productos, y un descubrimiento que ya sabíamos pero que vuelves a aprender cada vez: el caché de Cloudflare es maravilloso hasta que tienes que invalidarlo a mano commit a commit. Esta semana hubo features nuevas, pero también un montón de horas peleándonos con cosas que ya creíamos resueltas. Lo cuento sin maquillaje.
Hezu: el home convertido en obra en directo
Hezu se llevó la mayor parte del esfuerzo. Empezamos la semana cerrando FEAT-020 (la value proposition section, pensada tanto para SEO como para conversión) y de ahí encadenamos FEAT-021 (carrusel infinito de casos de uso con flechas y swipe táctil) y arrancamos FEAT-022, el overhaul completo del home. Tres features grandes en seis días suena bien hasta que miras los commits intermedios.
El carrusel fue un buen ejemplo de por qué el código "sencillo" engaña. La primera versión usaba un keyframe CSS infinito y, al añadir control por flechas, el JS quería mover el transform mientras el CSS seguía animando el suyo. Resultado: el carrusel daba saltos cada vez que pulsabas. La solución fue reescribirlo con requestAnimationFrame y dejar al CSS fuera del bucle de animación. Un detalle aburrido para quien no lo vive, pero exactamente el tipo de bug que solo aparece cuando un usuario real le da a una flecha.
Después vino el otro clásico: el FOUC. El título del hero parpadeaba mostrando "Asistente de crianza" durante medio segundo antes de que arrancara el typewriter. La solución bonita habría sido refactorizar el ciclo de vida del componente. La solución real fue ocultar el elemento con opacity:0 inline desde el primer frame y dejar que JS lo encendiera cuando tocara. Funciona. No es elegante. No nos importa.
Y luego, el caché. Ocho commits seguidos de cache-bust a app.js, ui-manager.js, use-case-handler.js y styles.min.css. El CDN de Cloudflare se aferraba a la versión vieja con un cariño conmovedor. Acabamos bajando el TTL de los JS de 24h a 1h y subiendo el CACHE_VERSION del i18n a 20260403. La lección, ya conocida pero ahora con más cicatriz: si tu producto cambia varias veces al día, un TTL de 24 horas no es caché, es sabotaje.
En paralelo, decisión de marca: quitamos todas las menciones a "IA" del copy de marketing en 22 locales. Hezu sigue funcionando con Gemini por debajo (migrado esta semana a gemini-3-flash-preview, por cierto), pero "asistente con IA" es ya un cliché que aporta cero. Si funciona bien, no necesita el adjetivo.
Ganga24: la guerra perdida contra Cloudflare/LaLiga
En Ganga24, FEAT-020 fue una de esas mejoras que parecen tontas y luego cambian la experiencia: el bot ahora deja elegir preferencia de retailer, y solo ofrece los que de verdad están en el feed (no Amazon si Amazon no aparece esa semana). Pequeño, pero quita ruido.
Lo más curioso fue empezar FEAT-021: bypass de bloqueos Cloudflare/LaLiga vía nginx con HTTPS fallback. Sin entrar en detalles, hay enlaces de afiliado que ciertos ISPs españoles bloquean por el famoso conflicto LaLiga-Cloudflare, y para un agregador de ofertas eso es perder clics literalmente porque tu IP vive en el sitio equivocado. La spec quedó cerrada esta semana con sección QA incluida; implementación la próxima.
Además se montó GA4 con Consent Mode v2 (porque sí, hay que medir), favicon nuevo con el robot, y un fix pequeño pero satisfactorio: las notificaciones del bot ya no exponen el score interno del prefilter. Ese número solo le importaba al equipo, no al usuario que esperaba ver una oferta.
Chordna: SEO y un Gemini deprecado a traición
En Chordna cerramos FEAT-013 (internal linking SEO, fase 3) y FEAT-014 (páginas About y Privacy con footer), y arrancamos FEAT-016, un draft de GEO — Generative Engine Optimization, optimizar para aparecer en respuestas de modelos generativos en lugar de solo en Google. Tema novedoso, todavía discutible cuánto mueve la aguja, lo apuntamos como hipótesis, no como certeza.
Lo divertido fue descubrir un viernes que gemini-2.0-flash-exp estaba deprecated para usuarios nuevos. La canción de siempre: el modelo sigue funcionando para quien ya lo usaba, pero cualquier alta nueva fallaba silenciosamente. Pasamos a gemini-2.5-flash primero y luego a gemini-3-flash-preview en todos los proyectos. Si vives de APIs de modelos, normaliza dedicar un día al mes a esto.
También hubo un round de housekeeping: timeouts en llamadas externas y a Gemini, manejo de errores serio, entidades HTML mal escapadas en JSX, keys de React basados en índice (mal) cambiados a keys estables (bien), y un endpoint request-analysis que ahora habla directo con Firestore en vez de pasar por un proxy. El tipo de limpieza que no celebra nadie y que ahorra horas de debugging futuro.
Sofi: el cron que se comió tres horas de CPU
El día 14 de marzo el evening_summary de Sofi entró en bucle infinito y se comió tres horas de CPU antes de que nadie se diera cuenta. Esta semana fueron los fixes: signal.alarm(0) movido al bloque finally para garantizar que se cancela aunque el cuerpo del cron explote, y alertas de sync que solo saltan después de tres intentos fallidos de recovery (antes alertaba al primero, que era ruido).
La otra pieza grande fue FEAT-015: desacoplar la generación de resúmenes del canal de entrega. Hasta ahora el resumen se generaba con formato Telegram bakeado dentro. Tras el refactor hay un summary_generator que produce contenido neutro, y un delivery_service que lo adapta a cada canal (Telegram, WhatsApp). El contenido es único y multi-canal; solo cambia el formato. Cuando añadamos email o web, el coste de integración debería ser horas, no días.
sixsevenapps: la web que estás leyendo
Y por último, esta web. FEAT-003 (formulario de contacto reutilizable, edge-compatible) y FEAT-004 (sección del equipo presentando a los agentes IA) cerradas y desplegadas. La sección de equipo merece mención: presenta a Elena, Laura, Pablo y Andrea como lo que son, agentes especializados, sin disfrazarlo de "nuestro talento". Honestidad bruta como argumento de marketing.
También pusimos en marcha el pipeline del journal: cron diario a las 7:00 (Madrid), semanal los lunes a las 7:10, con Claude como fallback de Gemini cuando este se queda sin cuota. Hicimos backfill de 99 entradas de tres meses atrás, y rebrandeamos a "Small lab. Big ideas." — más honesto sobre tamaño y ambición que cualquier slogan corporativo.
Semana densa. Cinco productos vivos, una persona, un equipo de agentes que ya se sabe sus papeles. Y un caché de Cloudflare que nos sigue ganando algunas batallas.