synops/docs/features/universell_input.md
vegard a3dfa3b254 Webhook-templates: forhåndsdefinerte mappinger for kjente tjenester (oppgave 29.6)
Legger til et template-system for webhooks som vet hvordan kjente
tjenester strukturerer sine JSON-payloads, og mapper dem til
meningsfulle node title/content/metadata.

Templates:
- github-push: Commits med repo, branch, pusher, formaterte meldinger
- github-issues: Issue-hendelser med nummer, labels, state
- github-pull-request: PR-hendelser med branch-info, merge-status
- slack-message: Slack Event API-meldinger med kanal og bruker
- ci-build: Generisk CI/CD (GitHub Actions, GitLab CI, Jenkins)

Backend:
- webhook_templates.rs: Template-definisjoner og apply-logikk
- webhook.rs: Bruker template fra webhook-nodens metadata.template_id
- webhook_admin.rs: GET /admin/webhooks/templates, POST set_template,
  template_id i create og list

Frontend:
- Template-velger i opprett-skjema og på hver webhook-kort
- Kan bytte template på eksisterende webhooks

6 unit-tester for alle templates. Verifisert med curl mot live endpoint.
2026-03-18 22:10:33 +00:00

168 lines
5.5 KiB
Markdown

# 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