From 9fefa0a8c257f48d8f7fd2210effc4c0c7255619 Mon Sep 17 00:00:00 2001 From: vegard Date: Wed, 18 Mar 2026 01:18:35 +0000 Subject: [PATCH] Arbeidsflaten: workspace+tools-modell erstatter vokse-modellen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ny retning: arbeidsflaten.md — spatial canvas med verktøy-paneler. Drag-and-drop mellom verktøy oppretter nye noder med source_material-edges. Noder muterer ikke — de føder nye noder. Oppdatert docs: - universell_input.md: "retyping" → "nye noder fra eksisterende" - rom_ikke_forum.md: "bli" → "føde", siloer → verktøy-paneler - universell_overfoering.md: blokker → verktøy-paneler, dual-modell - meldingsboks.md: multi-rolle → visning i flere kontekster Nye docs: - arbeidsflaten.md: retning med kompatibilitetsmatrise og inkompatibilitet - artikkelverktoy.md: langform TipTap-editor med drag-and-drop mottak Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 4 + docs/features/artikkelverktoy.md | 100 +++++++++++++ docs/features/meldingsboks.md | 12 +- docs/features/universell_overfoering.md | 89 +++++++----- docs/retninger/README.md | 1 + docs/retninger/arbeidsflaten.md | 184 ++++++++++++++++++++++++ docs/retninger/rom_ikke_forum.md | 21 +-- docs/retninger/universell_input.md | 28 ++-- 8 files changed, 384 insertions(+), 55 deletions(-) create mode 100644 docs/features/artikkelverktoy.md create mode 100644 docs/retninger/arbeidsflaten.md diff --git a/CLAUDE.md b/CLAUDE.md index 98017e5..e887315 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,6 +34,7 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`: - `maskinrommet.md` — Rust-orkestrator: fang, prosesser, lever - `bruker_ikke_workspace.md` — Noder er sentrum: brukere, team, innhold er noder. Tilgangsmatrise fra edges. - `datalaget.md` — PG(+AGE) som graf og arkiv, SpacetimeDB som sanntidslag + - `arbeidsflaten.md` — Spatial canvas med verktøy-paneler, drag-and-drop, kompatibilitetsmatrise - `docs/primitiver/` — Spesifikasjoner for kjerneprimitivene: - `nodes.md` — Node-skjema, node_kind, visibility, CAS-noder, eierskap - `edges.md` — Edge-skjema, typer, metadata, systemedges @@ -46,6 +47,9 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`: - `docs/features/` — Tekniske byggeklosser: - Se individuelle filer for chat, kanban, kalender, meldingsboks, kunnskapsgraf, whiteboard, live transkripsjon, ressursforbruk, m.fl. + - `lydstudio.md` — Lydredigering via FFmpeg, EDL, ikke-destruktiv prosessering + - `artikkelverktoy.md` — Langform TipTap-editor, drag-and-drop mottak, source_material-edges + - `universell_overfoering.md` — Drag-and-drop mellom verktøy-paneler, kompatibilitetsmatrise - `docs/proposals/` — Idébank med 32+ uimplementerte forslag (se README.md) - `docs/setup/` — Oppsett og drift: - `produksjon.md` — Steg-for-steg oppsett av Hetzner VPS fra scratch diff --git a/docs/features/artikkelverktoy.md b/docs/features/artikkelverktoy.md new file mode 100644 index 0000000..e7f5c98 --- /dev/null +++ b/docs/features/artikkelverktoy.md @@ -0,0 +1,100 @@ +# Feature: Artikkelverktøyet — langform-editor på arbeidsflaten + +## 1. Konsept + +Artikkelverktøyet er et verktøy-panel på arbeidsflaten med en TipTap-editor +optimalisert for langform-skriving. Det aksepterer drag-and-drop fra andre +paneler og oppretter innholdsnoder med `source_material`-edges tilbake +til kildene. + +Ref: [arbeidsflaten](../retninger/arbeidsflaten.md), +[publisering](../concepts/publisering.md) + +## 2. Opprettelse + +Når artikkelverktøyet åpnes, opprettes en ny innholdsnode: + +``` +node_kind: "content" +metadata.document: { "type": "doc", "content": [] } // Tom TipTap-doc +visibility: "hidden" // Privat til forfatteren deler +``` + +Noden er en artikkel fra fødsel — ingen "konvertering" fra annet innhold. + +## 3. Drag-and-drop mottak + +Artikkelverktøyet implementerer `BlockReceiver`-interfacet og aksepterer: + +| Kilde | Handling | Edge | +|-------|----------|------| +| **Chatboble** | Sett inn sitert tekst i editoren | `source_material` (context: "quoted") | +| **Transkripsjon** | Sett inn tekstblokk fra segment | `source_material` (context: "quoted") | +| **Bilde** | Sett inn inline-bilde | `has_media` | +| **Lydfil** | Sett inn lydavspiller (embed) | `has_media` | +| **Tekst/notat** | Sett inn innhold | `source_material` (context: "referenced") | +| **Annen artikkel** | Sett inn utdrag | `source_material` (context: "quoted") | + +Ved drop: +1. Ny `source_material`-edge fra artikkel → kilde +2. Innhold settes inn i editoren på markørposisjon +3. Visuell indikator i editoren viser at teksten har en kilde + (subtil venstrekant-markering, klikkbar for å se originalen) + +## 4. Editor-konfigurasjon + +TipTap med fulle extensions for langform: + +- Overskrifter (h2, h3, h4) +- Blockquotes, kodeblokker +- Bilder (inline, refererer CAS-noder via `has_media`) +- Lister (ordnet, uordnet, sjekklister) +- Tabeller +- Lenker +- Embeds (lyd, video) + +Forenklede presets tilgjengelig: +- **Artikkel** (default): alle extensions +- **Show notes**: lister, tidskoder, lenker +- **Notat**: tekst, sjekklister + +## 5. Publiseringsintegrasjon + +Artikkelen følger publiseringsreisen via edge-progresjon: + +``` +intended_for → submitted_to → belongs_to +(arbeidsfase) (vurdering) (publisert) +``` + +Publiseringspanelet vises ved siden av editoren når `intended_for`-edge +finnes. Forfatteren fyller ut presentasjonselementer (tittel, ingress, +forsidebilde) som egne noder med edges til artikkelen. + +## 6. Kildesporbarhet + +Artikkelens `source_material`-edges gir komplett lineage: + +``` +Artikkel "Trikken kan bli gratis" + ←source_material── Chatboble i #redaksjon (sitert) + ←source_material── Transkripsjonssegment fra episode 42 (sitert) + ←source_material── Notat fra dagboken (referert) + ←has_media──────── Bilde av trikken (CAS-media) +``` + +UI viser en "Kilder"-panel i editoren med alle koblede noder. +Klikk → naviger til originalen. + +## 7. Bygger på + +- [Universell input](../retninger/universell_input.md) — TipTap-editor, dokumentlagring +- [Publisering](../concepts/publisering.md) — publiseringsreise via edges +- [Arbeidsflaten](../retninger/arbeidsflaten.md) — drag-and-drop, verktøy-panel +- [Universell overføring](universell_overfoering.md) — mottaker-interface + +## 8. Responsivt + +- **Desktop:** Side ved side med andre paneler, full editor +- **Tablet:** Fullskjerm-editor med "Send til..."-meny for kilder +- **Mobil:** Forenklet editor, ingen drag-and-drop (bruk meny) diff --git a/docs/features/meldingsboks.md b/docs/features/meldingsboks.md index 3130d92..3379fbc 100644 --- a/docs/features/meldingsboks.md +++ b/docs/features/meldingsboks.md @@ -166,9 +166,15 @@ Aktive verdier etter migrering: Utfasede verdier (kan ikke fjernes fra PG ENUM, men skal aldri brukes i ny kode): `'aktør'`, `'tema'`, `'faktoide'`, `'note'`, `'kanban_card'`, `'calendar_event'` -## 4. Multi-rolle via view-config +## 4. Visning i flere kontekster -Konvertering = legg til view-config. Ingen data flyttes: +En node kan vises i flere verktøy samtidig via edges og view-configs. +For lettvekts-triage (node → kanban, node → kalender) legges en edge/ +view-config til. For innholdstransformasjon (chatboble → artikkel) +opprettes en ny node med `source_material`-edge. Se +[arbeidsflaten](../retninger/arbeidsflaten.md). + +Multi-visning via view-config (samme node, flere kontekster): ``` Meldingsboks (messages + nodes) @@ -312,7 +318,7 @@ Migrasjonen konverterer eksisterende data: - **Kalenderhendelse:** INSERT i `nodes` + `messages` (med tittel) + `calendar_event_view`. Én transaksjon. - **Faktoide:** INSERT i `nodes` + `messages` (`message_type = 'factoid'`) + `graph_edges` med `ABOUT`-relasjon til aktør/tema. Én transaksjon. - **Notat:** INSERT i `nodes` + `messages` (med tittel + body). `channel_id` peker på en personlig eller delt channel, eller er NULL. -- **Konvertering mellom roller:** Legg til view-config-rad (kanban/kalender). Aldri kopier data. +- **Visning i ny kontekst:** Legg til view-config-rad (kanban/kalender) for lettvekts-triage. For innholdstransfer: ny node med `source_material`-edge. - **Kontekst-navigering:** Bruk `reply_to`-kjeden for å bygge brødsmulesti tilbake til opprinnelig diskusjonskontekst. - **TTL:** Implementér som nattlig jobbkø-jobb (`message_ttl_cleanup`). Sjekk fritak-regler før sletting. Ved sletting: slett fra `messages` → cascade til `nodes` via FK. - **Tilgang:** Styres via `node_access`-matrisen. Visibility håndteres i applikasjonskode (SvelteKit): `WHERE visibility = 'shared' OR author_id = $current_user`. diff --git a/docs/features/universell_overfoering.md b/docs/features/universell_overfoering.md index d7696d0..33cd98e 100644 --- a/docs/features/universell_overfoering.md +++ b/docs/features/universell_overfoering.md @@ -1,22 +1,38 @@ -# Feature: Universell overføring — flytt objekter mellom blokker +# Feature: Universell overføring — flytt innhold mellom verktøy **Filsti:** `docs/features/universell_overfoering.md` ## 1. Konsept -Universell overføring er mekanikken som lar brukere flytte meldingsboks-objekter mellom vilkårlige blokker: fra storyboard til chat, fra kanban til kalender, fra chat til storyboard. Enhver blokk kan *sende* og *motta* objekter. Meldingsboksen er alltid det underliggende objektet — overføringen endrer kun *view-config*, ikke selve meldingen. +Universell overføring er kjerneinteraksjonen på arbeidsflaten: drag-and-drop +mellom verktøy-paneler. Se [arbeidsflaten](../retninger/arbeidsflaten.md) for +den overordnede retningen. -### 1.1 Grunnprinsipp +### 1.1 To moduser -En meldingsboks (node i kunnskapsgrafen) kan ha flere samtidige roller via view-configs (se `meldingsboks.md` §4). Universell overføring gjør dette til en førsteklasses brukerinteraksjon: +| Modus | Hva skjer | Eksempel | +|-------|-----------|---------| +| **Innholdstransfer** | Ny node opprettes med `source_material`-edge til kilden | Chatboble → artikkelverktøy: ny artikkelnode | +| **Lettvekts-triage** | Eksisterende node får ny edge/plassering | Chatboble → kanban: noden vises i kanban OG chat | + +Default avhenger av verktøy-paret. Se kompatibilitetsmatrisen i +[arbeidsflaten](../retninger/arbeidsflaten.md). Bruker kan overstyre +med modifier-tast (Shift = alltid ny node). + +### 1.2 Grunnprinsipp ``` -Bruker drar kort fra Storyboard → slipper på Chat-blokken - → Meldingen får en ny plassering i chatten (placement-record) - → Meldingen beholder sin posisjon på storyboardet - → Diskusjonstråden er synlig begge steder (samme objekt) +Bruker drar kort fra Chat → slipper på Artikkelverktøyet + → Ny artikkelnode opprettes med sitert tekst + → source_material-edge kobler artikkel → chatboble + → Chatboblen forblir uendret i chatten + +Bruker drar kort fra Chat → slipper på Kanban-brettet + → Noden får board-edge + status-edge (lettvekts) + → Noden vises i kanban OG chat (samme node, to kontekster) ``` -Alternativt kan brukeren *flytte* (fjerne fra kilde, legge til i mål) i stedet for å *kopiere* (beholde begge). Kontekstmeny gir valget. +Bruker kan alltid flytte (fjerne fra kilde) i stedet for å kopiere +(beholde begge). Kontekstmeny gir valget. ## 2. Plasseringsrelasjon (Placement) @@ -70,10 +86,10 @@ En melding opprettet mandag i chatten som dras til storyboardet onsdag har `crea ### 3.1 Drag-and-drop -Brukeren drar et objekt ut av en blokk. Når objektet forlater blokk-grensen: +Brukeren drar et objekt ut av en verktøy-panel. Når objektet forlater verktøy-panel-grensen: 1. Objektet blir en "ghost" (semi-transparent drag-representasjon) -2. Andre blokker som kan motta objektet highlighter sin mottakssone +2. Andre verktøy-paneler som kan motta objektet highlighter sin mottakssone 3. Slipp på en mottakssone → overføring ### 3.2 Kontekstmeny: "Send til..." @@ -88,7 +104,7 @@ Høyreklikk kort → "Send til..." → └── 🎬 Storyboard: Episode 47 ``` -Listen viser alle blokker brukeren har tilgang til som kan motta meldinger. +Listen viser alle verktøy-paneler brukeren har tilgang til som kan motta meldinger. ### 3.3 Flytt vs. kopier @@ -97,31 +113,35 @@ Listen viser alle blokker brukeren har tilgang til som kan motta meldinger. ## 4. Mottak-mekanikk (target) -Hver blokk-type definerer en **mottaker** som bestemmer hva som skjer når et objekt ankommer: +Hver verktøy-panel-type definerer en **mottaker** som bestemmer hva som skjer når et objekt ankommer: -### 4.1 Mottaker per blokk-type +### 4.1 Mottaker per verktøy-panel-type -| Blokk | Default-plassering | Visuell feedback | +| Verktøy-panel | Default-plassering | Visuell feedback | |-------|-------------------|-----------------| | **Chat** | Ny melding i bunnen, `entered_at = now()` | Kort blinker inn i chatflyten | | **Kanban** | Første kolonne (eller "Innboks"), posisjon øverst | Kort glir inn i kolonnen | | **Storyboard** | Senter av viewport (eller slipp-posisjon) | Kort fader inn | | **Kalender** | Dagens dato, heldagshendelse | Dato highlighter | -| **Notes** | Ny blokk i bunnen av notatet | Tekst fades inn | +| **Notes** | Ny verktøy-panel i bunnen av notatet | Tekst fades inn | -### 4.2 Mottakssone-rendering +### 4.2 Mottakssone-rendering og inkompatibilitet -Hver blokk rendrer en visuell drop-target når en drag er aktiv: +Hver verktøy-panel rendrer en visuell drop-target når en drag er aktiv: -- **Hele blokken** lyser opp med en subtil border/glow -- **Spesifikke soner** (f.eks. en kolonne i kanban, en dato i kalender) highlighter ved hover -- **Avviste drops** (feil type objekt) viser en dempet tilstand +- **Kompatibel:** Panelet lyser opp med subtil border/glow +- **Spesifikke soner** (f.eks. en kolonne i kanban) highlighter ved hover +- **Inkompatibel:** Drop-sonen er rød/grå. Tooltip forklarer *hvorfor* + og foreslår alternativ der det gir mening. + +Se kompatibilitetsmatrisen i [arbeidsflaten](../retninger/arbeidsflaten.md) +for komplett oversikt over hva som kan dras til hva. ### 4.3 Mottaker-interface ```typescript interface BlockReceiver { - /** Kan denne blokken motta dette objektet? */ + /** Kan denne verktøy-panelen motta dette objektet? */ canReceive(message: Message): boolean; /** Opprett plassering for mottatt objekt */ @@ -132,7 +152,7 @@ interface BlockReceiver { } ``` -Alle blokk-typer implementerer dette interfacet. +Alle verktøy-panel-typer implementerer dette interfacet. ## 5. SpacetimeDB-integrasjon @@ -164,15 +184,15 @@ Sync-workeren persisterer til PG `message_placements`-tabellen. ## 6. Responsivt design -- **Desktop:** Drag-and-drop mellom blokker fungerer naturlig +- **Desktop:** Drag-and-drop mellom verktøy-paneler fungerer naturlig - **Tablet:** Drag-and-drop fungerer med touch, men "Send til..."-meny er primær -- **Mobil:** Kun "Send til..."-meny (blokker er stacked i én kolonne, drag mellom dem er upraktisk) +- **Mobil:** Kun "Send til..."-meny (verktøy-paneler er stacked i én kolonne, drag mellom dem er upraktisk) ## 7. Bygger på - **Meldingsboks** (`meldingsboks.md`): Alle overførte objekter er meldingsbokser - **Kunnskapsgraf** (`kunnskapsgraf_og_relasjoner.md`): Plasseringer er relasjoner i grafen -- **BlockShell** / PageGrid: Blokk-rammen som rendrer mottakssoner +- **BlockShell** / PageGrid: Verktøy-panel-rammen som rendrer mottakssoner - **SpacetimeDB** (`synkronisering.md`): Sanntidssynk av plasseringer ## 8. Konsekvenser for eksisterende kode @@ -181,7 +201,7 @@ Sync-workeren persisterer til PG `message_placements`-tabellen. `BlockShell` trenger: - `onDragEnter`/`onDragLeave`/`onDrop` handlers for visuell feedback -- Prop for `receiver: BlockReceiver` fra innholdsblokken +- Prop for `receiver: BlockReceiver` fra innholdsverktøy-panelen - Fullskjerm-toggle (knapp i header + Esc for å lukke) ### 8.2 Ny plasserings-tabell @@ -193,9 +213,12 @@ Sync-workeren persisterer til PG `message_placements`-tabellen. Ny tabell `message_placement` med reducers for place/remove/move. ## 9. Instruks for Claude Code -- Overføring oppretter aldri en kopi av meldingen — kun en ny plassering (view-config) -- `entered_at` er alltid `now()` ved overføring, aldri kopiert fra kilden -- En melding uten noen plasseringer er "løs" — den eksisterer i grafen men vises ikke noe sted. UI skal advare om dette ved siste fjerning -- Drag-and-drop bruker HTML5 Drag and Drop API for blokk-til-blokk, og pointer events for intra-canvas (storyboard/whiteboard) -- Hold overføringslogikken i en sentral `transferService` — ikke spread ut i hver blokk-type -- Mottaker-interfacet er obligatorisk for alle blokk-typer +- **Innholdstransfer** (ny node) brukes når innholdet transformeres (chat → artikkel) +- **Lettvekts-triage** (ny edge/plassering) brukes når kontekst legges til (chat → kanban) +- `source_material`-edge kobler ny node tilbake til kilden ved innholdstransfer +- `entered_at` er alltid `now()` ved plassering, aldri kopiert fra kilden +- En melding uten noen plasseringer er "løs" — UI advarer ved siste fjerning +- Inkompatible drops gir visuell feedback (rød/grå) + tooltip med forklaring +- Drag-and-drop bruker HTML5 API mellom paneler, pointer events intra-canvas +- Hold overføringslogikken i en sentral `transferService` +- Mottaker-interfacet er obligatorisk for alle verktøy-panel-typer diff --git a/docs/retninger/README.md b/docs/retninger/README.md index 450c836..46ea9c9 100644 --- a/docs/retninger/README.md +++ b/docs/retninger/README.md @@ -27,6 +27,7 @@ andre dokumenter. En retning kan også forkastes eller parkeres. | [Maskinrommet](maskinrommet.md) | **Besluttet** | Én Rust-tjeneste: fang, prosesser, lever. Eier all skriving. Edge-drevet ressursorkestrering. | | [Noder er sentrum](bruker_ikke_workspace.md) | **Besluttet** | Alt er noder (brukere, team, innhold). Edges definerer relasjoner og tilgang. Materialisert tilgangsmatrise for RLS. | | [Datalaget](datalaget.md) | **Besluttet** | SpacetimeDB holder hele grafen, PG er persistent arkiv, CAS for binærdata, AGE ved behov | +| [Arbeidsflaten](arbeidsflaten.md) | **Besluttet** | Spatial canvas med verktøy-paneler. Drag-and-drop skaper nye noder med edges. | ### Relaterte spesifikasjoner diff --git a/docs/retninger/arbeidsflaten.md b/docs/retninger/arbeidsflaten.md new file mode 100644 index 0000000..2ce6d87 --- /dev/null +++ b/docs/retninger/arbeidsflaten.md @@ -0,0 +1,184 @@ +# Arbeidsflaten — verktøy og rom + +**Status: Besluttet.** + +> Arbeidsflaten er en spatial canvas der verktøy-paneler lever side ved side. +> Brukeren arrangerer sitt eget rom. Drag-and-drop mellom verktøy er +> kjerneinteraksjonen. Innhold flyter mellom verktøy via nye noder og edges. + +## Observasjoner + +Synops har bygget chat, kanban, kalender, studio, kunnskapsgraf — hver som +sin visning. De er alle spørringer mot samme graf, men de lever på separate +ruter (`/chat/[id]`, `/board/[id]`, `/calendar`). Brukeren navigerer mellom +dem. + +Tidligere beskrev vi at innhold "vokser" mellom kategorier: en chatmelding +kan "bli" en artikkel ved å få edges. Arkitektonisk elegant, men klønete i +praksis — du vil ikke redigere en chatboble til en langform-artikkel. + +Observasjoner som ledet hit: + +- **Verktøy-spesifikke oppgaver trenger verktøy-spesifikke grensesnitt.** + En artikkel-editor er ikke en chat-input. Et lydstudio er ikke en + medieavspiller. Å late som alt er én overflate gir dårlig UX. +- **Kontekstbytte koster.** Å navigere mellom /chat og /board og /calendar + bryter flyten. Verktøyene bør leve side ved side. +- **Innhold bør flyttes mellom verktøy, ikke muteres.** + Når en chatmelding inspirerer en artikkel, bør resultatet være en *ny* + artikkelnode med en edge tilbake til meldingen — ikke en mutert melding. + +## Tesen + +**Arbeidsflaten er et personlig rom med verktøy-paneler.** Brukeren +arrangerer sin egen flate med de verktøyene de trenger. Drag-and-drop +mellom paneler er den primære interaksjonen for å flytte innhold. + +Nøkkelprinsipp: **Noder føder nye noder.** Når innhold flyttes mellom +verktøy, opprettes nye noder med `source_material`-edges tilbake til +kilden. Originalen forblir uendret. Artikkelen sporer sine kilder +gjennom grafen. + +## Verktøy-paneler + +Hvert verktøy er en selvinneholdt Svelte-komponent som: +- Tar `nodeId` / `collectionId` + config som props +- Håndterer egen datahenting og tilstand +- Respekterer container-størrelse (responsive innenfor panelet) +- Kan maksimeres til fullskjerm +- Implementerer drag-and-drop mottak der det gir mening + +| Verktøy | Hva det gjør | Aksepterer drag | +|---------|--------------|-----------------| +| **Chat** | Sanntidsmeldinger i kommunikasjonsnode | Vilkårlig node → del som melding | +| **Artikkelverktøy** | TipTap langform-editor | Chatbobler, tekst, transkripsjoner, bilder, lyd | +| **Kanban** | Oppgavestyring med kolonner | Chatbobler, tekst → ny oppgave | +| **Kalender** | Tidslinje med `scheduled`-edges | Kanban-kort, chatbobler → ny hendelse | +| **Lydstudio** | Waveform-redigering, ffmpeg-prosessering | Lydfiler → åpne i studio | +| **Kunnskapsgraf** | D3-visualisering av noder og edges | — (visuell utforsker) | +| **Transkripsjon** | Segmenter synkronisert med lyd | — (les-visning) | +| **Dagbok** | Private notater, kronologisk | — (personlig) | +| **AI-verktøy** | Konfigurerbar AI-tekstbehandling med prompt-velger | Tekstnoder, chatbobler, transkripsjoner → AI-prosessert output | + +## Drag-and-drop mellom verktøy + +### Mekanisme + +1. Bruker drar en node fra verktøy A +2. Under drag vises drop-soner i kompatible verktøy +3. Ved drop: mål-verktøyet bestemmer hva som skjer +4. Typisk: ny node opprettes + `source_material`-edge til kilden +5. Alternativt: eksisterende node får ny edge (lettvekts-triage) + +### To moduser + +| Modus | Hva skjer | Når | +|-------|-----------|-----| +| **Innholdstransfer** | Ny node opprettes med `source_material`-edge | Innholdet transformeres (chat → artikkel, chat → oppgave) | +| **Lettvekts-triage** | Eksisterende node får ny edge | Kontekst legges til (node → kanban-board, node → kalender) | + +Default avhenger av verktøy-paret. Bruker kan overstyre med modifier-tast +(Shift = alltid ny node). + +## Kompatibilitetsmatrise + +| Kilde → Mål | Artikkelverktøy | Chat | Kanban | Kalender | Studio | +|---|---|---|---|---|---| +| **Chatboble** | Ny artikkelnode, sitert tekst, `source_material` | (samme kontekst) | Ny oppgave + `source_material` | Ny hendelse + `source_material` | — | +| **Tekst/notat** | Kopier inn, `source_material` | Del som melding med `mentions` | Ny oppgave | Ny hendelse | — | +| **Lydfil** | Sett inn avspiller, `has_media` | Del med mention | — | — | Åpne i studio | +| **Lydfil → Lydfil** | — | — | — | — | **Inkompatibel** | +| **Transkripsjon** | Sett inn tekst + `source_material` | Del utdrag | — | — | — | +| **Kanban-kort** | Kopier innhold + `source_material` | Del som melding | (flytt mellom kolonner) | Legg til `scheduled` edge | — | +| **Bilde** | Sett inn + `has_media` | Del som melding | — | — | — | +| **Vilkårlig node** | — | Del-melding med `mentions` | — | — | — | +| **AI-verktøy → node** | — | — | — | — | — | + +**AI-verktøy som mål:** + +| Kilde → AI-verktøy | Resultat | +|---|---| +| **Chatboble** | Ny node med AI-output + `derived_from`-edge | +| **Tekst/notat** | Ny node med AI-output + `derived_from`-edge | +| **Transkripsjon** | Ny node med AI-output + `derived_from`-edge | +| **Lydfil/bilde** | Inkompatibel: "AI-verktøyet behandler kun tekst" | + +**AI-verktøy som kilde (dra verktøyet → tekstnode):** +Modifiserer noden in-place. Originalen versjoneres. Se `docs/features/ai_verktoy.md`. + +"—" betyr at kombinasjonen ikke gir mening og drop-sonen er inaktiv. + +## Inkompatibilitet + +Ikke alt kan gå overalt. Når en drag er inkompatibel: + +1. **Visuell feedback:** Drop-sonen blir rød/grå under drag-over +2. **Forklaring:** Tooltip viser *hvorfor* — ikke bare "kan ikke slippes her" +3. **Alternativ:** Foreslå en bedre handling der det er mulig + +### Eksempler + +| Forsøk | Feedback | +|--------|----------| +| Lydfil → Lydfil | "Lydfiler kan ikke slås sammen direkte. Åpne i Studioet for å redigere." | +| Bilde → Studio | "Studioet behandler kun lydfiler." | +| Lydfil → Kanban | "Lydfiler kan ikke bli oppgaver direkte. Dra til Chat for å dele, eller til Artikkelverktøyet for å sette inn." | + +## Tre lag for arbeidsflaten + +Hver bruker har sin egen arbeidsflate. Arrangement lagres som preferanser +på brukernoden. + +| Lag | Kilde | Forrang | +|-----|-------|---------| +| **Personlig** | Brukerens eget arrangement | Høyest — overstyrer alt | +| **Node-default** | Samlingens traits foreslår layout | Mellom — utgangspunkt | +| **Plattform-default** | Synops sine standarder | Lavest — fallback | + +Eksempel: en samling med `podcast` + `studio` + `chat` traits foreslår +en layout med disse tre panelene. Brukeren kan flytte, legge til, fjerne +paneler fritt. Arrangementet huskes per bruker per kontekst. + +## `source_material`-edge + +Ny edge-type som kobler en avledet node til kilden den ble laget fra. + +``` +Artikkel-node ──source_material──→ Chatboble +Artikkel-node ──source_material──→ Transkripsjonssegment +Artikkel-node ──source_material──→ Notat +``` + +Edge-metadata: +```jsonc +{ + "context": "quoted", // "quoted", "summarized", "referenced" + "excerpt": "Den opprinnelige teksten som ble dratt inn" +} +``` + +Gir artikler sporbar lineage: du kan alltid se *hvor* materialet kom fra. + +## Forhold til andre retninger + +- **[Rom, ikke forum](rom_ikke_forum.md):** Arbeidsflaten *er* rommet. + Verktøy-paneler er lagene som kan slås av og på. "Trylle frem, legge + fra seg" realiseres som paneler som dukker opp og forsvinner. +- **[Universell input](universell_input.md):** Input-primitiven lever + i hvert verktøy med kontekst-tilpasset konfigurasjon. Arbeidsflaten + bestemmer *hvor* input havner. +- **[Noder er sentrum](bruker_ikke_workspace.md):** Verktøy er visninger + av grafen. Arbeidsflaten er brukerens personlige arrangement av disse + visningene. +- **[Datalaget](datalaget.md):** SpacetimeDB driver sanntidsoppdatering + mellom paneler. Drag-and-drop oppretter noder/edges som synkes instant. + +## Hva ville vært annerledes + +- Chat, kanban, kalender lever **side ved side**, ikke som separate sider +- Du **drar en chatboble til artikkelverktøyet** i stedet for å "retype" + den med edges +- Artikkelen **sporer sine kilder** via `source_material`-edges +- Inkompatible handlinger gir **tydelig feedback** med forklaringer +- Brukerens arrangement er **personlig og persistent** — du setter opp + arbeidsflaten din én gang og den huskes diff --git a/docs/retninger/rom_ikke_forum.md b/docs/retninger/rom_ikke_forum.md index 957ccee..6134871 100644 --- a/docs/retninger/rom_ikke_forum.md +++ b/docs/retninger/rom_ikke_forum.md @@ -84,11 +84,12 @@ Tesen ovenfor kan føles abstrakt. Mer konkret: Sidelinja bør være en der produktive ting er lette å oppnå og strukturen følger deg, ikke omvendt. ### Formløs input, struktur etterpå -I dag velger du visning først: "nå er jeg i chat", "nå er jeg i kanban." Men -meldingsboksen er allerede designet for at input ikke trenger å vite hva den -*er* på forhånd. En tanke bør kunne starte som en løs setning og bli et -kanban-kort, en faktoid, en kalenderoppføring — uten at brukeren måtte -bestemme det på forhånd. Visninger er flyktige linser. Innhold er permanent. +Input trenger ikke vite hva den *er* på forhånd. En tanke starter som en +løs setning i input-feltet. Etterpå kan den *føde* et kanban-kort, en +faktoid, en artikkel — brukeren drar den til riktig verktøy-panel på +arbeidsflaten, og en ny node opprettes med riktige edges. Originaltanken +forblir uendret. Verktøy-panelene bestemmer strukturen, ikke input-metoden. +Se [arbeidsflaten](arbeidsflaten.md). ### Trylle frem, legge fra seg Trenger du et whiteboard? Det dukker opp. En videosamtale? Den starter. @@ -98,10 +99,12 @@ trenger ikke "lukke" noe eller "lagre" noe. Ting eksisterer i verden og kan gjenfinnes. ### Siloer forsvinner -"Universell overføring" som eksplisitt feature blir overflødig fordi det -ikke finnes separate steder å overføre *mellom*. Du endrer ikke *hvor* -noe er — du endrer *hvordan* du ser på det som allerede er der. Chat, -kanban, kalender er ikke apper — de er visninger av samme tilstandsrom. +Universell overføring er ikke en separat feature — det er selve +interaksjonsmønsteret. Verktøy-paneler lever side ved side på +arbeidsflaten, og drag-and-drop mellom dem er den primære flyten. +Du flytter ikke innhold mellom apper — du drar det fra et verktøy +til et annet i rommet du allerede er i. Chat, kanban, kalender er +visninger av samme graf, arrangert på samme flate. ### Privat og delt som lag, ikke separate systemer Privat/delt er bare en diff --git a/docs/retninger/universell_input.md b/docs/retninger/universell_input.md index a94ebdc..1c401b8 100644 --- a/docs/retninger/universell_input.md +++ b/docs/retninger/universell_input.md @@ -58,9 +58,11 @@ setter en *default* editor-konfigurasjon. Men brukeren kan alltid overstyre — utvide til full editor eller forenkle. Ingen kunstig grense mellom "chatmelding" og "artikkel." -Du *kan* skrive en gjennomformatert tekst med overskrifter, bilder -og blockquotes i chatten. Om du vil publisere den etterpå er det -bare å legge til en publiserings-edge. Innholdet er det samme. +Du *kan* skrive en gjennomformatert tekst i chatten. Men hvis en +chatmelding inspirerer en artikkel, drar du den til artikkelverktøyet +på arbeidsflaten. En ny innholdsnode opprettes med `source_material`-edge +til meldingen. Artikkelen skrives i et verktøy designet for langform — +chatinput er designet for samtale. Se [arbeidsflaten](arbeidsflaten.md). Editoren husker brukerens valg per kontekst via preferanser på brukernoden. @@ -131,12 +133,16 @@ Hva en node "er" bestemmes utelukkende av edges: - Node + `mentions` → topic = faktoid i kunnskapsgrafen - Node uten edges = løs tanke, ennå uorganisert -**Retyping er trivielt.** Chatmelding → kanban-kort = legg til -board-edge og status-edge. Ingen datamigrering, bare edges. +**Nye noder fra eksisterende.** Chatmelding → oppgave = ny +oppgavenode med `source_material`-edge til meldingen. Meldingen +forblir uendret. For lettvekts-triage (noden vises i kanban OG +chat): legg til `status`-edge direkte — ingen ny node nødvendig. -**Multitype er naturlig.** En node kan være *både* kanban-kort -*og* kalenderoppføring *og* faktoid. Det er ikke en edge case — -det er arkitekturen. +**Multitype er naturlig.** En node kan ha flere roller samtidig +— både kanban-kort og kalenderoppføring og faktoid. Det er for +noder som genuint tjener flere formål, ikke for å "gro" en +chatboble til en artikkel. Artikkelen er en *ny* node med +`source_material`-edge. Se [arbeidsflaten](arbeidsflaten.md). ### Edge-tildeling @@ -144,8 +150,10 @@ Når du "bare sier noe" — hvem bestemmer edges? 1. **Kontekst gir det meste.** Du er i en samtale → `belongs_to`- edge til samtalen. Du er alene → privat. Dekker 80%. -2. **Eksplisitt handling.** Du drar en node til kanban-brettet. - Du tagger noe. Du setter en dato. +2. **Eksplisitt handling.** Du drar en node til kanban-brettet + (legg til board-edge) eller til artikkelverktøyet (ny node med + `source_material`-edge). Du tagger noe. Du setter en dato. + Se [arbeidsflaten](arbeidsflaten.md) for kompatibilitetsmatrise. 3. **AI-foreslått.** Systemet foreslår `mentions`-edge når du nevner en person. Foreslår kanban når noe ligner en oppgave.