### Fase 17 — Versioning, git tags + CHANGELOG + about modal **v1.0 · 1/4.** First fase of the v1.0 cycle (post-MVP2). Lands the version-tracking infrastructure that every later v1.0 fase will register entries against. **Estado: 📋 Planificada.** Atiende cuatro asks acoplados: 1. **Git tags** — usar `vMAJOR.MINOR.PATCH` semver. Tag creado localmente; el script de deploy verifica que `HEAD` apunta a un tag antes de empezar (warn pero no bloquea). 2. **CHANGELOG.md** — formato Keep-a-Changelog. Cada release una sección `## [vX.Y.Z] — YYYY-MM-DD` con sub-bloques `### Added / Changed / Fixed`. Cada bullet anotado `[new]`, `[fix]` o `[tweak]`. Backfill de toda la historia previa como una sola sección beta. 3. **About modal en `/settings`** — abre desde la sección "Acerca de" (ya existe el chip de versión, Fase 14.3.4); el modal renderiza `CHANGELOG.md` completo, importado en build-time (`?raw`) — sin fetch en runtime. 4. **v1.0.0** se etiqueta al cierre de Fase 20 (Euskera), no aquí. **Decisiones clave:** - Versión canónica vive en el `package.json` de la raíz (lo usa Fase 14.3 via `__APP_VERSION__`). Bump manual antes de tag. - `CHANGELOG.md` en raíz, no en `docs/`. Tooling como GitHub releases lo busca ahí por convención. - Backfill BETA = **una sola sección** `## [v0.0.0-beta] — 2026-05-19 — MVP + MVP2 (Fases 0–16)` con 30–50 bullets organizados por área (auth, lists, tasks, notes, PWA, infra). Sin sub-secciones por fase — los plan/history docs ya cubren ese nivel. - Modal de changelog: parser markdown ligero (no librería; basta `marked` si ya está en el bundle, si no `String.replace` para `###`/`-`/`**`). Solo renderiza secciones — no enlaces externos. - Tag creation: manual `git tag -a vX.Y.Z -m "..."` por ahora. No automatizar push de tags hasta que el flujo esté probado. --- #### 17.1 CHANGELOG.md backfill **Fichero:** nuevo `CHANGELOG.md` en raíz. **Tareas:** - [ ] **17.1.1** Crear `CHANGELOG.md` con cabecera estándar Keep-a-Changelog: ```markdown # Changelog All notable changes are documented here. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] ## [v0.0.0-beta] — 2026-05-19 — MVP + MVP2 (Fases 0–16) ... ``` - [ ] **17.1.2** Backfill el bloque BETA leyendo cada `docs/history/fase-*.md` + `plan/fase-*.md`. 30–50 bullets agrupados: - **Auth + identity** (Fase 1, 7, 8) - **Shopping lists + items** (Fase 2a, 2b, 4, 5, 7, 10, 11, 15) - **Tasks + notes** (Fase 3, 9.3) - **Search** (Fase 4) - **Mobile UX + accessibility** (Fase 5, 9, 16) - **PWA + offline** (Fase 6, 14) - **Collective management** (Fase 10, 12, 13) - **Server admin** (Fase 13) - **i18n** (Fase 0, 4) - **Infra + deploy** (Fase 0, 6, 8, 14.3, plus the off-stack proxy + Caddy + backup/rollback work) - [ ] **17.1.3** Cada bullet con prefix `[new]` / `[fix]` / `[tweak]`. Ejemplos: - `[new] Item tags scoped per collective + drag-reorder (Fase 11).` - `[fix] auth.users role/aud trigger to keep PostgREST routing past Keycloak provisioning (migrations 013–014).` - `[tweak] Edge proxy off-stack — internal Caddy on :3000 + external TLS terminator.` --- #### 17.2 About modal + changelog viewer **Ficheros:** nuevo `apps/web/src/lib/components/ChangelogModal.svelte`, edits a `apps/web/src/routes/(app)/settings/+page.svelte`. **Tareas:** - [ ] **17.2.1** Importar el CHANGELOG en build-time: añadir `import changelogRaw from '../../../../CHANGELOG.md?raw'` en el módulo del modal. Verificar que el path se resuelve desde `apps/web/` (3 niveles arriba); ajustar si falla bajo el adapter-node. - [ ] **17.2.2** Parser ligero inline: split por líneas, formatear `##`/`###` como headers, `-` como list items, `**text**` como bold via ``. Sin XSS surface — el input es estático del repo, no usuario. - [ ] **17.2.3** `ChangelogModal.svelte`: - Trigger: prop `open: boolean` + `onClose`. - Layout: overlay + panel centered (reusar el patrón de `CreateCollectiveModal.svelte`). - Header: "Historial de cambios" + close icon. - Body: scrollable, max-h-[70vh]. Sticky version chips a la izquierda (opcional). - Cierra con Esc o click en overlay. - [ ] **17.2.4** En `/settings`, debajo del chip de versión existente, añadir un botón discreto "Ver historial" (text-xs subrayado) que setea `showChangelog = true`. --- #### 17.3 Deploy script tag check **Fichero:** `infra/scripts/deploy-erosi.sh`. - [ ] **17.3.1** Al inicio (antes del rsync), si `git describe --exact-match --tags HEAD 2>/dev/null` falla (HEAD no es un tag), imprimir advertencia amarilla: ``` WARNING: HEAD is not at a tagged commit. Deploys without a tag won't map cleanly to CHANGELOG entries. Continue? [5s abort] ``` Sleep 5s con Ctrl-C abort. Si está taggeado, mostrar el tag al lado de la SHA en el banner. - [ ] **17.3.2** Cuando esté en un tag, incluir el tag (no solo la SHA) en `.deploys.log` como columna 4 opcional: `\t\t\t`. Mantener compat: las 3 columnas anteriores siguen ahí. - [ ] **17.3.3** `rollback-erosi.sh --list` muestra el tag si está presente. --- #### 17.4 Tests - [ ] **17.4.1** Vitest unit `apps/web/src/lib/components/ChangelogModal.test.ts`: - CHM-U-01 modal cerrado no renderiza nada. - CHM-U-02 modal abierto renderiza el `

