Four planned-fase docs for the first tagged release.
- Fase 17 — semver git tags + CHANGELOG.md (Keep-a-Changelog, [new]/
[fix]/[tweak] prefixes), one big v0.0.0-beta backfill block covering
Fases 0–16, About-modal in /settings rendering bundled CHANGELOG via
?raw import, deploy-script tag check + tag column in .deploys.log.
- Fase 18 — shopping list flow: required title (client + DB tighten),
per-collective per-prefix #N auto-numbering parsed from typed title,
collectives.default_list_title, collective_list_titles catalog + admin
RPCs, autocomplete union (catalog + last-10). Migration 027.
- Fase 19 — EMOJI_CATALOG with faces/food/animals/objects categories
(~280 codepoints, Unicode 14 baseline for iOS<17 compat), new
EmojiPicker.svelte replacing the 8-emoji hardcoded selector at 4
sites. No migration.
- Fase 20 — Euskera locale: messages/eu.json via machine-translate
seed flagged with [needs review], users.language check constraint
extended to ('en','es','eu'), accept-language parser + selector in
/settings. Migration 028. v1.0.0 tag lands at the end of this fase.
README + CLAUDE.md updated with the v1.0 cycle pointers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.4 KiB
7.4 KiB
Fase 20 — Euskera locale (eu)
v1.0 · 4/4. Última fase del ciclo v1.0. Tras cerrarla, se taggea v1.0.0.
Estado: 📋 Planificada. Añadir Euskera (Basque, ISO 639-1 eu) como tercer idioma soportado, sumándose a en y es. Tras esta fase la app está disponible para los hogares vasco-parlantes.
Estado actual (auditado 2026-05-19):
- Paraglide en
apps/web/messages/{en,es}.json. Compile-time tree-shaken por idioma. - Selector de idioma actual:
users.language text(probablementeen|espor check constraint o convención). Auto-detect ya en Fase 10.8. - ~300+ keys en cada locale (estimado por el tamaño actual).
Decisiones clave:
- Machine-translate seed + flag for review (opción B): generar
messages/eu.jsoncon traducción automática (DeepL-formatted-text o GPT-class) marcando cada valor con sufijo[needs review]para que la persona euskera-hablante pueda repasar y borrar el marcador. - Soporte de idiomas declarados en la lista canónica:
apps/web/src/lib/i18n/supported.ts(verificar nombre exacto, puede que viva enparaglideconfig). Añadir'eu'. users.languageaccept'eu'en el check constraint (si existe). Si no hay constraint, añadirlo ahora con 3 valores.- Auto-detect (Fase 10.8): reconocer
eu/eu-ES/eu-FRenaccept-language. - Selector visible:
/settingsya tiene un control de idioma. Añadir opción "Euskera".
20.1 Migración: language check
Fichero: supabase/migrations/028_users_language_eu.sql.
-- Drop the existing check (if it exists; some seeds may not have it).
alter table public.users
drop constraint if exists users_language_check;
-- Re-add with eu allowed.
alter table public.users
add constraint users_language_check
check (language in ('en','es','eu'));
Tareas:
- 20.1.1 Migración 028.
- 20.1.2 Tests pgTAP
supabase/tests/020_users_language_eu.sql:- update a
'eu'accepted. - update a
'fr'rejected by check.
- update a
- 20.1.3
just db-types.
20.2 Locale file
Fichero: nuevo apps/web/messages/eu.json.
- 20.2.1 Pipeline de generación (manual, una vez):
- Tomar
messages/es.jsoncomo source-of-truth (lengua romance + base traductor más fiable hacia euskera queen). - Traducir cada valor con DeepL API o GPT con prompt "Translate to Euskera (Basque), keep ICU placeholders intact, preserve punctuation, formal register".
- Marcar cada valor traducido con sufijo
[needs review]antes del cierre de la string. Excepción: las keys con placeholders ICU ({name},{count}) llevan también el sufijo pero la review debe verificar que los placeholders no se hayan movido a posiciones gramaticalmente raras para euskera (SOV order vs SVO).
- Tomar
- 20.2.2 Validar el JSON: misma key set que
en.jsonyes.json. Scriptscripts/check-locales.mjsque diff las keys y falla si faltan o sobran. - 20.2.3 Bundle Paraglide rebuild:
pnpm --filter @colectivo/web exec paraglide-compile(o cualquiera que sea el comando — verificar enpackage.json).
20.3 Wiring
Ficheros:
apps/web/src/lib/i18n/*(configuración de Paraglide — locales soportados).apps/web/src/lib/utils/accept-language.ts(Fase 10.8 — añadir'eu'al set conocido).apps/web/src/routes/(app)/settings/+page.svelte(selector de idioma).
Tareas:
- 20.3.1 Añadir
'eu'al array de idiomas en la config de Paraglide (project.inlang/settings.jsonu otro fichero del plugin). - 20.3.2
accept-language.tsparser: reconocereu,eu-ES,eu-FR→'eu'. - 20.3.3 Selector de idioma en
/settings: nueva opción "Euskera". Label en cada idioma:en: "Basque"es: "Euskera"eu: "Euskera"
- 20.3.4 Cambiar idioma a
eurecarga Paraglide tags sin reload de página (setLanguageTag('eu')) + escribeusers.language = 'eu'.
20.4 Tests
- 20.4.1 Vitest unit
apps/web/src/lib/utils/accept-language.test.ts(extender):- LANG-U-EU-01
eu→'eu'. - LANG-U-EU-02
eu-ES→'eu'. - LANG-U-EU-03
eu-FR;q=0.5,en→'eu'(preferencia primaria).
- LANG-U-EU-01
- 20.4.2 Vitest integración
language-bootstrap.test.ts(extender):- LANG-INT-EU-01 user setea language=eu, update OK.
- LANG-INT-EU-02 user intenta language='fr' → check constraint violation.
- 20.4.3 Playwright
tests/e2e/euskera.test.ts:- EU-01 Ana cambia idioma a Euskera en
/settings→ strings nav cambian (Listas → "Erosketak", o lo que diga el JSON), sin reload. - EU-02 Eva (usuario nuevo) con header
Accept-Language: eu→ onboarding renderiza en Euskera.
- EU-01 Ana cambia idioma a Euskera en
20.5 Review checklist (post-translation)
Antes del v1.0.0 release, abrir issue/asignar tarea para alguien euskera-hablante:
- 20.5.1 Repasar
messages/eu.json, eliminar el sufijo[needs review]de cada string corregido. - 20.5.2 Para keys con plurales (
item_count_one,item_count_othersi existen), verificar que ambos son correctos (euskera no distingue como inglés/español; puede ser una sola forma). - 20.5.3 Términos del dominio: "colectivo", "lista", "tarea", "nota", "compra". Acordar la traducción con el cliente (no asumir que la máquina la acertó).
20.Z Verificación + cierre
- 20.Z.1
just test-allverde. Suma esperada: +2 pgTAP + 3 unit + 2 integración + 2 e2e = +9. - 20.Z.2 Smoke manual: rotar las 3 pantallas top-level (
/lists,/tasks,/notes) en cada idioma. Ninguna debe mostrar la key cruda (__SKIPPED__o el id). - 20.Z.3 Bundle-size check: el chunk de
eues lazy-loaded por Paraglide; verificar que solo se carga cuando el user lo elige. No debe pesar más quees.json. - 20.Z.4 Entrada en CHANGELOG:
[new] Euskera (Basque) locale (Fase 20). Machine-translated seed pending native review. - 20.Z.5 Documentar en
docs/history/fase-20-euskera-locale.md.
20.ZZ v1.0.0 release
- 20.ZZ.1 Bump
package.jsonversion →1.0.0. - 20.ZZ.2 Editar
CHANGELOG.md: mover entradas de[Unreleased]a## [v1.0.0] — YYYY-MM-DD. Incluir resumen de las 4 fases del ciclo (17–20). - 20.ZZ.3
git tag -a v1.0.0 -m "v1.0.0 — versioning + shopping list flow + emoji avatars + euskera". - 20.ZZ.4 Deploy desde el tag. Smoke en prod.
- 20.ZZ.5 Anuncio interno + nota sobre euskera review.
Riesgos / notas
- Calidad de la traducción automática: euskera no es un idioma soportado de primera por DeepL (verificar fecha actual). GPT-4 class lo hace pero con errores. El sufijo
[needs review]es explícito para no shipear texto incorrecto sin marcar. - ICU placeholders en euskera: el orden de palabras (SOV) puede empujar
{name}a posiciones no naturales en inglés/español. Revisar. - Selector ya soporta
system(auto-detect): por la Fase 10.8 ya hay lógica de fallback. Asegurar queeupropaga por todo el árbol. - Test fixture users: si los seeds (Ana, Borja, …) tienen
language='es'hardcoded, ningún test rompe — solo los nuevos.
Scope explícito fuera
- Galego, Català, Português, Francés. Solo Euskera en este release.
- Pluralización ICU avanzada (one/two/few/many/other) — euskera usa pluralización simple.
- Traducción de los strings de Keycloak (login screen). Ese es el operador del Keycloak externo.
- Localización del CHANGELOG. Solo en inglés.
- Localización de los nombres de los emojis (Fase 19). Aria-label sigue siendo el codepoint name CLDR en inglés.