Commit graph

439 commits

Author SHA1 Message Date
a91d358263 STDB WebSocket-klient med reaktive Svelte-stores (oppgave 3.3)
Frontend kobler til SpacetimeDB via WebSocket og abonnerer på
node- og edge-tabellene. Data eksponeres som reaktive Svelte 5-stores
(runes) som oppdateres automatisk ved insert/update/delete.

Implementering:
- spacetimedb SDK (npm) + genererte TypeScript-bindings
- connection.svelte.ts: tilkoblingsmanager med reaktiv state
- stores.svelte.ts: nodeStore og edgeStore med sekundærindekser
  (bySource, byTarget, byKind, byType osv.)
- Layout initialiserer tilkobling ved autentisering
- Hjemmesiden viser tilkoblingsstatus og antall noder/edges
- .env.example med VITE_SPACETIMEDB_URL og VITE_SPACETIMEDB_MODULE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:55:37 +01:00
6829731525 Starter oppgave 3.3 2026-03-17 13:46:39 +01:00
6bc742cc8d Authentik OIDC login (oppgave 3.2)
Implementerer autentisering med Authentik via @auth/sveltekit:
- OIDC authorization code flow med PKCE og state-verifisering
- JWT-callback lagrer authentik_sub (SHA256-hash, ikke UUID) for
  konsistens med maskinrommets auth_identities-tabell
