synops/tasks.md
2026-03-17 16:50:12 +01:00

160 lines
11 KiB
Markdown

# 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)
Fase 3 + 4 → Fase 13 (traits)
Fase 6 + 13 → Fase 14 (publisering)
Fase 3 + 10 → Fase 15 (adminpanel)
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
- [x] 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`.
- [x] 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.
- [x] 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`.
- [x] 1.4 Caddy-config: reverse proxy for maskinrommet (api.sidelinja.org), SpacetimeDB, og SvelteKit. Auto-TLS. Ref: `docs/setup/produksjon.md`.
- [x] 1.5 Authentik: opprett OIDC-provider og applikasjon for Synops. Konfigurer redirect URIs. Ref: `docs/erfaringer/authentik_oppsett.md`.
## Fase 2: Maskinrommet — skjelett
- [x] 2.1 Rust-prosjekt: opprett `maskinrommet/` med axum, tokio, sqlx (PG), serde. Dockerfile. Kompilerer og starter. Ref: `docs/retninger/maskinrommet.md`.
- [x] 2.2 Auth-middleware: valider Authentik JWT-tokens, slå opp `auth_identities` → node_id. Returner 401 for ugyldige tokens.
- [x] 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
- [x] 2.4 Skrivestien: `POST /intentions/create_node` — valider, skriv STDB (instant), spawn async PG-skriving. Returner node_id umiddelbart.
- [x] 2.5 Flere intensjoner: `create_edge`, `update_node`, `delete_node`. Validering av tilgang (created_by eller owner/admin-edge).
- [x] 2.6 Docker Compose: legg maskinrommet inn i server-stacken. Intern nettverkstilgang til PG og STDB.
## Fase 3: Frontend — skjelett
- [x] 3.1 SvelteKit-prosjekt: opprett `frontend/` med TypeScript, TailwindCSS. PWA-manifest. Lokal dev med HMR.
- [x] 3.2 Authentik login: OIDC-flow (authorization code + PKCE). Session-håndtering. Redirect til login ved 401.
- [x] 3.3 STDB WebSocket-klient: abonner på noder og edges. Reaktiv Svelte-store som oppdateres ved endringer.
- [x] 3.4 Mottaksflaten v0: vis noder med edge til innlogget bruker, sortert på `created_at`. Enkel liste med tittel og utdrag.
- [x] 3.5 TipTap-editor: enkel preset (tekst, markdown, lenker). Send `create_node`-intensjon til maskinrommet ved submit.
- [x] 3.6 Sanntidstest: åpne to faner, skriv i én, se noden dukke opp i den andre via STDB.
## Fase 4: Tilgangskontroll
- [x] 4.1 `recompute_access` i maskinrommet: ved edge-endring, oppdater `node_access`-matrisen. Håndter direkte edges (owner, admin, member, reader).
- [x] 4.2 Team-transitivitet: member_of-edge til team → arv tilgang fra teamets edges.
- [x] 4.3 Visibility-filtrering: STDB-spørringer respekterer visibility-enum. Frontend ser bare noder brukeren har tilgang til.
- [x] 4.4 RLS-policies på PG: `node_access`-basert filtrering for tunge spørringer.
## Fase 5: Kommunikasjonsnoder
- [x] 5.1 Opprett kommunikasjonsnode: intensjon `create_communication` → node med `node_kind='communication'`, deltaker-edges, metadata (started_at).
- [x] 5.2 Kontekst-arv: input i kommunikasjonsnode → automatisk `belongs_to`-edge.
- [x] 5.3 Chat-visning i frontend: noder med `belongs_to`-edge til kommunikasjonsnode, sortert på tid, sanntid via STDB.
- [x] 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
- [x] 6.1 CAS-lagring: filsystem med content-addressable hashing (SHA-256). Katalogstruktur med hash-prefix. Deduplisering.
- [x] 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.
> Påbegynt: 2026-03-17T16:50
- [ ] 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 13: Trait-system
- [ ] 13.1 Trait-metadata på samlingsnoder: maskinrommet validerer `metadata.traits`-objektet ved `create_node` og `update_node` for samlingsnoder. Avvis ukjente trait-navn. Ref: `docs/primitiver/traits.md`.
- [ ] 13.2 Trait-aware frontend: samlingssider leser `traits` fra metadata og rendrer kun aktive komponenter. Dynamisk komponent-lasting basert på trait-liste.
- [ ] 13.3 Pakkevelger: UI for å opprette ny samling med forhåndsdefinert pakke (nettmagasin, podcaststudio, redaksjon osv.) eller manuelt valg av traits.
- [ ] 13.4 Trait-administrasjon: admin-UI for å legge til/fjerne traits på eksisterende samlinger med konfigurasjon per trait.
## Fase 14: Publisering
- [ ] 14.1 HTML-rendering: maskinrommet rendrer `metadata.document` til HTML ved publisering, lagrer i CAS. Noden får `metadata.rendered.html_hash`. Ref: `docs/concepts/publisering.md`.
- [ ] 14.2 Caddy-ruting for synops.no/pub: statisk serving av CAS-rendret HTML. Rute `synops.no/pub/{slug}/{id}` → oppslag i maskinrommet → CAS-fil. SEO-metadata (OG-tags, canonical).
- [ ] 14.3 Publiseringsflyt i frontend: publiseringsknapp på noder i samlinger med `publishing`-trait. Forhåndsvisning, slug-editor, bekreftelse. Avpublisering ved fjerning av edge.
- [ ] 14.4 RSS/Atom-feed: samling med `rss`-trait genererer feed automatisk ved publisering/avpublisering. `synops.no/pub/{slug}/feed.xml`.
- [ ] 14.5 Custom domains: bruker registrerer domene i `publishing`-trait. Maskinrommet validerer DNS, Caddy on-demand TLS med validerings-callback. Re-rendring med riktig canonical URL.
## Fase 15: Adminpanel
- [ ] 15.1 Systemvarsler: varslingsnode (`node_kind='system_announcement'`) med type (info/warning/critical), nedtelling og utløp. Frontend viser banner/toast for alle aktive klienter via STDB. Ref: `docs/concepts/adminpanelet.md`.
- [ ] 15.2 Graceful shutdown: admin setter vedlikeholdstidspunkt → nedtelling i frontend → nye LiveKit-rom blokkeres → jobbkø stopper → vent på aktive jobber → restart. Vis aktive sesjoner før bekreftelse.
- [ ] 15.3 Jobbkø-oversikt: admin-UI for aktive, ventende og feilede jobber. Filtrer på type/samling/status. Manuell retry og avbryt.
- [ ] 15.4 AI Gateway-konfigurasjon: admin-UI for modelloversikt, API-nøkler (kryptert), ruting-regler per jobbtype, fallback-kjeder, forbruksoversikt per samling. Ref: `docs/infra/ai_gateway.md`.
- [ ] 15.5 Ressursstyring: prioritetsregler mellom jobbtyper, ressursgrenser per worker, ressurs-governor for automatisk nedprioritering under aktive LiveKit-sesjoner, disk-status med varsling.
- [ ] 15.6 Serverhelse-dashboard: tjeneste-status (PG, STDB, Caddy, Authentik, LiteLLM, Whisper, LiveKit), metrikker (CPU, minne, disk), backup-status, logg-tilgang.
- [ ] 15.7 Ressursforbruk-logging: `resource_usage_log`-tabell i PG. Maskinrommet logger AI-tokens (inn/ut, modellnivå), Whisper-tid (sek), TTS-tegn, CAS-lagring (bytes), LiveKit-tid (deltaker-min). Båndbredde via Caddy-logg-parsing. Ref: `docs/features/ressursforbruk.md`.
- [ ] 15.8 Forbruksoversikt i admin: aggregert visning per samling, per ressurstype, per tidsperiode. Drill-down til jobbtype og modellnivå.
- [ ] 15.9 Brukersynlig forbruk: hver bruker ser eget forbruk i profil/innstillinger. Per-node forbruk synlig i node-detaljer for eiere.
## 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.