synops/tasks.md
vegard 08d2933788 Mottaksflaten v0: vis noder koblet til innlogget bruker (oppgave 3.4)
Henter brukerens node_id fra maskinrommets /me-endepunkt ved innlogging
(via Authentik access_token), cacher i JWT-sesjon. Mottaksflaten viser
alle noder brukeren har edges til (begge retninger), sortert nyeste først,
med tittel, utdrag, node_kind-merke og edge-type-merker.

Endringer:
- auth.ts: fetchNodeId() kaller maskinrommet /me ved sign-in
- app.d.ts: utvider JWT og Session med node_id/nodeId
- +page.svelte: erstatter dashboard med mottaksflate-visning
- .env.example: MASKINROMMET_URL for server-side API-kall

Krever at brukeren logger ut og inn igjen for å hente node_id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 14:13:36 +01:00

7.6 KiB

Synops — Implementeringsoppgaver

Sekvensiell liste. Hver oppgave gjøres i én Claude Code-sesjon. Runner-scriptet plukker første ugjorte oppgave som ikke er blokkert.

Statuser

  • - [ ] — Klar til å gjøres
  • - [~] — Pågår. En agent jobber på denne. Andre agenter hopper over.
  • - [x] — Ferdig
  • - [?] — Åpent spørsmål, trenger avklaring fra Vegard.
  • - [!] — Blokkert av teknisk problem.

[~], [?] og [!] blokkerer alle oppgaver som avhenger av denne. Detaljer skrives som innrykket tekst med > prefix under oppgaven. Runner-scriptet legger automatisk til > Påbegynt: <timestamp> for [~].

Hvis en [~]-oppgave har stått i >60 min uten commit, anta at sesjonen krasjet. Kjør run-next-task.sh --unstale for å frigjøre.

Avhengigheter

Oppgaver innen en fase er sekvensielle (1.1 før 1.2, osv). Faser avhenger av hverandre slik:

Fase 1 (infra) → Fase 2 (maskinrommet) → Fase 3 (frontend)
                                        ↘ Fase 4 (tilgang)
Fase 3 + 4 → Fase 5 (kommunikasjon)
Fase 2 → Fase 6 (CAS) → Fase 7 (lyd)
Fase 5 → Fase 8 (aliaser)
Fase 3 → Fase 9 (visninger)
Fase 2 → Fase 10 (AI)
Fase 5 + 6 + 7 → Fase 11 (produksjon)
Alt → Fase 12 (herding)

Hvis en oppgave er [?] eller [!], hoppes den over — og alle oppgaver som avhenger av den (innen fasen + avhengige faser). Uavhengige faser kan fortsatt plukkes.


Fase 1: Infrastruktur-fundament

  • 1.1 PostgreSQL schema: opprett database synops, enums (visibility, access_level), tabeller (nodes, edges, node_access, auth_identities) med indekser. Kjør på server via SSH. Ref: docs/primitiver/nodes.md, docs/primitiver/edges.md, docs/retninger/bruker_ikke_workspace.md.
  • 1.2 Seed-data: opprett Vegards brukernode (node_kind='person', title='Vegard') og auth_identities-rad. Opprett Sidelinja samlings-node og owner-edge fra Vegard.
  • 1.3 SpacetimeDB modul: opprett Rust-modul med nodes og edges-tabeller som speiler PG-skjema. Grunnleggende reducers for CRUD. Deploy til server. Ref: docs/retninger/datalaget.md, docs/erfaringer/spacetimedb_integrasjon.md.
  • 1.4 Caddy-config: reverse proxy for maskinrommet (api.sidelinja.org), SpacetimeDB, og SvelteKit. Auto-TLS. Ref: docs/setup/produksjon.md.
  • 1.5 Authentik: opprett OIDC-provider og applikasjon for Synops. Konfigurer redirect URIs. Ref: docs/erfaringer/authentik_oppsett.md.

Fase 2: Maskinrommet — skjelett

  • 2.1 Rust-prosjekt: opprett maskinrommet/ med axum, tokio, sqlx (PG), serde. Dockerfile. Kompilerer og starter. Ref: docs/retninger/maskinrommet.md.
  • 2.2 Auth-middleware: valider Authentik JWT-tokens, slå opp auth_identities → node_id. Returner 401 for ugyldige tokens.
  • 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
  • 2.4 Skrivestien: POST /intentions/create_node — valider, skriv STDB (instant), spawn async PG-skriving. Returner node_id umiddelbart.
  • 2.5 Flere intensjoner: create_edge, update_node, delete_node. Validering av tilgang (created_by eller owner/admin-edge).
  • 2.6 Docker Compose: legg maskinrommet inn i server-stacken. Intern nettverkstilgang til PG og STDB.

