synops/docs/retninger/datalaget.md
vegard 00bf5d27ce Arkitekturbeslutninger: noder er sentrum, edges definerer alt
Grunnleggende arkitekturbeslutninger tatt og dokumentert:

- Alt er noder (brukere, team, innhold, mediefiler, samlings-noder)
- Edges definerer hva en node er (freeform typer, metadata i JSONB)
- Materialisert tilgangsmatrise (node_access) erstatter workspace-RLS
- Visibility (hidden/discoverable/readable/open) på noder
- Aliaser via usynlige system-edges
- Maskinrommet eier all skriving (SpacetimeDB først, PG asynk)
- SpacetimeDB holder hele grafen, PG er persistent backup
- Node- og edge-skjema spesifisert (docs/primitiver/)

Fjernet workspace-konseptet fra hele dokumentasjonen (~40 filer).
Fem retninger besluttet, én åpen (rom, ikke forum).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 10:29:54 +01:00

97 lines
3.3 KiB
Markdown

# Datalaget
**Status: Besluttet.**
> SpacetimeDB holder hele grafen i minne og mottar skrivinger først.
> PostgreSQL er persistent arkiv og backup. CAS lagrer binærdata.
> Apache AGE legges til ved behov for Cypher-traverseringer.
## Lagmodell
```
GUI (SvelteKit)
│ skriv │ les (sanntid, WebSocket)
▼ ▼
Maskinrommet (Rust) SpacetimeDB ──→ GUI
│ validering ▲
├──→ SpacetimeDB (først) ───┘
└──→ PostgreSQL (asynk, persistent)
```
### Skrivestien
GUI → Maskinrommet → validering → SpacetimeDB (instant) → PG (asynk).
Frontend oppdateres umiddelbart. PG persisterer i bakgrunnen.
### Lesestien (sanntid)
SpacetimeDB → GUI (direkte WebSocket, ~10μs).
Hele grafen er i SpacetimeDB. Frontend har alltid alt tilgjengelig.
### Lesestien (tunge spørringer)
GUI → Maskinrommet → PG.
Fulltekstsøk, pgvector (semantisk søk), statistikk, AGE-traverseringer.
## SpacetimeDB — hele grafen i minne
Node- og edge-skjemaet er minimalt (åtte kolonner hver). For en
liten brukerbase er hele grafen triviell å holde i minne. Fordeler:
- Ingen sync-logikk for å bestemme hva som er "aktivt"
- Ingen henting fra PG når noen åpner noe gammelt
- Frontend har alltid alt via WebSocket
- Én lesekilde — ingen tvetydighet
Når dette blir problematisk (hundretusenvis av noder), innføres
eviction. Det er en optimalisering, ikke en arkitekturendring.
## PostgreSQL — arkiv og kraftspørringer
PG er persistent backup for hele grafen, pluss hjemsted for
tunge operasjoner SpacetimeDB ikke er laget for:
- **Fulltekstsøk** — `tsvector``nodes.content` og `nodes.title`
- **Semantisk søk** — pgvector for embedding-basert likhet
- **Graftraversering** — rekursive CTEs, Apache AGE ved behov
- **Statistikk** — aggregeringer, tidsserier
- **Tilgangsmatrise** — `node_access` beregnes her, speiles til STDB
### Apache AGE — ved behov
De fleste spørringer er grunne (1-3 hopp) og håndteres av CTEs.
AGE legges til som PG-extension når Cypher-semantikk faktisk trengs:
1. **Nå:** PG med nodes/edges-tabeller og CTEs
2. **Når CTEs blir smertefulle:** Legg til AGE
3. **Usannsynlig:** Evaluer Neo4j hvis AGE ikke holder
AGE er en extension, ikke en migrering — boltes på uten å endre
eksisterende kode.
## CAS — binærlagring
Lyd, bilde, video lagres content-addressable på disk. CAS-noder
i grafen bærer metadata (`cas_hash`, `mime`, `size_bytes`).
Selve biten lever utenfor PG.
Pruning-regler basert på modalitet, edges og aksessmønstre.
Se [maskinrommet](maskinrommet.md).
## SpacetimeDB som utbyttbar
SpacetimeDB er en sanntidscache, ikke en avhengighet. Hvis den
fjernes:
- **Sanntid:** PG `LISTEN/NOTIFY` → SvelteKit SSE
- **Skriving:** Maskinrommet → PG direkte
- **Lesing:** Maskinrommet → PG → GUI
Trenger ikke implementeres, men arkitekturen skal aldri gjøre
det umulig. Se [synkronisering](../infra/synkronisering.md).
## Forhold til andre retninger
- [Noder er sentrum](bruker_ikke_workspace.md) — tilgangsmatrise
beregnet fra edge-grafen, speiles til SpacetimeDB
- [Universell input og mottak](universell_input.md) — noder og edges
er datamodellen for alle tre primitiver
- [Maskinrommet](maskinrommet.md) — CAS-pruning, edge-drevet
ressursorkestrering, validering før skriving