# Erfaring: Adapter-mønster for PG ↔ SpacetimeDB ## 1. Mønsteret som fungerte Et felles interface (`ChatConnection`) med to implementasjoner: - **PG-adapter** — polling hvert 3 sek, full-fetch, ingen ekstern avhengighet utover REST API - **SpacetimeDB hybrid-adapter** — PG for historikk + SpacetimeDB WebSocket for sanntidspush Factory-funksjon velger adapter basert på miljøvariabel (`VITE_SPACETIMEDB_URL`). ``` ChatBlock.svelte → createChat() → PG-adapter (fallback) → SpacetimeDB hybrid (hvis URL er satt) ``` **Fordeler:** - Kan teste PG-adapter isolert uten Docker/SpacetimeDB - Fallback er trivielt — fjern env-variabelen - Komponenten vet ingenting om hvilken adapter som brukes **Referanse:** `web/src/lib/chat/` — hele mappen er organisert etter dette mønsteret. ## 2. Anti-pattern: Lazy wrapper som bytter adapter Vi prøvde først en "lazy wrapper" som startet med PG-adapter og byttet til SpacetimeDB-adapter når tilkoblingen var klar. Problemet: - En plain `let activeConnection` i wrapperen er **ikke reaktiv** i Svelte 5 - Når wrapperen byttet adapter, forsvant meldingene — ny adapter startet med tom liste - Svelte-komponentene så aldri byttet fordi proxy-referansen ikke oppdaterte seg **Lærdom:** Ikke bytt adapter runtime. Velg én ved oppstart. Hybrid-adapteren løser problemet bedre — den bruker begge kilder samtidig i stedet for å bytte mellom dem. ## 3. Hybrid fremfor ren SpacetimeDB Ren SpacetimeDB-tilnærming krever "oppvarming" — lasting av historikk fra PG inn i SpacetimeDB ved oppstart. Dette skaper: - Kompleksitet i Rust-modulen (load_messages-reducer) - Konfliktrisiko under oppvarming (§8.1 i synkronisering.md) - Tom chat inntil oppvarming er ferdig **Hybrid-løsningen:** Frontend henter PG-historikk via REST (umiddelbart tilgjengelig) og lytter på SpacetimeDB kun for *nye* meldinger. Deduplisering skjer i klienten (sjekk mot eksisterende IDer). **Fordeler:** - Ingen oppvarming nødvendig - Historikk er alltid tilgjengelig, selv om SpacetimeDB er nede - SpacetimeDB-modulen trenger bare håndtere nye meldinger, ikke historikk ## 4. Graceful degradation — stille feilhåndtering SpacetimeDB-adaptere bør **aldri** vise feilmelding til brukeren ved tilkoblingsproblemer. PG-data er allerede lastet — brukeren har en fungerende chat. ```typescript .onConnectError((_ctx, err) => { console.warn('[spacetime] connection error, PG-data beholdes:', err); // Ingen error-state til UI — PG-data er intakt }) ``` ## 5. Anbefaling for neste komponent Når Kanban eller Whiteboard skal bygges med SpacetimeDB: 1. **Start med PG-adapter.** Få hele flyten til å fungere med REST/polling først. 2. **Lag SpacetimeDB hybrid-adapter.** PG for historikk, SpacetimeDB for sanntid. 3. **Bruk samme factory-mønster.** Felles interface, env-variabel for valg. 4. **Test begge adaptere uavhengig** før du integrerer i UI-komponenten.