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>
97 lines
3.3 KiB
Markdown
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` på `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
|