- Omorganiser docs/: konsepter, features, infra og proposals i egne mapper - Ny docs/erfaringer/ med lærdommer fra chat-implementering (Svelte 5, SpacetimeDB, adapter-mønster) - Oppdater ARCHITECTURE.md: Lag 1 status, ny §10 Erfaringslogg, SpacetimeDB i lokal dev - Oppdater synkronisering.md med implementeringsstatus og designvalg - Oppdater lokal.md med SpacetimeDB og AI Gateway - Utvid PG-skjema med channels, messages, media_files, message_revisions - Legg til seed_dev.sql, migration_safety.md, .env.example - Nye feature-specs: chat, kanban, whiteboard, live_ai, lydmeldinger m.fl. - Nye konsept-specs: studioet, møterommet, redaksjonen, den asynkrone gjesten m.fl. - SpacetimeDB og AI Gateway i docker-compose.dev.yml - collect-docs.sh inkluderer erfaringer/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
2.9 KiB
Markdown
65 lines
2.9 KiB
Markdown
# 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.
|