Files
collective-lists/CHANGELOG.md
Oier Bravo Urtasun d3b4187119 docs(fase-20): history doc + CHANGELOG [Unreleased] entry
History doc covers: ENUM-vs-CHECK rationale (plan was written against
the wrong primitive — actual gate is the language_code ENUM from
migration 001), machine-translation seed + [needs review] marker,
ICU-placeholder parity verification, locale-keys diff script
contract, and the ParaglideJS {#key lang}-on-navigation cross-cutting
gap that constrained the shape of EU-01.

Test deltas: pgTAP +5, integration +2, unit +4, e2e +2 — 581 + 3
skipped (was 568 + 3). Documents the pre-existing 010_sync_conflicts
flake (offline.test.ts e2e contamination) as out of scope for Fase 20.

CHANGELOG gains the [Unreleased] entry. Moves into [v1.0.0] in the
release commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 04:16:19 +02:00

101 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/).
Each bullet is prefixed with `[new]` (added capability), `[fix]` (resolved
defect) or `[tweak]` (behaviour or implementation change with no new
surface). Areas group related entries; section bullets ending in `:` are
labels for the area, not log entries.
## [Unreleased]
- [new] Required list title + auto-numbered prefix + admin-curated title catalog (Fase 18).
- [new] Emoji picker expanded with full food + animals categories (Fase 19).
- [new] Euskera (Basque) locale (Fase 20). Machine-translated seed pending native review.
## [v0.0.0-beta] — 2026-05-19 — MVP + MVP2 (Fases 016)
Single rollup for everything shipped before tagging started. Covers the
entire MVP cycle (Fases 07) plus the prod auth hardening pass (Fase 8)
and the eight MVP2 fases (916). Reads as a feature catalogue, not a
day-by-day diff — the per-fase docs in `docs/history/` and the per-fase
plans in `plan/` are the source of record.
- Auth + identity:
- [new] Keycloak → GoTrue → Supabase OIDC integration (PKCE), with `auth.users` pre-seed for the 5 dev users (Fase 1).
- [new] Self-registration via Keycloak; invitations are link-only (no email), generated on `/collective/manage` (Fase 1).
- [new] Multi-collective per user with sidebar switcher; active collective persisted to `localStorage` (Fase 1).
- [new] Atomic `create_collective(name, emoji)` RPC so onboarding works in a single round-trip without tripping `is_admin` / `is_member` policies (migration 012, Fase 7).
- [new] Public `/logged-out` route + RP-initiated Keycloak end-session on logout, so the SSO cookie is actually cleared and the next login re-prompts (Fase 8).
- [new] Account hard-delete (`delete_account()` RPC) with sole-admin auto-promote and a Danger-zone modal (migration 021, Fase 10.5).
- [fix] `auth.users.role`/`aud` default-fill trigger so PostgREST routing survives the Keycloak provisioning path; INSERT + UPDATE both covered to defeat GoTrue's pop-ORM re-clobber (migrations 013014, Fases 78).
- [fix] `isLoggingOut` guard in `(app)/+layout.svelte` to suppress the auth-gate `$effect` during the logout navigation, closing a "PKCE code verifier not found in storage" race on prod (Fase 8).
- [fix] `pendingInvitationToken` restored from `sessionStorage` after login so the user lands on `/invitation/<token>` instead of `/onboarding` or `/lists` (Fase 7).
- Shopping lists + items:
- [new] Lists overview (featured + grid + completed + trash) and detail view with checkbox toggle, qty stepper, inline edit, drag-reorder (Fase 2a).
- [new] Frequency-driven suggestion chips on the add-item form, backed by the `item_frequency` table + trigger (Fase 2a; migration 006).
- [new] Realtime "Modo Compra" full-screen session view with 56 px toggles, flip animation, complete-list → redirect; postgres_changes subscription per list with echo-deduplication (Fase 2b; migration 007).
- [new] Offline-first sync queue (`SyncQueue` IDB-backed, FIFO flush, PK-conflict-as-success) with `online`-event auto-flush; offline/syncing banner mounted in detail + session views (Fase 2b).
- [new] Selection mode with bulk delete / move / mark-checked, long-press entry on mobile + desktop toggle button (Fase 5.11).
- [new] Reset-from-detail button on completed lists; "Crear nuevo colectivo" entry in sidebar + drawer (Fase 10).
- [new] Trash drawer restore + hard-delete via `restore_list()` / `hard_delete_list()` RPCs (migration 020, Fase 10.4).
- [new] Collective-scoped item tags (chips + picker + filter bar + realtime resort) backed by `item_tags` + `shopping_item_tags` (migration 022, Fase 11).
- [new] Common-items management on `/collective/manage` — 3-way Hide / Normal / Boost segmented control writing `weight` via admin-only RPCs; suggestion strip reorders by weight + use_count + last_used_at (migration 026, Fase 15).
- [new] Suggestion dropdown excludes names already on the active list (`excludeNames` capped at 200 to respect Kong URI limits) (Fase 15).
- [tweak] Item row redesigned to `drag-handle | name-button | qty stepper` with swipe-to-(un)check; double-tap opens an edit overlay; `unit` column dropped because it became unreachable (migration 011, Fase 5.10).
- [tweak] Add-form moved inline as the last child of the unchecked section; sticky bottom bars retired (Fase 5.14).
- [tweak] List rename inline at the top of the detail view with 500 ms debounced autosave; "New list" button moved to the masthead (Fase 5.8).
- Tasks + notes:
- [new] Task lists + tasks with completion-consistency CHECK (`is_completed ⇔ completed_by ⇔ completed_at`) and drag-reorder (migration 008, Fase 3).
- [new] Notes with 8-colour palette, pinned + archived (mutually exclusive), 7-day trash window enforced via RLS + `pg_cron` purge; editor with 500 ms debounced autosave (migration 009, Fase 3).
- [new] Sync-conflicts review route at `/settings/sync-conflicts`, paginated, side-by-side local vs remote payloads, per-device dismissal via `localStorage` (Fase 14.2).
- Search:
- [new] Cross-section search via `search_in_collective()` SECURITY INVOKER RPC over generated `tsvector` columns on items/tasks/notes; debounced input, filter chips, deep-link per result type (migration 010, Fase 4).
- Mobile UX + accessibility:
- [new] Mobile shell — top bar with hamburger + collective name + avatar, slide-in drawer, bottom tab bar with safe-area inset, sticky contextual headers on detail routes (Fase 5).
- [new] `UndoToast` for destructive actions (4 s TTL, auto-commit, mounted globally), with `scheduleUndoable()` queue (Fase 5).
- [new] Spinner component (`sm/md/lg`, `currentColor`, `motion-reduce:animate-none`, sr-only label) integrated at 7 loading sites (Fase 16).
- [tweak] Desktop reading width capped at `max-w-2xl` for content detail routes; mobile and `/lists/[id]/session` excluded (Fase 9.2).
- PWA + offline:
- [new] Installable PWA — Workbox precaching via `@vite-pwa/sveltekit`, manifest, iOS meta tags + apple-touch icons, placeholder slate-and-"C" icons (Fase 6.2).
- [new] Service-worker auto-registration via `useRegisterSW` + 15 min `reg.update` poll; `UpdateToast` with "Reload" action when a new build is available; "Ready to use offline" auto-dismiss toast (Fase 14.1).
- [new] `OfflineChip` in `MobileTopBar` + `DesktopSidebar` with a pending-ops badge when the queue is non-empty (Fase 14.2).
- [new] Build-time version constants (`__APP_VERSION__` / `__APP_COMMIT__` / `__BUILD_TIME__`) exposed via `$lib/version`; "Acerca de" chip on `/settings`; `GIT_SHA` baked through the Dockerfile build arg by the deploy script (Fase 14.3).
- [tweak] PWA strategy on prod switched to `generateSW` because `@vite-pwa/sveltekit` 0.6.8 hardcodes the source SW filename under `injectManifest` (Fase 6 → revisit in Fase 14).
- [fix] `<link rel="manifest">` added to `app.html` so Android Chrome surfaces the install prompt (Fase 14 follow-up).
- Collective management:
- [new] Rename collective + change emoji (CU-H07) on `/collective/manage` (Fase 10.2).
- [new] Leave-collective flow (CU-H06) with sole-admin auto-promote via `leave_collective()` RPC; sole-member rejected with P0001 (migration 017, Fase 10.1).
- [new] Dissolve-collective flow (CU-H08) with type-the-name confirmation, via `dissolve_collective()` RPC (migration 018, Fase 10.3).
- [new] Section visibility — per-user + per-collective `feature_flags jsonb` + `section_enabled()` STABLE SQL helper using COALESCE precedence (migration 023, Fase 12).
- [new] Auto-detect language on first sign-in from `navigator.languages`, gated to fresh accounts (`<60 s old` + `language = 'en'`) (Fase 10.6).
- [tweak] Every `created_by`/`updated_by` FK relaxed from `NOT NULL RESTRICT` to `NULL SET NULL` so a user delete cascades cleanly (migration 019, Fase 10.5).
- Server admin:
- [new] Global `server_admin` role (`server_admins` table) orthogonal to `collective_members`; `is_server_admin()` SECURITY DEFINER gate; bootstrap from `SERVER_ADMIN_EMAIL` on first DB init (migration 024, Fase 13).
- [new] `/admin` route group with 9 SECURITY DEFINER RPCs (collective lifecycle, member removal, server-level section defaults) + append-only `admin_actions` audit log + last-admin guard (migration 025, Fase 13).
- [new] `section_enabled()` extended with a server layer prepended to the user/collective precedence chain (Fase 13.2).
- i18n:
- [new] Paraglide JS messages for `en` + `es`, compiled at build time; `setLanguageTag()` flips the active locale without reload; selector on `/settings` writes to `public.users.language` (Fase 0).
- [new] Search + collective-management + PWA copy fully localised in both languages across every fase that added user-facing strings (Fases 4, 10, 14).
- Infra + deploy:
- [new] Local dev stack — Docker compose with Postgres / GoTrue / PostgREST / Realtime / Storage / Kong / Keycloak; `setup.sh` for idempotent first-time bring-up; `Justfile` task runner (Fase 0).
- [new] Production stack on ambrosio (OVH VPS) at https://erosi.limonia.net — `infra/scripts/deploy-erosi.sh` (rsync + first-deploy secret generation + every-deploy migration apply + pre-deploy backup + `.deploys.log` append) and `infra/scripts/rollback-erosi.sh` (paired code + DB rollback) (Fase 6 + later iterations).
- [new] Kong rate-limit on `/rest/v1/collective_invitations` (20/hour per Authorization header) with `request-transformer` URI rewrite (Fase 6.3).
- [new] JWT rotation script (`infra/scripts/rotate-jwt.sh`) + production env template + `rls-audit.sh` curl sweep + `just lighthouse` build-and-score recipe (Fase 6.4 + 6.5).
- [new] Internal Caddy on `:3000` fans `/rest|/auth|/realtime|/storage|/graphql|/pg` → Kong, everything else → app; external TLS terminator (off-stack) forwards plain HTTP to ambrosio:3000 (Fase 6 → revision after prod cutover).
- [new] Theme tokens stored as RGB triplets so `dark:` variants resolve consistently; three-mode preference (`light` / `dark` / `system`) persisted to `users.theme` + mirrored to `localStorage` with inline anti-FOUC script (migration 015, Fase 9.1).
- [new] `sync_conflicts` append-only log + queue-side divergence detection so last-write-wins conflicts are auditable (migration 016, Fase 9.3).
- [new] Pre-deploy `pg_dumpall` snapshot kept in `backups/predeploy-*.sql.gz` (newest 10) with paired code/DB rollback via `rollback-erosi.sh --previous` / `--to=<sha>` / `--code-only` (Fase 14 deploy work).
- [fix] `docker compose exec -T` calls inside SSH heredoc deploys now redirect stdin per call so the surrounding heredoc isn't drained — silently skipped migrations no longer happen (Fase 8 deploy hardening).
- [fix] PostgREST schema cache reload (`NOTIFY pgrst, 'reload schema'`) appended after every deploy and rollback so freshly-added RPCs are visible without a container restart (Fase 15 deploy work).
- [fix] WebKit Playwright project gated behind `RUN_WEBKIT=1` so hosts without the GTK libs (libicu74, libwoff1, …) keep `just test-all` green; `*.webkit.test.ts` files excluded from the chromium project (Fase 9.4).