Arbeidsflaten: workspace+tools-modell erstatter vokse-modellen

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) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-18 01:18:35 +00:00
parent 822bcb41d1
commit 9fefa0a8c2
8 changed files with 384 additions and 55 deletions

View file

@ -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

View file

@ -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)

View file

@ -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`.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.