Fikser funnet under validering:
- Gjør collection-prop valgfri i alle trait-komponenter slik at de
fungerer i personlig arbeidsflate uten collection-kontekst
- Legger til null-guards for collection.id i alle derived-blokker
og funksjoner som oppretter edges
- Fjerner microsSinceUnixEpoch-rester fra STDB-migrasjonen —
createdAt er nå et tall (Unix µs), ikke et objekt
- Retter saveTimeout-lekkasje i collection-sida: timer ryddes nå
ved navigasjon mellom samlinger
- Fikser TypeScript-feil i editorial (number vs string, uoppnåelig
'scheduled'-sammenligning), studio (bigint vs number),
RecordingTrait ($state-generics)
- Typefeil redusert fra 55 → 4 (gjenværende er pre-eksisterende
i mixer.ts/livekit.ts, ikke fase 19-20)
Validert: Canvas pan/zoom, BlockShell, layout-persistering,
snarveier, transfer service, alle panelreworks. Frontend bygger OK.
- SoundPadGrid: spor setTimeout-IDer og rydd opp ved komponent-destroy
(unngår oppdatering av tilstand etter unmount)
- Admin usage: fiks skrivefeil "1 ar" → "1 år"
- tasks.md: marker 23.7 som fullført
Frontend bruker nå kun portvokterens WebSocket for sanntidsdata.
SpacetimeDB-klienten er erstattet med en enkel WebSocket-klient
som kobler til /ws-endepunktet og oppdaterer reactive stores direkte.
Frontend-endringer:
- Nye lokale typer (types.ts) erstatter STDB module_bindings
- connection.svelte.ts: WebSocket til portvokteren med auto-reconnect
- stores.svelte.ts: Prosesserer WS-meldinger (initial_sync + events)
- MixerTrait: STDB-reducers erstattet med HTTP API-kall
- api.ts: Nye mixer-endepunkter (create, gain, mute, effect, role)
- +layout.svelte: Fjernet dual-tilkobling, kun portvokterens WS
- pg-ws.svelte.ts: Slettet (erstattet av connection.svelte.ts)
Dokumentasjon:
- datalaget.md: Fase M1+M2 markert som fullført
- api_grensesnitt.md: Oppdatert arkitekturdiagram, nye mixer-endepunkter
StudioTrait var en minimal liste med TraitPanel-wrapper. Nå er den et
fullverdig BlockShell-panel som følger mønsteret fra CalendarTrait (20.7)
og EditorTrait (20.8):
- Fjernet TraitPanel-wrapper, bruker egen flex-layout som fyller BlockShell
- Viser lydfiler med metadata: format-tag, varighet, størrelse, dato
- Drag-and-drop ut: lydfiler kan dras til andre paneler (editor, kalender)
- Drop-aksept: mottar lydfiler fra andre paneler via BlockReceiver
- Viser prosesserte versjoner (derived_from edges) per fil
- Responsivt med @container queries (360px, 500px) og @media fallback
- Lagt til `studio` trait i trait-katalogen i docs/primitiver/traits.md
- accessToken sendes nå fra collection page til StudioTrait
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fjerner TraitPanel-wrapper og erstatter med selvstendig panel-layout
som matcher KanbanTrait/CalendarTrait-mønsteret:
- Selvstendig layout som fyller BlockShell content area
- Listevisning med klikk-for-å-redigere (inline tittel + innhold)
- Source_material-edges vises som "Kilder"-sidebar i editor-visningen
- Visuell venstrekant-markering på artikler med kilder
- Opprett ny artikkel direkte fra panelet
- Container queries for responsiv tilpasning (small/medium/mobile)
- Beholder all eksisterende funksjonalitet: AI preset drops, publisering,
drag-and-drop ut av panelet
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CalendarTrait var tidligere en stub med lenke til /calendar-ruten.
Nå er hele kalender-UI-et innebygd direkte i panelet:
- Månedsgrid med navigasjon (forrige/neste/i dag)
- Hendelser vises som fargekodede chips i dagceller
- Drag-and-drop mellom datoer for å flytte hendelser
- Inline opprettelse av nye hendelser (tittel + valgfri tid)
- setDragPayload for å dra hendelser til andre paneler
- BlockReceiver: aksepterer content/communication-noder fra chat/kanban
- Responsivt med @container queries for små paneler
- Hendelsesliste under grid for oversikt over måneden
Følger samme mønster som ChatTrait (20.5) og KanbanTrait (20.6).
accessToken sendes nå til CalendarTrait fra collection-siden.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
KanbanTrait var tidligere bare en lenke til /board/[id]. Nå viser den
kolonner og kort direkte i BlockShell-panelet, med full funksjonalitet:
- Inline kanban-brett med kolonner (todo/in_progress/done) fra metadata
- Intern drag-and-drop mellom kolonner (status-edge oppdatering)
- Cross-panel drag: kort bruker setDragPayload for drag til andre paneler
- BlockReceiver: aksepterer drops fra chat/editor (innholdstransfer-modus)
- Opprett kort direkte i kolonne (inline input)
- Responsivt: kolonner stables vertikalt på smale paneler (@container + @media)
- accessToken-prop lagt til for mutasjoner
/board/[id]-ruten beholdes som frittstående visning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ChatTrait viser nå meldinger, input og taleopptak direkte i panelet i
stedet for bare lenker til /chat/[id]. Ved flere kanaler vises kanalliste
med klikk-navigasjon; ved én kanal åpnes chatten direkte.
Endringer:
- ChatTrait: inline meldingsvisning, ChatInput, AudioPlayer, auto-scroll
- BlockReceiver peker nå til aktiv kanal (ikke bare collection)
- Meldingsbobler er draggable ut til andre paneler
- Responsivt flex-layout som tilpasser seg container-størrelse
- accessToken-prop lagt til (trengs for meldingssending)
- Forelder-sider oppdatert til å sende accessToken
- /chat/[id]-ruten beholdes som frittstående fullside-visning
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transfer service bestemmer overføringsmodus basert på verktøy-par:
- innholdstransfer (ny node + source_material edge) for transformasjoner
(f.eks. chat → editor: chatboble blir kilde for ny artikkel)
- lettvekts-triage (ny edge/plassering) for konteksttillegg
(f.eks. chat → kanban: noden vises i begge kontekster)
Shift-modifier overstyrer alltid til innholdstransfer (ny node).
Endringer:
- transfer.ts: resolveTransferMode() med verktøy-par-matrise,
executeTransfer() som kaller API for node/edge-opprettelse
- BlockShell: sender e.shiftKey til onDrop-callback
- Workspace handlePanelDrop: kobler sammen modus-resolving og API-kall
- Docs: oppdatert universell_overfoering.md med implementasjonsstatus
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hver trait-komponent (Chat, Kanban, Kalender, Editor, Studio) har nå
en BlockReceiver med canReceive() som sjekker kompatibilitetsmatrisen.
Inkompatible drops viser forklaring og forslag til alternativ.
Endringer:
- transfer.ts: Per-verktøy compat-sjekker (checkChatCompat, checkKanbanCompat,
checkCalendarCompat, checkEditorCompat, checkStudioCompat) + createBlockReceiver factory
- types.ts: BlockReceiver utvidet med optional receive() + PlacementIntent type
- BlockShell.svelte: Validerer payload på faktisk drop (ikke bare drag-over)
- Alle 5 traits: Eksporterer BlockReceiver med canReceive + receive
- workspace/+page.svelte: Kobler receivers til BlockShell i spatial canvas
- Doc oppdatert til å reflektere faktisk implementasjon
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Brukerens standard arbeidsflate med node_kind='workspace'.
Vises på /workspace når ikke koblet til en samling.
Backend:
- GET /my/workspace: finn eller opprett brukerens workspace-node
- Automatisk provisjonering ved første besøk (STDB + async PG)
- Owner-edge fra bruker til workspace
Frontend:
- /workspace rute med Canvas + BlockShell (gjenbruker spatial canvas)
- Fritt valg av verktøy-paneler fra verktøymeny
- Layout persisteres i workspace-nodens metadata via updateNode
- Tom-tilstand med verktøy-velger for nye brukere
- Responsivt: stacked tabs på mobil, spatial canvas på desktop
- Kontekst-velger i header for navigering til samlinger
Navigasjon:
- "Min flate"-knapp på mottak-siden
- "Min arbeidsflate" i ContextHeader dropdown for samlingssider
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dobbeltklikk på panel-header toggler minimert tilstand. Minimerte
paneler viser kun header (ikon + tittel), skjuler innhold og
resize-handles. Posisjon, bredde og full høyde bevares i layout
og gjenopprettes ved nytt dobbeltklikk. Tilstanden persisteres
i edge metadata sammen med resten av workspace-layouten.
Endringer:
- PanelLayout: nytt `minimized?`-felt
- BlockShellEvents: nytt `onMinimizeChange`-event
- BlockShell: minimized-prop, dblclick-handler, minimize-knapp,
skjuler content/resize når minimert
- Workspace-side: håndterer minimize-state, oppdaterer canvas-
objekthøyde til PANEL_HEADER_HEIGHT når minimert
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Erstatter den statiske headeren på arbeidsflaten med en interaktiv
kontekst-header som lar brukeren:
- Bytte mellom samlinger via nedtrekksmeny (kontekst-velger)
- Søke blant tilgjengelige samlinger
- Se mest brukte samlinger øverst (frekvens + recency-scoring)
- Legge til nye verktøy-paneler via verktøymenyen
- Se hvilke paneler som allerede er aktive på flaten
Nye filer:
- ContextHeader.svelte: header-komponent med kontekst-velger og verktøymeny
- workspace/recency.ts: localStorage-basert frekvens/recency-tracking
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BlockShell er panelrammen for arbeidsflaten — wrapper rundt hvert
verktøy-panel (trait). Gir konsistent header med tittel, fullskjerm-
og lukk-knapper, drag-handles for repositionering via header,
resize-handles på alle kanter og hjørner, og drop-sone med visuell
feedback (blå glow for kompatibel, rød for inkompatibel).
Responsivt: min/max constraints, mobil-tilpasning (stacked layout,
større touch-targets, ingen resize-handles). Bruker HTML5 drag-and-drop
API for overføring mellom paneler, pointer events for repositionering.
Filer:
- blockshell/types.ts — SizeConstraints, BlockReceiver, DropZoneState
- blockshell/BlockShell.svelte — selve wrapper-komponenten
- blockshell/index.ts — eksporter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer det felles canvas-underlaget som whiteboard, storyboard
og fremtidige canvas-views skal bruke. Ren Svelte 5 komponent uten
backend-avhengigheter.
Funksjoner:
- Pan/zoom kamera med CSS transforms (transform-origin: 0 0)
- Viewport culling med 200px margin for smooth scrolling
- Pointer events (unified mus + touch)
- Pinch-zoom og to-finger-pan for touch
- Snap-to-grid (toggle med G-tast eller toolbar)
- Fullskjermsmodus (fixed positioning)
- Lasso-seleksjon og shift+klikk multi-select
- Edge-pan ved drag nær kanter
- Responsivt: 44px touch targets på mobil, tilpasset toolbar
- zoomToFit() for å sentrere alle objekter
- Consumer-rendering via Svelte 5 snippets
Filer:
- frontend/src/lib/components/canvas/Canvas.svelte
- frontend/src/lib/components/canvas/types.ts
- frontend/src/lib/components/canvas/index.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Brukere kan nå opprette egne AI-preset-noder med custom prompt,
dele dem med samlinger/team via shared_with-edges, og redigere/slette
egne presets. Modellprofil (flash/standard) er låst — kun admin
kan oppgradere fra flash til standard.
Backend:
- POST /intentions/create_ai_preset: Oppretter custom preset med
tvunget category=custom og model_profile=flash. Valgfri deling
til samling i samme kall.
- update_node: Beskytter model_profile mot endring av ikke-admin.
Forhindrer kategori-endring fra custom til standard.
Frontend:
- AiToolPanel: "+ Nytt preset"-knapp, opprett/rediger-skjema med
tittel, prompt, retning, ikon og farge. Rediger/slett/del-knapper
for egne custom presets. Egendefinerte presets markert med "egn."
- createAiPreset() i api.ts.
Dokumentasjon:
- ai_verktoy.md: Oppdatert fasestatus, ny § 10 om egendefinerte
presets med API-eksempler og modellprofil-beskyttelse.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer toveis drag-and-drop mellom AI-verktøypanelet og
innholdspaneler, med visuell feedback og kompatibilitetssjekking.
Nye filer:
- transfer.ts: Sentralisert transfer-tjeneste med kompatibilitetsmatrise,
DragPayload-format (application/x-synops-transfer), og
inkompatibilitets-meldinger for lyd/bilde-noder.
Endringer:
- AiToolPanel: Drop-sone bruker presetets farge (dynamisk border/bg),
viser rød sone med forklaring ved inkompatible noder (lyd/bilde),
presets er draggable ut (for tool_to_node retning).
- EditorTrait: Aksepterer AI-preset drops på innholdsnoder (tool_to_node),
viser visuell feedback (lilla=kompatibel, rød=inkompatibel),
trigger in-place revisjon via aiProcess API.
- ChatTrait: Kommunikasjonsnoder er nå draggable til AI-verktøyet.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Svelte-komponent for AI-prosessering i arbeidsflaten:
- AiToolPanel.svelte: Viser ai_preset-noder fra STDB som velgbare
verktøy, med modell-indikator (flash/standard) og prompt-forhåndsvisning
- Drag-and-drop mottak for tekstnoder med visuell feedback
- Validerer kompatibilitet (kun content/communication-noder)
- Kaller /intentions/ai_process via ny aiProcess()-funksjon i api.ts
- Integrert i collection-siden, tilgjengelig for alle innloggede brukere
- EditorTrait: innholdsnoder er nå draggable for AI-prosessering
- Fritekst-felt for egendefinert instruksjon (backend-støtte kommer i 18.6)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tre endringer som sammen gir brukeren innsyn i FFmpeg-feil:
1. Backend: Nytt GET /query/job_status-endepunkt i queries.rs.
Frontenden pollet allerede denne URLen, men endepunktet manglet.
Returnerer status, result og error_msg fra job_queue.
2. RenderDialog: Ny error-tilstand med formatFfmpegError() som
trekker ut lesbar feilmelding fra FFmpeg stderr-dump. Viser
kort oppsummering + ekspanderbar full feilmelding via <details>.
3. Studio-side: Sender renderError til RenderDialog som errorMessage.
Toast-varselet vises kun når dialogen er lukket (unngår duplisering).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Legger til min/max-attributter på alle tallfelter i OperationPanel
slik at nettleseren hindrer ugyldig input før det sendes til backend.
Grensene matcher backend-valideringen i audio.rs:
- silenceThreshold: -96 til 0 dB
- silenceMinMs: 1 til 60000 ms
- normTarget: -70 til 0 LUFS
- fadeInMs/fadeOutMs: 1 til 300000 ms
- compThreshold: -60 til 0 dB
- compRatio: 1 til 20 (max lagt til, min fantes allerede)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Robotstemme: Ring-modulasjon via OscillatorNode som modulerer
GainNode.gain — gir metallisk, Dalek-aktig effekt. Justerbar
frekvens (30–300 Hz) og modulasjonsdybde (0–100%).
Monsterstemme: Egenutviklet AudioWorkletProcessor med phase vocoder
for sanntids pitch-shifting. Bruker overlap-add med 2048-sample FFT
og 4x overlap for ~42ms latens ved 48kHz. Pitch-faktor 0.5x–2.0x.
UI: Effektvelger-knapper (Robot/Monster) i FX-seksjon per kanal,
med fargekodede parametersliders som vises når effekten er aktiv.
On/off-state synkroniseres via STDB toggle_effect, parametere er
per-klient (ulike brukere kan ha forskjellige monitorinnstillinger).
STDB: Lagt til set_effect_param reducer for fremtidig param-synk
(krever spacetime CLI for publish — ikke deployet ennå).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer lydpads (inspirert av RødeCaster Pro II) i mixeren:
- mixer.ts: Nytt pad-system med AudioBuffer-caching, GainNode per pad,
og one-shot AudioBufferSourceNode-avspilling. Funksjoner for load,
play, stop, og gain-kontroll.
- livekit.ts: Data message-støtte (sendDataMessage, onDataMessage) for
synkronisert pad-avspilling på tvers av LiveKit-deltakere. Bruker
reliable delivery med topic-filtrering.
- SoundPadGrid.svelte: 4×2 responsivt pad-grid med fargede knapper.
Forhåndslaster lydfiler fra CAS til AudioBuffer. Visuell feedback
ved avspilling (scale-animasjon). Konfigurasjonsmodus for å sette
label, farge og laste opp lydfil per pad. Pad-konfig lagres i
metadata.mixer.pads på samlingsnoden.
- MixerTrait.svelte: Integrerer SoundPadGrid mellom kanalstriper og
master-seksjon. Sender isViewer-prop for tilgangskontroll.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer sanntids mixer-synkronisering mellom alle deltakere i et
LiveKit-rom via SpacetimeDB. Når én deltaker justerer gain eller muter
en kanal, oppdateres alle klienters Web Audio-graf og UI umiddelbart.
SpacetimeDB-modul (Rust):
- MixerChannel-tabell med room_id/target_user_id-indekser
- Reducers: set_gain (clamped 0.0-1.5), set_mute, toggle_effect,
create/delete_mixer_channel, set_mixer_role (editor/viewer)
- Viewer-sjekk i reducers — viewer kan ikke endre andres kanaler
- Opprydding av mixer-kanaler i close_live_room og clear_all
Frontend (SvelteKit):
- mixerChannelStore med reaktive callbacks og room_id-indeks
- MixerTrait leser delt state fra STDB, skriver endringer via reducers
- suppressRemoteSync-flagg forhindrer feedback-loop ved egne endringer
- Viewer-modus: disabled sliders/knapper for låste deltakere
- Visuell (V)-indikator for viewer-kanaler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer Mixer-UI som trait-komponent for samlingssider:
- Kanalstripe per deltaker med volumslider (0–150%), VU-meter (CSS),
nød-mute-knapp (rød, tydelig) og navnelabel
- Master-seksjon med fader, VU-meter og master-mute
- Responsivt design: stacked layout på mobil, horisontal på desktop
- Animert VU-meter via requestAnimationFrame og AnalyserNode-data
- Integrert i collection-siden som 'mixer'-trait
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Installerer livekit-client og bygger grunnlaget for sanntidslyd:
- $lib/livekit.ts: LiveKit-wrapper med romtilkobling, deltakersporing,
og Web Audio-ruting. Auto-attach av <audio> er deaktivert — all lyd
rutes gjennom AudioContext med GainNode per deltaker (klar for mixer).
- api.ts: joinCommunication/leaveCommunication API-funksjoner
- RecordingTrait.svelte: UI for tilkobling, mikrofon-toggle og deltakerliste
med live speaking-indikator
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Legger til to nye API-endepunkter for brukersynlig ressursforbruk:
- GET /my/usage — brukerens eget forbruk (filtrert på triggered_by)
- GET /query/node_usage — forbruk for én node (kun eier/admin)
Frontend:
- /profile — profilside med grafstatistikk og forbruksoversikt
- NodeUsage-komponent integrert i samlings-detaljsiden
- Brukernavn i header lenker nå til profilsiden
Tilgangssjekk: nodeforbruk krever created_by eller owner/admin-edge.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implementerer systemvarsler (system_announcement-noder) som vises som
banner/toast for alle aktive klienter i sanntid via SpacetimeDB.
Backend (maskinrommet):
- POST /intentions/create_announcement: oppretter varslingsnode med
validering av announcement_type (info/warning/critical), datoer
(scheduled_at, expires_at) og blocks_new_sessions. Visibility
settes automatisk til 'open' for broadcast til alle klienter.
- POST /intentions/expire_announcement: fjerner varslingsnode med
tilgangskontroll (kun eier kan slette).
Frontend:
- SystemAnnouncements.svelte: filtrerer nodeStore for aktive
system_announcement-noder, skjuler utløpte (expires_at), viser
nedtelling for planlagte hendelser (scheduled_at). Fargekoding:
rød (critical), gul (warning), blå (info). Critical kan ikke
dismisses. Oppdaterer nedtelling hvert sekund.
- Komponent lagt til i +layout.svelte for global synlighet.
- API-funksjoner (createAnnouncement, expireAnnouncement) i api.ts.
Ref: docs/concepts/adminpanelet.md § "Systemvarsler og vedlikeholdsmodus"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Publisert tittel, ingress, OG-bilde og undertittel er nå egne noder
koblet til artikler via title/subtitle/summary/og_image-edges.
Rendering bruker presentasjonselementer med fallback til artikkelfelt.
Backend:
- Ny query: GET /query/presentation_elements?article_id=...
- render_article_to_cas henter presentasjonselementer via edges
- fetch_article + fetch_index_articles bruker pres.elementer
- Batch-henting for forsideartikler (én SQL-spørring)
- ArticleData utvides med subtitle + og_image
- Alle fire temaer viser subtitle og OG-bilde
- SEO og_image-tag fylles fra presentasjonselement
Frontend:
- PresentationEditor.svelte: opprett/rediger tittel, undertittel,
ingress, OG-bilde med variantvelger (editorial/ai/social/rss)
- Integrert i PublishDialog via <details>-seksjon
- API-klient: fetchPresentationElements(), deleteNode()
Grunnlag for A/B-testing (oppgave 14.17): edge-metadata støtter
ab_status/impressions/clicks/ctr, best_of() prioriterer winner > testing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redaktøren ser alle artikler med submitted_to-edge til samlingen,
gruppert i fire kolonner etter status. Drag-and-drop mellom kolonner
endrer status via update_edge. Siste kolonne ("Planlagt") åpner en
dialog for å sette publish_at i edge-metadata — klar for oppgave 14.12
(planlagt publisering).
Backend: GET /query/editorial_board med forfatterinfo og edge-metadata.
Frontend: /editorial/[id] med sanntidsoppdateringer via SpacetimeDB.
Lenke fra PublishingTrait når require_approval er aktivt.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Visuell editor for redaksjonell forside-styring. Rute:
/collection/[id]/forside med tre soner (hero, featured, strøm).
- HTML5 drag-and-drop mellom hero/featured/strøm-plasser
- Pin-knapp per artikkel (forhindrer automatisk fjerning)
- Hurtigknapper for å flytte artikler mellom slots
- Forhåndsvisning via iframe av publisert forside
- Bruker POST /intentions/set_slot API fra maskinrommet
- Sanntidsdata fra SpacetimeDB (belongs_to-edges med slot-metadata)
- PublishingTrait viser nå «Rediger forside»-knapp og publisert-lenke
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Legger til et admin-panel på samlingssiden der man kan legge til/fjerne
traits fra katalogen og konfigurere per-trait-innstillinger. Endringene
sendes via updateNode til maskinrommet som validerer mot VALID_TRAITS.
- Ny updateNode-funksjon i api.ts
- Delt trait-katalog i lib/traits.ts (brukes av collection/new og TraitAdmin)
- TraitAdmin.svelte: toggle traits, rediger config-nøkler, lagre
- Integrasjon i collection/[id] med Traits-knapp i header
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Samlingsnoder med `metadata.traits` rendres nå som egne sider på
/collection/[id]. Hvert trait-navn mappes til en dedikert Svelte-komponent
som viser relevant UI. Traits uten egen komponent vises med et generisk panel.
Komponenter for 9 traits: editor, chat, kanban, podcast, publishing,
rss, calendar, recording, transcription. Mottak-siden viser traits som
pills og lenker til samlingssiden.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nytt GET /query/segments/srt-endepunkt som genererer nedlastbar SRT-fil
fra transcription_segments-tabellen. Bruker RLS-verifisert tilgang.
Frontend har nedlastingsknapp i TranscriptionView med autentisert fetch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ny funksjonalitet for å kjøre re-transkripsjon på eksisterende media-noder
og sammenligne gammel vs ny versjon per segment. Manuelt redigerte segmenter
fra forrige versjon blir uthevet, og brukeren velger per segment hvilken
versjon som skal beholdes.
Backend (Rust):
- POST /intentions/retranscribe — trigger ny Whisper-jobb for media-node
- GET /query/transcription_versions — list alle versjoner for en node
- GET /query/segments_version — hent segmenter for spesifikk versjon
- POST /intentions/resolve_retranscription — anvend per-segment-valg
Frontend (Svelte):
- RetranscriptionCompare.svelte — side-om-side visning med per-segment-valg
- TranscriptionView: re-transkriber-knapp, auto-detect nye versjoner, polling
- API-klient: nye funksjoner for alle re-transkripsjonsendepunkter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend:
- GET /query/segments?node_id=... — henter nyeste segmenter for en media-node
med RLS-basert tilgangssjekk via nodes-tabellen
- POST /intentions/update_segment — redigerer segmenttekst, setter edited=true
Frontend:
- TranscriptionView.svelte: universell komponent for segment-visning med
tidsstempler, avspillingsknapp per segment, og redigerbare tekstfelt
- AudioPlayer: integrert med TranscriptionView når segmenter finnes,
faller tilbake til flat tekst ellers
- Mottak og chat-sider oppdatert med nodeId/accessToken for segment-lasting
- Fikser duration_ms → sekunder-konvertering i metadata-oppslag
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Legger til AudioPlayer-komponent som spiller av lyd fra CAS-noder
med waveform-visualisering via wavesurfer.js. Komponenten viser
play/pause, tidslinje, og kan ekspandere transkripsjonen.
Chat-visningen inkluderer nå media-noder (has_media-edges) sammen
med tekstmeldinger, sortert kronologisk. Talenotater vises med
mikrofon-ikon, waveform og transkripsjon.
Mottak-siden viser også AudioPlayer for media-noder med lyd.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Legger til VoiceRecorder-komponent som bruker MediaRecorder API for
lydopptak i nettleseren. Opptaket lastes opp til CAS via eksisterende
uploadMedia-endepunkt, som automatisk trigger Whisper-transkripsjon.
Komponenten er integrert i:
- ChatInput: mikrofon-knapp mellom tekstfelt og send-knapp
- NodeEditor: mikrofon-knapp i verktøylinjen
Flyten: opptak → webm/opus blob → upload → CAS → whisper_transcribe-jobb.
Ingen backend-endringer nødvendig — hele transkripsjons-pipelinen fra
oppgave 7.2 gjenbrukes uendret.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brukeren kan nå dra eller lime inn bilder i TipTap-editoren.
Bildet lastes opp til CAS via upload_media-endepunktet, og settes
inn som <img> med CAS-URL i metadata.document (HTML).
Endringer:
- Ny uploadMedia() og casUrl() i api.ts for multipart upload
- @tiptap/extension-image med CasImage-utvidelse (data-node-id attr)
- handleDrop/handlePaste i editor intercepter bildefiler
- Upload-status vises i editoren mens bilder lastes opp
- accessToken sendes ned til NodeEditor fra +page.svelte
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implementerer full 1:1 chat-loop:
- NewChatDialog: velg person å starte samtale med
- Fikser API-felt (participant_ids → participants) for korrekt
kommunikasjon med maskinrommets create_communication-endepunkt
- Opprett kommunikasjonsnode med to deltakere (owner + member_of)
- Dedupliserer: finner eksisterende samtale før ny opprettes
- Chat-header viser den andre deltakerens navn i 1:1-samtaler
- Testbruker-node opprettet på server for verifisering
Full loop verifisert via STDB: node + edges + melding + belongs_to
fungerer, WebSocket-subscribers ser endringer i sanntid.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Chat-visning i frontend som viser noder med belongs_to-edge til en
kommunikasjonsnode, sortert på tid, med sanntidsoppdatering via
SpacetimeDB.
Nye filer:
- frontend/src/routes/chat/[id]/+page.svelte — Chat-side som viser
meldinger (noder med belongs_to-edge), deltakere, auto-scroll,
og avsender-info. Bruker edgeStore.byTarget() for reaktive
oppdateringer når nye meldinger kommer via STDB.
- frontend/src/lib/components/ChatInput.svelte — Enkel meldings-input
med Enter-for-send, auto-resize textarea.
Endringer:
- frontend/src/lib/api.ts — Lagt til createCommunication()-funksjon
for å opprette kommunikasjonsnoder fra frontend.
- frontend/src/routes/+page.svelte — Kommunikasjonsnoder i mottaket
er nå klikkbare lenker til chat-visningen. "Ny samtale"-knapp.
- tasks.md — Oppgave 5.3 markert som ferdig.
Arkitektur: Chat-visningen bruker context_id-parameteren i
create_node-intensjonen (implementert i 5.2) for automatisk
belongs_to-edge. Meldinger hentes reaktivt fra STDB-stores —
ingen polling, ingen ekstra API-kall.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Legger til en TipTap-basert rik tekst-editor i mottaksflaten som sender
create_node-intensjoner til maskinrommet ved submit.
- TipTap med StarterKit (tekst, markdown), Link-extension og Placeholder
- NodeEditor.svelte: tittel + innhold, Ctrl+Enter for submit
- API-klient (lib/api.ts) som kaller maskinrommet via /api proxy
- Authentik access_token eksponert i session for API-kall
- Vite proxy rewrite fikset (/api → maskinrommet root)
- HTML-innhold lagres i metadata.document, ren tekst i content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>