Fase 3: Frontend — skjelett

  • 3.1 SvelteKit-prosjekt: opprett frontend/ med TypeScript, TailwindCSS. PWA-manifest. Lokal dev med HMR.
  • 3.2 Authentik login: OIDC-flow (authorization code + PKCE). Session-håndtering. Redirect til login ved 401.
  • 3.3 STDB WebSocket-klient: abonner på noder og edges. Reaktiv Svelte-store som oppdateres ved endringer.
  • 3.4 Mottaksflaten v0: vis noder med edge til innlogget bruker, sortert på created_at. Enkel liste med tittel og utdrag.
  • 3.5 TipTap-editor: enkel preset (tekst, markdown, lenker). Send create_node-intensjon til maskinrommet ved submit.
  • 3.6 Sanntidstest: åpne to faner, skriv i én, se noden dukke opp i den andre via STDB.

Fase 4: Tilgangskontroll

  • 4.1 recompute_access i maskinrommet: ved edge-endring, oppdater node_access-matrisen. Håndter direkte edges (owner, admin, member, reader).
  • 4.2 Team-transitivitet: member_of-edge til team → arv tilgang fra teamets edges.
  • 4.3 Visibility-filtrering: STDB-spørringer respekterer visibility-enum. Frontend ser bare noder brukeren har tilgang til.
  • 4.4 RLS-policies på PG: node_access-basert filtrering for tunge spørringer.

Fase 5: Kommunikasjonsnoder

  • 5.1 Opprett kommunikasjonsnode: intensjon create_communication → node med node_kind='communication', deltaker-edges, metadata (started_at).
  • 5.2 Kontekst-arv: input i kommunikasjonsnode → automatisk belongs_to-edge.
  • 5.3 Chat-visning i frontend: noder med belongs_to-edge til kommunikasjonsnode, sortert på tid, sanntid via STDB.
  • 5.4 Én-til-én chat: opprett kommunikasjonsnode med to deltakere. Full loop: skriv melding → vis i sanntid hos begge.

Fase 6: CAS og mediefiler

  • 6.1 CAS-lagring: filsystem med content-addressable hashing (SHA-256). Katalogstruktur med hash-prefix. Deduplisering.
  • 6.2 Upload-endepunkt: POST /intentions/upload_media → hash fil, lagre i CAS, opprett media-node med has_media-edge.
  • 6.3 Serving: GET /cas/{hash} → stream fil fra disk. Caddy kan serve direkte for ytelse.
  • 6.4 Bilder i TipTap: drag-and-drop/paste → upload → CAS-node → inline i metadata.document via node_id.

Fase 7: Lyd-pipeline

  • 7.1 faster-whisper oppsett: Docker-container, GPU hvis tilgjengelig, norsk modell. Ref: docs/erfaringer/.
  • 7.2 Transkripsjons-pipeline: lydfil i CAS → maskinrommet trigger Whisper → resultat i content-feltet.
  • 7.3 Voice memo i frontend: opptak-knapp i input-komponenten → upload → CAS → transkripsjon.
  • 7.4 Lyd-avspilling: spiller av original lyd fra CAS-node. Waveform-visning.

Fase 8: Aliaser

  • 8.1 Alias-noder: opprett alias-node med alias-edge (system=true) fra hovednoden. Usynlig for traversering.
  • 8.2 Kontekstbasert identitet: maskinrommet setter created_by til alias-node når brukeren opererer i kontekst der aliaset er vert/deltaker.

Fase 9: Flere visninger

  • 9.1 Kanban-visning: noder med board-edge, gruppert på status-edge. Drag-and-drop for statusendring.
  • 9.2 Kalender-visning: noder med scheduled-edge, på tidslinje.
  • 9.3 Dagbok-visning: private noder (ingen delte edges), sortert på tid.
  • 9.4 Kunnskapsgraf: topic-noder, mentions-edges. Visuell graf-visning.

Fase 10: AI og beriking

  • 10.1 LiteLLM oppsett: Docker-container, API-nøkler, modell-routing. Ref: docs/infra/ai_gateway.md.
  • 10.2 AI-foreslåtte edges: maskinrommet sender innhold til LLM → foreslår mentions, topics.
  • 10.3 Oppsummering: kommunikasjonsnode → AI-generert sammendrag som ny node.
  • 10.4 TTS: tekst → lyd via ElevenLabs. Mottaker-preferanse i metadata.

Fase 11: Produksjons-pipeline

  • 11.1 LiveKit oppsett: Docker-container for WebRTC. Ref: docs/setup/produksjon.md.
  • 11.2 Sanntidslyd: kommunikasjonsnode med live-status → LiveKit-rom for deltakere.
  • 11.3 Pruning-logikk: TTL per modalitet, signaler som forlenger levetid, disk-nødventil.
  • 11.4 Podcast-RSS: samlings-node med publiserings-edges → generert RSS-feed.

Fase 12: Herding

  • 12.1 Observerbarhet: strukturert logging, metrikker (request latency, queue depth, AI cost).
  • 12.2 Backup: PG-dump rutine, STDB → PG gjenoppbygging ved krasj.
  • 12.3 Feilhåndtering: retry med backoff i skrivestien, dead letter queue for feilede PG-skrivinger.
  • 12.4 Ytelse: profiler STDB-spørringer, optimaliser node_access-oppdatering.