synops/docs/infra/api_grensesnitt.md
vegard 27d0d8db94 Publiseringsflyt i frontend (oppgave 14.7)
Personlig publiseringsflyt for samlinger med publishing-trait der
require_approval: false. Bruker kan publisere artikler fra mottak
til samlingen, og avpublisere ved å fjerne belongs_to-edge.

Backend:
- Nytt delete_edge-endepunkt i maskinrommet med tilgangskontroll
  og automatisk forside-cache-invalidering ved avpublisering

Frontend:
- PublishDialog: forhåndsvisning, slug-editor, tema-info, bekreftelse
- EditorTrait: publiser/avpubliser-knapper på innholdsnoder i
  publiseringssamlinger, velger for upubliserte artikler
- deleteEdge i API-klienten

Docs:
- Oppdatert api_grensesnitt.md med delete_edge, update_edge, set_slot

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:33:37 +00:00

7 KiB

Infrastruktur: API-grensesnitt og Tjenesteansvar

1. Konsept

Frontend sender intensjoner til maskinrommet (Rust/axum HTTP API). Maskinrommet eier alle skrivinger: det validerer, skriver til SpacetimeDB (instant), persisterer til PG (asynk), og orkestrerer konsekvenser.

Lesestien for sanntid går direkte fra SpacetimeDB til frontend via WebSocket. Tunge spørringer (søk, statistikk, graftraversering) går via maskinrommet → PG.

2. Kommunikasjonskart

┌─────────────────────────────────────────────────────────────┐
│  Brukerens nettleser (SvelteKit klient)                     │
└──────────┬──────────────────────┬───────────────────────────┘
           │                      │
           │ HTTP (intensjoner)   │ WebSocket (sanntid)
           ▼                      ▼
┌──────────────────────┐   ┌──────────────────┐
│  Maskinrommet (Rust)  │   │  SpacetimeDB     │
│  axum HTTP API       │   │                  │
│                      │   │  - Hele grafen   │
│  Ansvar:             │   │  - Push til      │
│  - Validere          │   │    klienter      │
│  - Skrive STDB+PG   │   │                  │
│  - Orkestrere        │   └──────────────────┘
│  - Tunge spørringer  │
│  - Bakgrunnsjobber   │
└──┬─────┬─────┬───────┘
   │     │     │
   ▼     ▼     ▼
┌─────┐┌─────┐┌─────────────┐
│ PG  ││STDB ││ Whisper,    │
│     ││     ││ LiteLLM,   │
│     ││     ││ LiveKit ... │
└─────┘└─────┘└─────────────┘

3. Ansvarsfordeling

Komponent Rolle Snakker med
SvelteKit (klient) UI, brukerinteraksjon Maskinrommet (HTTP), SpacetimeDB (WS)
Maskinrommet (Rust) Intensjons-API, orkestrering, tunge spørringer PG, SpacetimeDB, CAS, Whisper, LiteLLM
SpacetimeDB Sanntids state, push til klienter Klienter (WS), maskinrommet (skriver)
PostgreSQL Persistent arkiv, søk, statistikk Maskinrommet (SQL)

4. Viktige avklaringer

  • Maskinrommet er en HTTP API-server (axum). Frontend sender intensjoner hit.
  • Maskinrommet eier alle skrivinger. Frontend skriver aldri direkte til PG eller STDB.
  • SpacetimeDB nås direkte fra klienten via WebSocket for lesing (sanntid).
  • SvelteKit er et rent frontend-prosjekt. Ingen server-side PG-tilgang.
  • Bakgrunnsjobber (Whisper, LLM, TTS) orkestreres av maskinrommet, aldri direkte fra frontend.

5. Implementerte endepunkter

Offentlige

  • GET /health — Helsesjekk. Verifiserer PG- og STDB-tilkobling.

