Volver a la wiki

Version Banner — Auto-aviso de nueva versión tras deploy

Descripción general

El Version Banner es un componente React sticky que detecta en tiempo real cuando se ha desplegado una nueva versión del workspace CreaRack Pro y avisa al usuario con un banner no intrusivo en la parte superior del viewport.

Implementado en la sesión s69 (18-05-2026) como «Opción B» del plan de notificación de versiones: polling cliente → sin WebSockets, sin dependencias extra, compatible con Cloudflare Pages.


Motivación

Los usuarios podían tener el workspace abierto durante horas (o días). Tras un deploy, trabajaban sobre código viejo sin saberlo, lo que podía producir inconsistencias con APIs o comportamientos inesperados. La solución fuerza una decisión informada del usuario sin interrumpir datos no guardados.


Arquitectura

Flujo completo

[CF Pages build]
  └─ node scripts/generate-version.mjs
       └─ escribe public/version.json  { commit_sha, commit_sha_full, build_at }

[Browser, cada 60s]
  └─ fetch('/version.json', { cache: 'no-store' })
       └─ compara commit_sha con el valor inicial
            ├─ igual → nada
            └─ diferente → muestra <VersionBanner />

Archivos implicados

ArchivoRol
scripts/generate-version.mjsScript Node.js que genera public/version.json en cada build
public/version.jsonArtefacto de build (gitignoreado); contiene commit_sha + build_at
src/components/VersionBanner.tsxComponente React con polling + UI del banner
src/layouts/SecondaryLayout.astroMonta <VersionBanner client:load /> en todas las páginas

Componente VersionBanner.tsx

Props: ninguna (self-contained).

Estado interno:

Comportamiento:


Script generate-version.mjs

Escrito en ESM puro (Node.js ≥18). Se ejecuta como paso previo a astro dev y astro build.

Resolución del SHA:

  1. Si existe la env var CF_PAGES_COMMIT_SHA (inyectada por Cloudflare Pages en build), la usa directamente.
  2. Fallback: git rev-parse HEAD mediante execSync.
  3. Si falla ambos: 'unknown'.

Salida (public/version.json):

{
  "commit_sha": "3e6a472",
  "commit_sha_full": "3e6a47239ed9a364e01643d29b5b978f0f44571d",
  "build_at": "2026-05-18T13:03:01.000Z"
}

El archivo está en .gitignore (se regenera en cada build; committearlo causaría ruido en el historial).


Integración en el layout

SecondaryLayout.astro monta el componente con la directiva client:load, que garantiza hidratación inmediata al cargar la página:

<AppLayout title={title} description={description}>
  <VersionBanner client:load />
  <div class="app">
    ...
  </div>
</AppLayout>

Como SecondaryLayout es el layout base de todas las páginas del workspace que extienden AppLayout, el banner queda disponible globalmente.


UX y diseño


Decisiones de diseño (Opción B vs. alternativas)

AlternativaDescartada porque
Opción A — SSE / WebSocket pushRequiere worker CF durable o server-sent events; complejidad desproporcionada para workspace interno
Opción B (esta) — Polling cliente 60sSimple, sin estado servidor, compatible con CF Pages estático. Latencia máxima = 60s
Opción C — Service Worker + cache bustingMayor complejidad de setup; requiere gestionar versiones del SW

Limitaciones conocidas


Historial

SesiónCommitDescripción
s693e6a472Implementación inicial completa

Véase también

Subir