Files
collective-lists/plan/fase-2b-realtime-modo-compra.md
Oier Bravo Urtasun b297d253d9 fix(auth+pwa): resolve stuck-loading race condition and PWA build error
Auth: `getSession()` in a SvelteKit load function races with Supabase's async
localStorage init and can return null for a valid session, triggering a spurious
login() redirect. Moved auth redirect to (app)/+layout.svelte via $effect, which
correctly waits for onAuthStateChange to fire. Also fixed collective data never
loading on page refresh (INITIAL_SESSION event, not SIGNED_IN).

PWA: SvelteKit blocks Workbox imports in src/service-worker.ts, preventing
@vite-pwa/sveltekit from finding the compiled SW output. Switched to generateSW
strategy (plugin auto-generates the SW). Custom SW deferred to Fase 2b using
src/sw.ts (a filename SvelteKit does not intercept).

Docs: added gotchas 6–8 to CLAUDE.md covering both root causes so they are not
reintroduced. Updated plan/fase-2b with the sw.ts workaround note.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 21:44:14 +02:00

43 lines
3.0 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.
### Fase 2b — Sincronización en Tiempo Real y Modo Compra
**Duración estimada: 23 semanas**
**Objetivo: el diferencial del producto. Es la fase más compleja técnicamente.**
#### 2b.1 Sincronización Realtime
- [ ] Suscripción a `Postgres Changes` de Supabase Realtime sobre `items_compra` filtrada por `lista_id`
- [ ] Suscripción a `Presence` de Supabase Realtime para indicador de miembros presentes en lista
- [ ] Store Svelte `realtimeSync`:
- Gestiona el ciclo de vida de las suscripciones (subscribe/unsubscribe al entrar/salir de la lista)
- Aplica cambios remotos al estado local sin causar bucles
- Detecta conflicto last-write-wins: si el `updated_at` remoto > local, aplica remoto y muestra aviso visual
#### 2b.2 Offline-First
- [ ] Instalación y configuración de `idb` (wrapper de IndexedDB)
- [ ] Esquema local en IndexedDB: `pending_ops`, `listas_cache`, `items_cache`
- [ ] Cola de operaciones pendientes: cada mutación se escribe en `pending_ops` antes de llamar a Supabase
- [ ] Service Worker (`@vite-pwa/sveltekit` + Workbox):
- **NOTA TÉCNICA:** SvelteKit intercepta `src/service-worker.ts` y bloquea imports externos (solo permite `$service-worker` y `$env/static/public`). Para usar Workbox con `injectManifest` hay que nombrar el fichero `src/sw.ts` (SvelteKit no lo reconoce como SW) y configurar `strategies: 'injectManifest'`, `filename: 'sw.ts'` en `vite.config.ts`. Actualmente el plugin usa `generateSW` (SW auto-generado, precaching básico).
- Cache-first para assets estáticos
- Network-first con fallback a caché para rutas de la app
- Background sync para flush de `pending_ops` al recuperar conexión
- Fallback manual `online` event (Safari no soporta Background Sync API)
- [ ] Fallback manual de sync: al detectar `online` en el evento del navegador, flush de la cola (cubre Safari que no soporta Background Sync API)
- [ ] Indicador de estado de sincronización en la UI: `sincronizado | sincronizando | sin conexión`
#### 2b.3 Modo Compra
- [ ] Ruta `/listas/[id]/compra` — UI dedicada al Modo Compra:
- Ítems en formato grande (mínimo 64px de altura), optimizado para pulsar con el pulgar
- Reordenamiento automático al marcar: pendientes arriba, marcados abajo (animación fluida con `flip`)
- Indicador de presencia: avatares de miembros que tienen la lista abierta simultáneamente
- Banner `sin conexión` cuando no hay red (los cambios se guardan en local)
- Botón prominente **"Finalizar compra"** — confirmación modal → lista pasa a `completada`
- Notificación push (si el usuario ha dado permiso) a otros miembros al finalizar
- [ ] Rendimiento: 60fps en gama media, tap < 100ms (validar en Chrome DevTools con throttling)
- [ ] Prueba de sincronización: dos dispositivos, misma lista, cambios visibles en < 1 segundo
**Criterio de aceptación:** dos personas en el mismo supermercado, con cobertura inestable, pueden marcar ítems desde sus móviles y verse los cambios mutuamente en tiempo real. Si se pierde la conexión, los cambios locales se sincronizan al recuperarla.
---