` del CHANGELOG. - CHM-U-03 click en overlay dispara `onClose`. - CHM-U-04 tecla Esc dispara `onClose`. - [ ] **17.4.2** Playwright `tests/e2e/changelog.test.ts`: - CL-01 Ana abre `/settings`, clica "Ver historial", modal aparece con la cabecera "v0.0.0-beta" visible. - CL-02 Esc cierra el modal. - [ ] **17.4.3** Unit linter: chequeo del CHANGELOG con un script `scripts/check-changelog.mjs` que valida (a) cabecera Keep-a-Changelog presente, (b) cada release tiene formato `## [vX.Y.Z] — YYYY-MM-DD`, (c) cada bullet empieza con `[new]`/`[fix]`/`[tweak]`. Wire en `just check`. --- #### 17.Z Verificación + cierre - [ ] **17.Z.1** `just test-all` verde. Suma esperada: +4 unit + 2 e2e + 0 pgTAP = +6. - [ ] **17.Z.2** Smoke: abrir `/settings` en prod, ver el botón "Ver historial", abrir el modal, verificar contenido. - [ ] **17.Z.3** Bump `package.json` version → `1.0.0-rc.0` para empezar el ciclo v1.0 (el `1.0.0` se reserva para el cierre de Fase 20). Tag `v1.0.0-rc.0` desde HEAD. - [ ] **17.Z.4** Documentar en `docs/history/fase-17-versioning-changelog.md`. - [ ] **17.Z.5** Strings Paraglide nuevos: `settings_about_view_changelog`, `changelog_modal_title`, `changelog_modal_close`. --- ### Riesgos / notas - **`?raw` import del CHANGELOG**: Vite lo bundlea como string al servir el módulo. Bundle size sube ~5–20KB. Si crece más allá de eso (varias releases), considerar lazy-load del modal vía dynamic `import()`. - **Tag check no bloquea el deploy**: warn + sleep, no abort. Mantener el flujo "deploy en cualquier commit" disponible para hotfixes urgentes. - **Linter de CHANGELOG**: no fail-loud en pre-commit hooks; rompe el flujo si alguien edita el CHANGELOG manualmente. Mejor warn-only. - **Markdown parser inline**: lo suficiente para Keep-a-Changelog (headers, lists, bold). Si el CHANGELOG crece con tablas, code blocks, links → swap a `marked` (que ya está si se añade un plugin de markdown para algún otro flujo) o `micromark-light`. ### Scope explícito fuera - Auto-generación del changelog desde commits (conventional-commits + standard-version). Manual por ahora. - GitHub Releases sync. Solo tags locales. - Push de tags al remoto desde el deploy script. Manual. - Versionado de la API/REST. Solo del cliente. - Notificación push de "nueva versión" — Fase 14.1 ya cubre el toast.