- Server hooks: alle ruter unntatt /signin og /auth/* krever sesjon
- Uautentiserte brukere redirectes til /signin (303)
- Innloggingsside med client-side signIn('authentik')
- Hovedside viser innlogget bruker med logg ut-knapp
- TypeScript-typer utvidet med JWT.authentik_sub

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:45:33 +01:00
073de4b148 Starter oppgave 3.2 2026-03-17 13:40:40 +01:00
d43365d5ea SvelteKit frontend-skjelett (oppgave 3.1)
Oppretter frontend/ med SvelteKit, TypeScript, TailwindCSS v4 og
adapter-node. PWA-manifest med SVG-ikon. Vite proxy til
api.sidelinja.org for lokal utvikling med HMR.

Oppdaterer docs/setup/lokal.md med riktige stier (frontend/ og
maskinrommet/ i stedet for web/ og rust/).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:37:41 +01:00
5fafa06139 Starter oppgave 3.1 2026-03-17 13:32:41 +01:00
76f386ac84 Maskinrommet i Docker Compose (oppgave 2.6)
Maskinrommet kjører nå som Docker-service i server-stacken:
- Lagt til maskinrommet-service i docker-compose.yml på server
- Intern nettverkstilgang til PG (postgres:5432) og STDB (spacetimedb:3000)
- Caddy proxyer api.sidelinja.org → maskinrommet:3100
- Verifisert: health-endpoint, PG-tilkobling, STDB-tilkobling, warmup,
  auth-middleware (401 uten token)

Oppdatert docs/setup/produksjon.md med:
- Maskinrommet i service-oversikt og Caddyfile
- SpacetimeDB-variabler i .env-template
- Deploy-instruksjoner for bygging av Docker-image
- Verifiseringssjekkliste

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:32:11 +01:00
79477a24bf Starter oppgave 2.6 2026-03-17 13:26:36 +01:00
1e9a4c83c3 Flere intensjoner: create_edge, update_node, delete_node (oppgave 2.5)
Implementerer tre nye skrivestier i maskinrommet med tilgangskontroll:

- POST /intentions/create_edge — opprett retningsbestemt edge mellom
  to noder. Validerer at begge noder eksisterer og edge_type er satt.
- POST /intentions/update_node — partial update av eksisterende node.
  Kun oppgitte felter endres, resten beholdes fra PG.
- POST /intentions/delete_node — slett node med cascade av edges.

Tilgangskontroll for update/delete: brukeren må enten være created_by
på noden, eller ha en owner/admin-edge til den. Sjekkes mot PG som
autoritativ kilde.

Alle endepunkter følger samme mønster som create_node:
STDB-skriving (instant) → async PG-persistering → umiddelbar respons.

Verifisert på server med 10 testcaser:
1. /me med gyldig token → 200
2. create_node → 200 med node_id
3. create_edge (gyldig) → 200 med edge_id
4. create_edge (ugyldig source) → 400
5. create_edge (tom edge_type) → 400
6. update_node (partial, eier) → 200
7. update_node (ingen tilgang) → 403
8. delete_node (eier) → 200
9. delete_node (ingen tilgang) → 403
10. update via owner-edge (Sidelinja) → 200

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:25:16 +01:00
f7a1a36824 Starter oppgave 2.5 2026-03-17 13:11:55 +01:00
61b35d3c01 Skrivestien: POST /intentions/create_node (oppgave 2.4)
Implementerer den første intensjonen i maskinrommet — skrivestien
som gjør at frontend kan opprette noder via maskinrommet.

Flyten:
1. Valider input (node_kind, visibility, metadata)
2. Generer UUIDv7 (tidssortert)
3. Skriv til SpacetimeDB (instant — frontend ser noden umiddelbart)
4. Spawn async tokio-task for PG-persistering
5. Returner node_id uten å vente på PG

Verifisert på server med fire testcaser:
1. Uten auth → 401
2. Ugyldig visibility → 400 med feilmelding
3. Minimal request (tomt body) → 200, node opprettet med defaults
4. Full request → 200, node verifisert i både STDB og PG

Også: Dockerfile oppdatert til Rust 1.88 (avhengigheter krevde >1.86),
og api_grensesnitt.md oppdatert med endepunktdokumentasjon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:09:50 +01:00
e7e8e8a10d Starter oppgave 2.4 2026-03-17 12:52:18 +01:00
c13a39317e Fullfør oppgave 2.3: STDB-klient, warmup og docs
- Fiks NULL-håndtering i warmup (COALESCE for title/content/created_by)
- Renere health check (delete nonexistent node i stedet for create+delete)
- Dokumenter HTTP API-format og warmup-flyt i erfaringer
- Lagre STDB-token i server .env
- Republiser STDB-modul etter containerrestart

Verifisert: warmup laster 2 noder + 1 edge, /health viser stdb=connected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:49:50 +01:00
cb7f88035d SpacetimeDB-klient og warmup i maskinrommet (oppgave 2.3)
Legger til HTTP-klient som kaller STDB-reducere via JSON API.
Warmup-modul laster hele grafen fra PG til STDB ved oppstart.

- stdb.rs: HTTP-klient med create/update/delete for noder og edges
- warmup.rs: PG → STDB sync (clear_all → noder → edges)
- main.rs: Integrerer STDB i AppState, kjører warmup ved oppstart

API-format: POST /v1/database/{db}/call/{reducer} med navngitte params.
STDB-token kan settes via SPACETIMEDB_TOKEN eller opprettes automatisk.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:44:27 +01:00
f946868ab1 Starter oppgave 2.3 2026-03-17 12:35:19 +01:00
8428fa45a0 Auth-middleware verifisert og fullført (oppgave 2.2)
- Fikser audience-validering (AUTHENTIK_CLIENT_ID som forventet aud)
- Oppdaterer seed-data med reell Authentik sub for Vegard
- Fikser DATABASE_URL i .env: peker nå til synops-database (ikke sidelinja)
- Dokumenterer maskinrommet-miljøvariabler i produksjon.md
- Markerer oppgave 2.2 som ferdig i tasks.md

Verifisert på server med fem testcaser:
1. /health (public) → 200
2. /me uten token → 401 "Mangler Authorization-header"
3. /me med ugyldig token → 401 "Ugyldig token"
4. /me med gyldig JWT, ukjent sub → 401 "Ukjent brukeridentitet"
5. /me med gyldig JWT, kjent sub → 200 med node_id

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:33:24 +01:00
854ed27797 Auth-middleware: JWT-validering og auth_identities-oppslag (oppgave 2.2)
Legger til Authentik JWT-validering i maskinrommet:
- Henter JWKS fra Authentik ved oppstart
- Validerer RS256-signatur, issuer og utløpstid
- Slår opp sub-claim i auth_identities → node_id
- AuthUser axum-extractor for beskyttede endepunkter
- /me test-endepunkt som krever gyldig token
- /health forblir offentlig

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:26:34 +01:00
0d0fd03415 Oppdater api_grensesnitt.md til maskinrommet-arkitekturen
Det gamle dokumentet beskrev en v1-arkitektur der SvelteKit var web-API
og Rust kun var workers. Med maskinrommet-retningen (besluttet) er Rust
en axum HTTP API-server som mottar intensjoner fra frontend og eier
alle skrivinger. Dokumentet er omskrevet til å reflektere dette.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:23:10 +01:00
b35eb100fa Starter oppgave 2.2 2026-03-17 12:20:54 +01:00
9f2667ba87 Maskinrommet Rust-skjelett med Dockerfile (oppgave 2.1)
Axum-server med health-endepunkt, PostgreSQL-tilkobling via sqlx,
strukturert logging med tracing. Flertrinns Dockerfile for produksjon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:20:39 +01:00
6129c1a265 Starter oppgave 2.1 2026-03-17 12:17:25 +01:00
2d73065510 Authentik OIDC-provider verifisert og dokumentert (oppgave 1.5)
OIDC-provider "sidelinja-web" og applikasjon "Sidelinja" var allerede
konfigurert i Authentik fra v1-oppsettet. Verifisert at alt fungerer:
- Discovery-endepunkt svarer korrekt
- JWKS tilgjengelig for JWT-validering (RS256)
- Redirect URIs konfigurert for prod + lokal utvikling (regex)
- Implicit consent flow (ingen godkjenningsskjerm)
- Client credentials lagret i server .env

Opprettet docs/erfaringer/authentik_oppsett.md som kanonisk referanse
for OIDC-konfigurasjonen — endepunkter, redirect URIs, scopes,
JWT-validering for maskinrommet, og API-administrasjon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:16:42 +01:00
84c8cc84c5 Starter oppgave 1.5 2026-03-17 12:11:58 +01:00
f1e9634117 Caddy-config: reverse proxy for alle Synops-domener (oppgave 1.4)
Oppretter Caddyfile med:
- auth.sidelinja.org → Authentik SSO
- sidelinja.org → SpacetimeDB (/spacetime/*), media (/media/*), SvelteKit (placeholder)
- api.sidelinja.org → maskinrommet (placeholder, 503 til fase 2)
- git.sidelinja.org → Forgejo
- vegard.info → placeholder

Auto-TLS via Let's Encrypt. Tjenester som ikke er deployet ennå bruker
respond-placeholders — kommentert reverse_proxy aktiveres når containerne
er klare. Verifisert på server: alle domener svarer med korrekt status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:11:22 +01:00
2b54498d04 Starter oppgave 1.4 2026-03-17 12:06:18 +01:00
12b94a9f1e SpacetimeDB-modul: nodes og edges med CRUD-reducers (oppgave 1.3)
Oppretter SpacetimeDB Rust-modul som speiler PG-skjema:
- Node-tabell (id, node_kind, title, content, visibility, metadata, timestamps)
- Edge-tabell (id, source_id, target_id, edge_type, metadata, system flag)
- CRUD-reducers: create/update/delete for begge tabeller
- clear_all reducer for warmup-reset
- Cascade-delete av edges ved node-sletting

Deployet til SpacetimeDB-instans på server (database: synops).
SpacetimeDB lagt til i docker-compose på serveren.

Verifisert med spacetime sql og call: tabeller fungerer,
CRUD-operasjoner fungerer, cascade-delete fungerer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:05:18 +01:00
f9cae49f43 Starter oppgave 1.3 2026-03-17 11:56:42 +01:00
89f1db63d2 Seed-data: Vegard brukernode, Sidelinja samling, owner-edge (oppgave 1.2)
Oppretter kjernedataene som resten av systemet bygger på:
- Vegards person-node med auth_identity (placeholder authentik_sub,
  oppdateres i oppgave 1.5 når Authentik konfigureres)
- Sidelinja samlings-node (tenant for podcastredaksjonen)
- Owner-edge fra Vegard til Sidelinja
- node_access-rad via recompute_access()

Kjørt og verifisert på server (sidelinja-postgres-1, synops-db).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:56:09 +01:00
6cc67d7d38 Starter oppgave 1.2 2026-03-17 11:54:31 +01:00
a30a484076 Opprett PostgreSQL-skjema for Synops (oppgave 1.1)
Oppretter database `synops` på serveren med kjerneskjemaet:
- Enums: visibility (hidden/discoverable/readable/open),
  access_level (reader/member/admin/owner)
- Tabeller: nodes, edges, node_access, auth_identities
- Funksjon: recompute_access for tilgangsmatrise-oppdatering
- Indekser iht. docs/primitiver/nodes.md og edges.md

Migrasjonen er kjørt og verifisert på produksjonsserver
(sidelinja-postgres-1, database: synops).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:53:31 +01:00
0746b4555a Starter oppgave 1.1 2026-03-17 11:51:10 +01:00
a7f3036e6f Bruk --dangerously-skip-permissions for autonom kjøring
claude --print alene stoppet på manglende write-permission.
Tilbakestiller oppgave 1.1 for ny kjøring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:51:05 +01:00
397017f8b6 Starter oppgave 1.1 2026-03-17 11:48:09 +01:00
bf2d833410 Legg til run-tasks.sh: sekvensiell runner til ferdig/blokkert
Kjører oppgaver i loop med pause mellom. Stopper når alt er gjort,
blokkert, eller trenger avklaring fra Vegard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:46:15 +01:00
bd5e94acf6 Oppgavelås [~] for parallelle agenter, fjern eksempler som forstyrret grep
tasks.md: Ny status [~] (pågår) med timestamp. Fjernet code-fence
eksempler som ble fanget av grep som ekte oppgaver.

run-next-task.sh: Markerer oppgave som [~] før start, tilbakestiller
ved krasj. --unstale frigjør oppgaver >60 min. Sjekker at forrige
oppgave i fasen er ferdig. Pull-instruksjon i prompt. Subagent-bruk
oppfordres der det er egnet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:39:38 +01:00
43fc267089 Legg til task-liste og autonom runner for implementering
tasks.md: 51 oppgaver i 12 faser med avhengighetskart og
statusmarkører ([?] for åpne spørsmål, [!] for blokkert).

run-next-task.sh: plukker neste tilgjengelige oppgave, hopper
over blokkerte faser og deres avhengigheter, starter fersk
Claude Code-sesjon med full kontekst-prompt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:35:22 +01:00
c1d3ad66a5 Fjern gjenværende v2-referanser, dokumenter editor og tekstlagring
Rydder opp siste «v2»-referanser i docs (status_quo, migration_safety,
personlig_workspace, spacetimedb_integrasjon). Legger til editor-seksjon
i universell_input.md (TipTap, presets, tekstlagring) og oppdaterer
nodes.md med content/metadata.document-modellen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 10:55:39 +01:00
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
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