Autentiserte (krever Authorization: Bearer <JWT>)

  • GET /me — Returnerer autentisert brukers node_id og authentik_sub.
  • POST /intentions/create_node — Opprett node. Skriv til STDB (instant), spawn async PG-skriving, returner node_id umiddelbart.
    • Body (JSON): { node_kind?, title?, content?, visibility?, metadata? }
    • Defaults: node_kind="content", visibility="hidden", andre felter tomme
    • Respons: { node_id: "<uuid>" }
  • POST /intentions/create_edge — Opprett edge mellom to noder. Validerer at begge nodene eksisterer og at edge_type ikke er tom.
    • Body (JSON): { source_id, target_id, edge_type, metadata?, system? }
    • Defaults: metadata={}, system=false
    • Respons: { edge_id: "<uuid>" }
  • POST /intentions/update_node — Oppdater eksisterende node (partial update). Krever tilgang: created_by eller owner/admin-edge.
    • Body (JSON): { node_id, node_kind?, title?, content?, visibility?, metadata? }
    • Kun oppgitte felter endres, resten beholdes
    • Respons: { node_id: "<uuid>" }
  • POST /intentions/delete_node — Slett node og tilhørende edges. Krever tilgang: created_by eller owner/admin-edge.
    • Body (JSON): { node_id }
    • Respons: { deleted: true }
  • POST /intentions/update_edge — Oppdater eksisterende edge (partial update). Krever tilgang: created_by eller owner/admin-edge til source-noden.
    • Body (JSON): { edge_id, edge_type?, metadata? }
    • Kun oppgitte felter endres, resten beholdes
    • Respons: { edge_id: "<uuid>" }
  • POST /intentions/delete_edge — Slett en edge. Brukes bl.a. for avpublisering. Krever tilgang: created_by eller owner/admin-edge til source-noden. Ved fjerning av belongs_to-edge til publiseringssamling invalideres forside-cache.
    • Body (JSON): { edge_id }
    • Respons: { deleted: true }
  • POST /intentions/set_slot — Sett slot-metadata (hero/featured/strøm) på belongs_to-edge i publiseringssamling. Håndterer hero-erstatning og featured-overflow.
    • Body (JSON): { edge_id, slot, slot_order?, pinned? }
    • Respons: { edge_id, displaced[] }

LiveKit / Sanntidslyd (oppgave 11.2)

  • POST /intentions/join_communication — Koble til sanntidslyd i en kommunikasjonsnode. Validerer deltaker-tilgang (owner/member_of/host_of-edge eller via alias). Genererer LiveKit access token (JWT), oppretter rom i STDB, oppdaterer node-metadata.
    • Body (JSON): { communication_id, role? } (role: "publisher" | "subscriber", default "publisher")
    • Respons: { livekit_room_name, livekit_token, livekit_url, identity, participants[] }
    • Frontend bruker livekit_token + livekit_url til å koble livekit-client SDK.
  • POST /intentions/leave_communication — Forlat sanntidsrom. Fjerner deltaker fra STDB live-rom.
    • Body (JSON): { communication_id }
    • Respons: { status: "left" }
  • POST /intentions/close_communication — Steng sanntidsrom (krever owner/admin). Fjerner alle deltakere, setter live_status=ended i metadata.
    • Body (JSON): { communication_id }
    • Respons: { status: "closed" }

SpacetimeDB sanntidstabeller (LiveKit)

  • live_room — Aktive rom. Felt: room_id, communication_id, is_active, started_at, participant_count.
  • room_participant — Deltakere i rom. Felt: id, room_id, user_id, display_name, role, joined_at. Frontend abonnerer på disse via SpacetimeDB WebSocket for sanntids deltakerliste.

6. Instruks for Claude Code

  • Maskinrommet (maskinrommet/) er Rust-prosjektet med axum, tokio, sqlx.
  • Intensjoner fra frontend → POST /intentions/* endepunkter i maskinrommet.
  • Tunge spørringer fra frontend → GET /query/* endepunkter i maskinrommet.
  • Frontend (SvelteKit) har ingen direkte databasetilgang.
  • Bakgrunnsjobber trigges av maskinrommet, ikke via en separat jobbkø-tabell.

Historisk merknad: Tidligere beskrev dette dokumentet en arkitektur der SvelteKit var web-API og Rust kun var workers. Denne ble erstattet av maskinrommet-arkitekturen (se docs/retninger/maskinrommet.md).