# Feature: Universell input — alle modaliteter blir noder

## Prinsipp

Alt som kommer inn i Synops ender som en node. Modaliteten er
transport — tekst, tale, bilde, URL, epost, webhook, RSS, video,
lokasjon, tegning, kalender. Noden er det som lever videre.

## Modaliteter

### Allerede implementert

| Modalitet | Input | Node-type | Prosessering |
|-----------|-------|-----------|-------------|
| Tekst | Tastatur → editor/chat | content | — |
| Tale | Mikrofon → Whisper | content + media | STT → tekst i content |
| Bilde | Kamera/fil → CAS | media | Valgfri AI-beskrivelse |
| Fil | Drag-and-drop/upload | media | MIME-deteksjon |
| URL | Lim inn → synops-clip | content | Readability-parsing |
| Epost | synops-mail | content | Avsender-verifisering |
| Drag-and-drop | Interaksjonsmodell | edge / ny node | Kontekstavhengig |

### Nye modaliteter

#### Skjermklipp
Paste screenshot fra clipboard. Lavterskel visuell input.

```
Ctrl+V (bilde i clipboard)
  → Frontend detekterer ClipboardEvent med image
  → Upload til CAS → media-node
  → Valgfri: synops-ai "beskriv dette bildet" → description i metadata
  → Inline i chat/editor som bilde med bildetekst
```

Bruk: bug-rapportering, visuell referanse, hurtig deling.

#### RSS/Feed-abonnement
Automatisk innhenting fra eksterne kilder.

```
synops-feed --url https://nrk.no/nyheter/rss --collection-id <uuid>
  → Poller hvert 30. minutt
  → Nye entries → content-noder med source_url
  → AI-oppsummering valgfritt
  → Paywall-deteksjon gjenbrukt fra synops-clip
```

Perfekt som orkestrering: "Overvåk denne kilden og varsle
redaksjonen om relevante saker."

#### Webhook (universell ekstern input)
Alt som ikke er menneske kan prate med Synops.

```
POST /api/webhook/<token>
  Content-Type: application/json
  { "title": "Build passed", "status": "success", ... }

  → Vaktmesteren validerer token
  → Oppretter content-node med payload i metadata
  → belongs_to-edge til målsamling
```

Webhook-templates (forhåndsdefinerte mappinger) for kjente tjenester:
- **GitHub Push:** `[repo] Push til branch — N commit(s)` med formaterte commit-meldinger
- **GitHub Issues:** `[repo] Issue #N action: title` med labels og state
- **GitHub PR:** `[repo] PR #N action: title` med branch-info og merge-status
- **Slack:** `Slack #channel — user` med meldingstekst
- **CI/CD:** `[repo] Build STATUS: pipeline` med branch, varighet og lenke

Template-id lagres i webhook-nodens metadata (`metadata.template_id`).
Admin-API: `GET /admin/webhooks/templates` (liste), `POST /admin/webhooks/set_template`.
Uten template brukes generisk ekstraksjon (title/content/body-felt).

#### Video
Opptak direkte i nettleseren.

```
[● Opptak] → MediaRecorder API → webcam eller skjerm
  → Upload til CAS → media-node
  → Valgfri: synops-video for transcode + thumbnail
```

Bruk: korte videomeldinger, skjermopptak for feedback,
møte-opptak uten LiveKit.

#### Geolokasjon
"Jeg er her" som input.

```
[📍 Del posisjon] → Geolocation API
  → Node med metadata.location: { lat, lon }
  → Kart-visning i node-detaljer (OpenStreetMap)
  → Valgfri: reverse geocoding for adresse
```

Bruk: feltarbeid, lokasjonstagging av innhold,
"dette skjedde her".

#### Håndskrift/tegning
Rask skisse som input — ikke whiteboard, men post-it.

```
[✏️ Tegn] → Enkel canvas-flate
  → Eksporter som PNG → CAS → media-node
  → Inline i chat/editor
```

Bruk: hurtig-skisse, diagram på mobil, visuell idé.

#### Kalender-import
Synkroniser med eksisterende kalendere.

```
synops-calendar --file møter.ics --collection-id <uuid>
  → Parser ICS → noder med scheduled-edges
  → Duplikatdeteksjon via UID
  → Oppdatering ved re-import
```

CalDAV-abonnement for kontinuerlig synk med Google/Outlook.

## Universell input-komponent

Alle modaliteter er tilgjengelige fra samme input-komponent:

```
┌──────────────────────────────────────────┐
│ Skriv noe...                        [↑] │
│                                          │
│ 🎤  📷  📎  🔗  📍  ✏️  📹             │
│ tale bilde fil url pos tegn video        │
└──────────────────────────────────────────┘
```

Ikonrad under input-feltet. Klikk → aktiver modalitet.
Resultat havner alltid som node — inline i chat, eller
som frittstående i samlingen.

## Alt er noder

Uansett modalitet:

```
Tekst      → content-node (content-felt)
Tale       → media-node + content-node (etter STT)
Bilde      → media-node (metadata: cas_hash, mime)
Skjermklipp → media-node (metadata: source=screenshot)
Video      → media-node (metadata: cas_hash, duration)
URL        → content-node (metadata: source_url)
RSS-entry  → content-node (metadata: source_url, feed_url)
Webhook    → content-node (metadata: webhook_id, payload)
Lokasjon   → content-node (metadata: location)
Tegning    → media-node (metadata: source=drawing)
Kalender   → content-node + scheduled-edge
Epost      → content-node (metadata: from, subject)
```

Edges kobler dem til kontekst (samling, samtale, person).
Visninger (kanban, kalender, graf) viser dem riktig basert
på edges og metadata — ikke basert på modalitet.

## Bygger på
- `docs/retninger/universell_input.md` — tre primitiver
- `docs/concepts/orkestrering.md` — RSS/webhook som triggere
- `docs/features/nodereferanser.md` — n:-lenking av alle noder
- `docs/retninger/interaksjonsmodell.md` — drag-and-drop
