From 286f59225fb5c8555ba3f0b597e20abe9123eba7 Mon Sep 17 00:00:00 2001 From: Oier Bravo Urtasun Date: Mon, 18 May 2026 04:10:19 +0200 Subject: [PATCH] feat(fase-12): nav gating + redirect guard + realtime publication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UI side: * DesktopSidebar / BottomTabBar filter their entries by $enabledSections, tag each entry with data-section, and BottomTabBar exposes a data-section-count attribute so the grid is observable from tests. * "lists" is force-shown unconditionally — the §12.3.4 always-one- landing rule covers the edge case where every layer says OFF. * (app)/+layout.svelte adds a $effect that, when the URL matches a disabled section (/tasks, /notes, /search), goto's /lists and shows a transient `section_disabled_for_collective` toast. * Root +layout.svelte exposes the supabase singleton on window.__sb in dev so the new Playwright spec can patch rows without a parallel client; dead-code-eliminated in production builds. DB side: * Migration 023 grows by ALTER PUBLICATION supabase_realtime ADD TABLE public.users + public.collectives + REPLICA IDENTITY FULL on both. Without this membership the features.ts subscriptions get zero events and SV-02 (collective toggle → realtime → member's nav updates) silently fails. Caught while running the spec. * pgTAP 015 grows from 16 to 20 assertions to cover publication membership + REPLICA IDENTITY for both new realtime tables. Paraglide messages: section_disabled_for_collective, the visibility section titles + blurbs, section_label_* per SectionKey. Both en + es. Playwright tests/e2e/section-visibility.test.ts (SV-01..SV-03): SV-01 user toggle → nav reflects → /tasks redirects to /lists SV-02 admin collective toggle → member sees it disappear in realtime SV-03 collective ON beats user OFF — per-collective resolution Co-Authored-By: Claude Opus 4.7 --- apps/web/messages/en.json | 12 +- apps/web/messages/es.json | 12 +- .../lib/components/layout/BottomTabBar.svelte | 25 ++- .../components/layout/DesktopSidebar.svelte | 24 ++- apps/web/src/routes/(app)/+layout.svelte | 44 ++++ apps/web/src/routes/+layout.svelte | 8 + apps/web/tests/e2e/section-visibility.test.ts | 198 ++++++++++++++++++ .../migrations/023_section_visibility.sql | 17 ++ supabase/tests/015_section_visibility.sql | 44 +++- 9 files changed, 369 insertions(+), 15 deletions(-) create mode 100644 apps/web/tests/e2e/section-visibility.test.ts diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index c30f3fb..082b4f6 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -230,5 +230,15 @@ "settings_tags_section": "Tags", "settings_tags_empty": "No tags yet — create one from any list.", "settings_tags_delete": "Delete", - "settings_tags_color": "Color" + "settings_tags_color": "Color", + "section_disabled_for_collective": "That section is hidden for this collective.", + "settings_section_visibility_title": "Visible sections", + "settings_section_visibility_blurb": "Hide top-level sections you don't use. Your admin can also hide them for the whole collective.", + "settings_section_visibility_overridden": "Hidden by the collective.", + "collective_section_visibility_title": "Collective sections", + "collective_section_visibility_blurb": "Hide sections for every member of this collective. Members can also hide them individually for themselves.", + "section_label_lists": "Lists", + "section_label_tasks": "Tasks", + "section_label_notes": "Notes", + "section_label_search": "Search" } diff --git a/apps/web/messages/es.json b/apps/web/messages/es.json index 96da857..6fbbf25 100644 --- a/apps/web/messages/es.json +++ b/apps/web/messages/es.json @@ -230,5 +230,15 @@ "settings_tags_section": "Etiquetas", "settings_tags_empty": "Aún no hay etiquetas — créalas desde cualquier lista.", "settings_tags_delete": "Eliminar", - "settings_tags_color": "Color" + "settings_tags_color": "Color", + "section_disabled_for_collective": "Esta sección está oculta para este colectivo.", + "settings_section_visibility_title": "Secciones visibles", + "settings_section_visibility_blurb": "Oculta las secciones de nivel superior que no usas. Tu admin también puede ocultarlas para todo el colectivo.", + "settings_section_visibility_overridden": "Oculta por el colectivo.", + "collective_section_visibility_title": "Secciones del colectivo", + "collective_section_visibility_blurb": "Oculta secciones para todos los miembros de este colectivo. Cada miembro también puede ocultarlas para sí.", + "section_label_lists": "Listas", + "section_label_tasks": "Tareas", + "section_label_notes": "Notas", + "section_label_search": "Buscar" } diff --git a/apps/web/src/lib/components/layout/BottomTabBar.svelte b/apps/web/src/lib/components/layout/BottomTabBar.svelte index 3e2e38e..e5e6ae8 100644 --- a/apps/web/src/lib/components/layout/BottomTabBar.svelte +++ b/apps/web/src/lib/components/layout/BottomTabBar.svelte @@ -1,15 +1,26 @@