synops/docs/primitiver/traits.md
vegard 8f7d2d7fe8 MindMap-trait for samlingsnoder (oppgave 27.3)
Gjør mindmap til et offisielt trait som kan velges ved opprettelse
av samlingsnoder. Frontend-komponenten (27.1) og BlockShell-panelet
(27.2) var allerede på plass — dette kobler traiten inn i backend-
validering og pakke-definisjoner.

Endringer:
- Lagt til "mindmap" i VALID_TRAITS (intentions.rs)
- Validering av konfig: default_depth 1-3, layout radial/tree
- Inkludert mindmap i Podcaststudio- og Wiki-pakker (traits.ts)
- Oppdatert trait-katalog i docs/primitiver/traits.md
2026-03-18 19:44:30 +00:00

209 lines
9.8 KiB
Markdown

# Traits — Evner og funksjonalitet for noder
**Status:** Vedtatt
## Konsept
En **trait** er en navngitt evne som beriker en samlingsnode med spesifikk
funksjonalitet. Traits bestemmer hva en samling *kan gjøre* — hvilke
UI-komponenter som vises i frontend og hvilken backend-oppførsel maskinrommet
aktiverer.
Traits er mekanismen som gjør at én og samme node-/edge-arkitektur kan
fungere som nettmagasin, podcaststudio, diskusjonsklubb, wiki, eller en
kombinasjon av flere.
## Designprinsipper
1. **Komposisjon, ikke typer.** En samling er ikke "et magasin" — den har
traits som *gjør den til* et magasin. Legg til eller fjern traits når
som helst uten migrasjon.
2. **Traits i metadata, ikke edges.** Traits er egenskaper ved samlingen,
ikke relasjoner mellom entiteter. Edges er for relasjoner (innhold →
samling). Metadata er for konfigurasjon (hva samlingen kan gjøre).
3. **Lukket katalog, åpen konfigurasjon.** Trait-navn er et kjent sett vi
eier koden for. Konfigurasjonen innenfor hver trait er fleksibel JSONB.
4. **Uavhengige traits.** Hver trait fungerer alene. Verdien oppstår i
sammensetningen — og det er brukeren som setter sammen, ikke utvikleren.
5. **To effekter per trait.** Hver trait aktiverer:
- **Frontend:** UI-komponenter, visninger, interaksjoner
- **Backend:** Maskinrommet-oppførsel, validering, jobb-triggering
## Metadata-struktur
Traits lever i samlingsnodenes `metadata.traits`-objekt:
```jsonc
{
"node_kind": "collection",
"title": "Sidelinja Magasin",
"metadata": {
"traits": {
"publishing": {
"slug": "sidelinja",
"custom_domain": "magasin.sidelinja.org",
"theme": "editorial",
"open_graph_defaults": { "image": "cas://sha256-abc123" }
},
"editor": {
"preset": "longform",
"allow_collaborators": true
},
"rss": {
"format": "atom",
"title": "Sidelinja Magasin",
"max_items": 50
},
"comments": {
"moderation": "pre-approve",
"anonymous": false
}
}
}
}
```
Fravær av en trait betyr at funksjonaliteten er deaktivert. Ingen boolean
`enabled`-flagg — traiten finnes eller finnes ikke.
## Trait-katalog
### Innhold & redigering
| Trait | Frontend | Backend |
|---|---|---|
| `editor` | TipTap med presets (longform, note, chat, code) | Validering av dokumentstruktur |
| `versioning` | Revisjonshistorikk, diff, rollback-knapp | Snapshot ved signifikante endringer |
| `collaboration` | Samtidig redigering, markører, inline-kommentarer | OT/CRDT via WebSocket |
| `translation` | Språkvelger, side-ved-side-visning | AI-oversettelse via jobbkø |
| `templates` | Mal-velger ved ny node | Mal-noder i samlingen |
### Publisering & distribusjon
| Trait | Frontend | Backend |
|---|---|---|
| `publishing` | Publiseringsknapp, forhåndsvisning, URL-visning, SEO-editor | HTML-rendering til CAS, Caddy-ruting, OG-tags |
| `rss` | Feed-URL synlig i UI | Feed-generering ved publisering |
| `newsletter` | Abonnentliste, utsendingsknapp, forhåndsvisning | E-postutsending ved publisering |
| `custom_domain` | Domene-innstilling i admin | Caddy on-demand TLS, DNS-validering |
| `analytics` | Besøksstatistikk-dashbord | Logg-parsing, IAB-filtrering |
| `embed` | Kopier embed-kode-knapp | Generer iframe-snippet med riktige dimensjoner |
| `api` | API-dokumentasjon, nøkkelhåndtering | Offentlig JSON-endepunkt for samlingens innhold |
### Lyd & video
| Trait | Frontend | Backend |
|---|---|---|
| `podcast` | Episodeliste, lydavspiller, RSS-lenke | RSS med enclosures, metadata-håndtering |
| `recording` | LiveKit-studio, opptak-kontroller | LiveKit-rom, lydkonsolidering |
| `transcription` | Transkripsjonsvisning, redigerbar SRT | Whisper-pipeline via jobbkø |
| `tts` | "Les opp"-knapp, lydversjon av artikler | Tekst-til-tale via jobbkø |
| `clips` | Klipp-editor, segment-markering | Segmentering, CAS-lagring av klipp |
| `playlist` | Ordnet avspillingsliste, drag-and-drop rekkefølge | Sekvensiell avspilling |
| `mixer` | Lydmixer: volumslidere, mute, VU-meter, sound pads, stemme-/EQ-effekter | Pad-konfig i metadata (se `docs/features/lydmixer.md`) |
| `studio` | Lydstudio-panel: lydfilliste med metadata, drag-ut, drop-aksept for lyd, lenke til fullverdig editor | Validering av lydformat, FFmpeg-pipeline via jobbkø (se `docs/features/lydstudio.md`) |
### Kommunikasjon
| Trait | Frontend | Backend |
|---|---|---|
| `chat` | Sanntidsmeldinger, tråder, reaksjoner | WebSocket-synk, TTL-håndtering |
| `forum` | Trådet diskusjon, sortering (nyeste/populære/ubesvarte) | Tråd-indeksering |
| `comments` | Kommentarfelt under publisert innhold | Moderasjonskø, evt. anonym input |
| `guest_input` | Gjeste-lenke-generering, svar-oversikt | Token-generering, CAS-upload, rate limiting |
| `announcements` | Enveis-feed, kun eiere/admins poster | Skrivetilgangsvalidering |
| `polls` | Avstemnings-UI, resultatvisning | Stemmetelling, duplikatdeteksjon |
| `qa` | Spørsmål/svar-format, oppstemming, "godkjent svar" | Sortering, markering |
### Organisering
| Trait | Frontend | Backend |
|---|---|---|
| `kanban` | Board med kolonner, drag-and-drop | Statusoverganger, posisjonsberegning |
| `calendar` | Kalendervisning (måned/uke/dag) | Scheduling-edges, ICS-eksport |
| `timeline` | Kronologisk visning | Tidsbasert sortering og filtrering |
| `table` | Strukturert tabellvisning, filtrerbare kolonner | Metadata-indeksering |
| `gallery` | Rutenett av bilde-/medianoder | Thumbnail-generering |
| `bookmarks` | Kuratert lenkesamling med forhåndsvisning | URL-enrichment via maskinrommet |
| `tags` | Tagging, filtrering, tag-sky | Tag-indeksering |
### Kunnskap
| Trait | Frontend | Backend |
|---|---|---|
| `knowledge_graph` | Visuell graf, auto-tagging | NER, embedding-generering |
| `mindmap` | Radial/tree-layout av noder rundt rot, pan/zoom, dybde 1-3 hopp | Validering av konfig (dybde, layout) |
| `wiki` | Slug-baserte sider, kryssreferanser, "finnes ikke ennå"-lenker | Slug-unikhet, backlink-indeks |
| `glossary` | Begrepsliste, hover-definisjoner i annet innhold | Begrep-matching i tekst |
| `faq` | Spørsmål/svar-par med søk | Søkeindeksering |
| `bibliography` | Kildehenvisninger, siteringsformat, referanseliste | Sitats-parsing, DOI-oppslag |
### Automatisering & AI
| Trait | Frontend | Backend |
|---|---|---|
| `auto_tag` | Foreslåtte tags ved ny node, godkjenn/avvis | AI-tagging via jobbkø |
| `auto_summarize` | AI-sammendrag synlig, redigerbart | Sammendrag-generering ved publisering/møteslutt |
| `digest` | Periodisk oppsummering i UI | AI-sammendrag av aktivitet på intervall |
| `bridge` | "Også funnet i..."-forslag | pgvector-embedding, krysskontekst-søk |
| `moderation` | Moderasjonskø, flagging | AI-assistert innholdsvurdering |
| `ai_tool` | AI-verktøy-panel med prompt-velger, drag-and-drop tekstbehandling | Modellprofil-mapping, AI Gateway, ai_usage_log (se `docs/features/ai_verktoy.md`) |
### Tilgang & fellesskap
| Trait | Frontend | Backend |
|---|---|---|
| `membership` | Søknads-/innmeldingsknapp | Søknadskø, godkjenningsflyt |
| `roles` | Rolletildeling i admin | Egendefinerte roller utover owner/admin/member/reader |
| `invites` | Invitasjonslenker med kopiering | Token-generering, utløp, maks bruk |
| `paywall` | Betalingsflyt, tilgangskontroll | Stripe/Vipps-integrasjon |
| `directory` | Medlemsoversikt med profiler | Profilindeksering |
### Ekstern integrasjon
| Trait | Frontend | Backend |
|---|---|---|
| `webhook` | Webhook-konfigurasjon i admin | HTTP-varsling ved hendelser |
| `import` | Import-veiviser (WordPress, Markdown, RSS) | Parsing, node-opprettelse, mediaimport |
| `export` | Eksport-knapp (Markdown, EPUB, PDF) | Format-konvertering, CAS-pakking |
| `ical_sync` | Kalender-URL, synk-status | Toveis ICS-synk |
## Pakker
Pakker er forhåndsdefinerte kombinasjoner av traits med fornuftige defaults.
En pakke er *ikke* en type eller en låst konfigurasjon — den er et startpunkt.
Brukeren kan legge til eller fjerne traits etterpå.
| Pakke | Traits |
|---|---|
| **Nettmagasin** | editor(longform), publishing, rss, comments, analytics, custom_domain, newsletter |
| **Podcaststudio** | podcast, recording, transcription, mixer, editor(shownotes), rss, analytics, clips, knowledge_graph, mindmap |
| **Nyhetsbrev** | editor(longform), newsletter, analytics, versioning |
| **Wiki** | wiki, editor(longform), collaboration, versioning, knowledge_graph, mindmap, glossary |
| **Diskusjonsklubb** | forum, chat, polls, membership, roles, directory |
| **Kursplattform** | editor(longform), playlist, qa, membership, paywall, templates |
| **Møteplass** | recording, mixer, chat, kanban, calendar, auto_summarize, guest_input |
| **Fotoblogg** | gallery, publishing, comments, custom_domain, rss |
| **Prosjektstyring** | kanban, calendar, chat, table, tags, roles |
| **Åpen forskning** | editor(longform), versioning, bibliography, publishing, comments, collaboration, api |
| **Community radio** | recording, mixer, podcast, chat, polls, membership, clips, playlist |
| **Bokmerke-vegg** | bookmarks, tags, publishing, rss, comments |
| **Redaksjon** | chat, kanban, calendar, editor(longform), knowledge_graph, guest_input |
## Implementeringsstrategi
Traits implementeres én og én, ikke alle samtidig. Prioritering følger
brukerbehovene til Sidelinja som første tenant. En trait krever:
1. **Spesifikasjon** — hva traiten gjør, metadata-skjema, UI-mockup
2. **Backend** — maskinrommet-kode som reagerer på traitens tilstedeværelse
3. **Frontend** — Svelte-komponent(er) som rendres når traiten er aktiv
4. **Dokumentasjon** — oppdater denne filen og evt. `docs/features/`
Rekkefølge for første bolk (Sidelinja-behov):
`editor``chat``publishing``rss``podcast``recording`
`transcription``knowledge_graph``kanban``calendar`