synops/docs/arkitektur.md
vegard 0a467066ba Synops v2: arkitektur, retninger og dokumentasjon
Nystart basert på arkitektonisk innsikt fra Sidelinja v1.
Koden er ny, visjon og primitiver er validert gjennom tidligere arbeid.

Inneholder:
- Komplett arkitekturdokumentasjon (docs/arkitektur.md)
- 6 vedtatte retninger (docs/retninger/)
- Alle concepts, features, proposals og erfaringer fra v1
- Server-oppsett og drift (docs/setup/)
- LiteLLM-konfigurasjon (API-nøkler via env)
- Editor.svelte referanse fra v1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 06:43:08 +01:00

6 KiB

Arkitektur — Sidelinja v2

Visjon

Sidelinja er en plattform for redaksjonelt arbeid og podcast-produksjon. Ikke en webapp med features — en plattform med primitiver som kan bli hva som helst.

Alt er noder og edges i en graf. Input fanger, mottak presenterer, kommunikasjonsnoder samler folk. Maskinrommet orkestrerer tekniske tjenester under. Frontend er et tynt lag som viser grafen.

Lagmodell

┌─────────────────────────────────────┐
│  GUI (SvelteKit)                     │
│  Visninger: spørringer mot grafen    │
└────────┬──────────────────┬─────────┘
         │ skriv            │ les (sanntid)
         │                  │ direkte WebSocket
┌────────▼────────┐  ┌─────▼─────────┐
│  Maskinrommet    │  │  SpacetimeDB  │
│  (Rust)          │  │  Aktive noder │
│  Orkestrering    │  └───────────────┘
└──┬─────┬─────┬──┘
   │     │     │
   ▼     ▼     ▼
┌─────┐┌─────┐┌─────┐┌─────────────┐
│ PG  ││STDB ││ CAS ││ Whisper,    │
│     ││(skr)││     ││ LiteLLM,   │
│     ││     ││     ││ LiveKit ... │
└─────┘└─────┘└─────┘└─────────────┘

Skrivestien

GUI → Maskinrommet (Rust) → tjenester

All orkestrering, edge-logikk, validering og ressursallokering går gjennom Rust. Maskinrommet leser edges og bestemmer hvilke tjenester som trigges.

Lesestien (sanntid)

SpacetimeDB → GUI (direkte WebSocket)

STDB klient-SDK gir ~10μs-oppdateringer med lokal cache. En bevisst optimering — ikke et hull i lagmodellen.

Lesestien (tradisjonell)

GUI → Maskinrommet (Rust) → PG

Søk, historikk, statistikk, arkiv. Cypher via AGE for graftraversering når CTEs ikke holder.

Datamodell

Noder

Én tabell. Alt innhold er noder: meldinger, oppgaver, notater, faktoider, mediefiler, kommunikasjonsrom, samlings-noder, brukere.

Felles skjema: id, innhold, created_at, author, content_hash (→ CAS). Modalitetsspesifikk metadata i JSONB.

Edges

Én tabell. Alle relasjoner er edges: tilhørighet, tilgang, type, synlighet, rolle, status.

Hva en node "er" bestemmes utelukkende av edges:

  • Node + edge til kanal = chatmelding
  • Node + edge til board + status-edge = kanban-kort
  • Node + edge til dato = kalenderoppføring
  • Node + edge til kun bruker = privat notat
  • Node + edge til topic = faktoid
  • Node uten edges = løs tanke

Visninger

Visninger er spørringer mot grafen med ulike filtre:

  • Chat = noder med kanal-edge, sortert på tid
  • Kanban = noder med board-edge, gruppert på status
  • Kalender = noder med dato-edge, på tidslinje
  • Mottaksflate = noder med edge til deg, vektet på relevans

Tre primitiver

1. Input

Én multimodal overflate som fanger alt: tekst, lyd, bilde, AI, URL. To versjoner — sanntid (STDB-lag) og flat (PG-lag). Output er alltid en node.

2. Mottak

Én personlig flate som presenterer alt tilpasset deg. Format bestemmes av mottaker (tekst/lyd). Filtrering via dine edges. Sanntid (stream) eller asynkront (digest).

3. Kommunikasjon

En node som samler folk med tilgangsregler. Samme type fra én-til-én-samtale til livesending. Forskjellen er edges: eier, input-tilgang, mottak-tilgang, rolle.

Maskinrommet

Rust-tjeneste med tre operasjoner: fang, prosesser, lever.

Edge-drevet ressursorkestrering: maskinrommet leser edges og bestemmer hvilke tjenester som spinnes opp. Dagboknotat = bare transkriber. Livesending = transkriber + LiveKit + AI + mediaprosessering.

Forvalter også CAS (binærlagring) med intelligent pruning basert på modalitet, edges og aksessmønstre.

Sikkerhet

RLS-siloer

Samlings-noder (det som var workspaces) er harde sikkerhetsgenser i PG med RLS. workspace_id = current_setting(...) — instant, vanntett. Edge-basert tilgang er UX innenfor siloen.

Privat er default

Input uten mottaker-edge er automatisk privat. Ingen ser det. Deling er å legge til edges.

Datalag

PostgreSQL

Arkiv og graf. Alle noder og edges. Fulltekstsøk, pgvector (semantisk søk), JSONB. Apache AGE for Cypher når CTEs ikke holder.

SpacetimeDB

Sanntidslag. Aktive noder og edges speilet fra PG. Frontend abonnerer via WebSocket. Ingen eierskapskonflikt — STDB er en live-visning av en delmengde av PG-grafen.

CAS (Content-Addressable Store)

Binærdata (lyd, bilde, video) lagret med hash. TTL basert på modalitet, edges og aksesslog. Tekst lever evig, lyd 30 dager, video 14 dager — forlenges ved aksess. Generert innhold (TTS, thumbnails) er en cache som regenereres on-demand.

Teknologivalg

Rolle Teknologi Begrunnelse
Orkestrator Rust Ytelse, typesikkerhet, allerede i stacken
Frontend SvelteKit PWA, SSR, allerede i stacken
Database PostgreSQL Økosystem (pgvector, fulltekstsøk, AGE), stabilitet
Sanntid SpacetimeDB In-memory, WebSocket-subscriptions, ~10μs
Binærlagring CAS (filsystem) Enkel, deduplisering, ingen ekstern avhengighet
AI Gateway LiteLLM Multi-provider, BYOK, OpenRouter fallback
STT faster-whisper Lokal, god norsk kvalitet
TTS ElevenLabs (→ lokal) Kommersiell start, lokal når kvaliteten holder
Auth Authentik SSO, OIDC, self-hosted
Reverse proxy Caddy Auto-TLS, enkel config
Lyd/video LiveKit WebRTC, self-hosted

Retninger

Arkitekturen er basert på vedtatte retninger dokumentert i docs/retninger/. Se docs/retninger/README.md for oversikt.