# Feature Spec: PostgreSQL ↔ SpacetimeDB Synkronisering **Filsti:** `docs/features/synkronisering.md` ## 1. Konsept SpacetimeDB gir sanntidsopplevelsen, PostgreSQL er langtidsminnet. Denne spec-en definerer hvordan data flyter mellom dem, hvem som eier sannheten, og hva som skjer ved feil. ## 2. Strategi: Event-drevet med kort forsinkelse SpacetimeDB-modulene (Rust) produserer persisterings-events ved dataendringer. En Rust-worker konsumerer disse og skriver til PostgreSQL, batched med ~5 sekunders vindu. **Akseptabelt datatap:** Maks 5 sekunder ved hard krasj av SpacetimeDB. Dette er akseptabelt for chat, kanban og show notes. ## 3. Dataflyt ``` ┌──────────────┐ events ┌──────────────┐ batch write ┌──────────────┐ │ SpacetimeDB │ ──────────────► │ Rust Worker │ ────────────────► │ PostgreSQL │ │ (sanntid) │ │ (sync_to_pg) │ │ (persistent)│ └──────────────┘ └──────────────┘ └──────────────┘ ┌──────────────┐ oppvarming (oppstart / reconnect) ┌──────────────┐ │ PostgreSQL │ ──────────────────────────────────────► │ SpacetimeDB │ └──────────────┘ └──────────────┘ ``` ## 4. Eierskapsmodell | Data | Autoritativ kilde | Synkretning | Merknad | |---|---|---|---| | Chatmeldinger | SpacetimeDB | → PG (event, batched) | | | Kanban-posisjon | SpacetimeDB | → PG (event) | | | Show notes | SpacetimeDB | → PG (event) | | | Live studio-markører | SpacetimeDB | → PG (event) | | | Kunnskapsgraf | PostgreSQL | → SpacetimeDB (oppvarming) | Read-only i SpacetimeDB | | Episodemetadata | PostgreSQL | Ingen synk | | | Brukerkontoer | PostgreSQL (Authentik) | Ingen synk | | | Statistikk | PostgreSQL | Ingen synk | | | Valgomat | TBD | TBD | Konseptet må modnes. Mulig PG-autoritativ med SpacetimeDB som serveringslag | ## 5. Mekanisme ### 5.1 SpacetimeDB → PostgreSQL (persistering) - SpacetimeDB-modulene kaller en intern `emit_sync_event()`-funksjon ved relevante dataendringer - Events bufres i en SpacetimeDB-tabell (`sync_outbox`) med tidsstempel og payload - Rust-workeren poller `sync_outbox` hvert ~5 sekund, leser alle usynkede events, skriver til PostgreSQL i én transaksjon, og markerer dem som synket - Ved PG-nedetid: events akkumuleres i `sync_outbox`. Workeren prøver igjen ved neste poll. Ingen data tapes så lenge SpacetimeDB kjører ### 5.2 PostgreSQL → SpacetimeDB (oppvarming) - Ved oppstart (eller reconnect) av SpacetimeDB laster Rust-workeren aktive data fra PG: - Aktive temaer med siste N chatmeldinger - Kanban-state for pågående episoder - Aktør/Tema-navn for autocomplete (read-only cache) - Dette er en enveis-last, ikke kontinuerlig synk. Kunnskapsgrafen oppdateres i SpacetimeDB kun ved oppstart eller eksplisitt refresh ## 6. Feilhåndtering - **SpacetimeDB krasjer:** Data siden siste synk (~5 sek) tapes. Ved restart oppvarmes fra PG - **PostgreSQL nede:** Sanntidsfunksjoner fortsetter å fungere. `sync_outbox` vokser. Workeren logger advarsler. Ved PG-recovery synkes backloggen automatisk - **Rust-worker krasjer:** `sync_outbox` akkumuleres. Ved restart plukker workeren opp der den slapp (usynkede events har ingen markering) ## 7. Instruks for Claude Code - `sync_outbox`-tabellen i SpacetimeDB bør ha et `synced`-flagg og `created_at`-tidsstempel - Workeren skal bruke jobbkø-infrastrukturen (se `docs/features/jobbkø.md`) for sin egen helse/observabilitet, men selve pollingen er en egen loop — ikke en vanlig jobb i køen - Hold sync-payloaden enkel: `{ "table": "chat_messages", "action": "insert", "data": {...} }` — workeren mapper dette til riktig PG-tabell - Ikke optimaliser for store datamengder ennå. Enkle INSERTs er bra nok til volumet stabiliserer seg