synops/docs/proposals/social_posting.md
vegard 0a467066ba Synops v2: arkitektur, retninger og dokumentasjon
Nystart basert på arkitektonisk innsikt fra Sidelinja v1.
Koden er ny, visjon og primitiver er validert gjennom tidligere arbeid.

Inneholder:
- Komplett arkitekturdokumentasjon (docs/arkitektur.md)
- 6 vedtatte retninger (docs/retninger/)
- Alle concepts, features, proposals og erfaringer fra v1
- Server-oppsett og drift (docs/setup/)
- LiteLLM-konfigurasjon (API-nøkler via env)
- Editor.svelte referanse fra v1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 06:43:08 +01:00

6.4 KiB
Raw Blame History

Forslag: Sosial publisering fra chat

Idé

Post til X (og senere Bluesky/Mastodon) direkte fra Redaksjonens chat. Noen sier noe morsomt eller skarpt — én kommando, og det er ute i verden. Flere teammedlemmer deler én konto uten å dele passord.

Hvorfor er det interessant?

  • Senker terskelen. En podcast-konto på X dør ofte fordi kun én person har tilgang og gidder. Med chat-integrasjon kan hvem som helst foreslå en post, og flyten er én handling — ikke "åpne X, logg inn på riktig konto, skriv, post".
  • Spontanitet. De beste sosiale medie-postene er de som kommer i øyeblikket. Å fange dem rett fra chatten der samtalen skjer bevarer energien.
  • Kontroll uten friksjon. Konfigurerbar godkjenningsflyt per workspace — fra "alle poster fritt" til "admin godkjenner alt".
  • Bygger på det som finnes. Chat, jobbkø, workspace-settings — ingen ny infrastruktur.

Hva bygger den på?

  • Chat/x-kommando som trigger publisering
  • Jobbkøsocial_post-jobbtype med retry ved rate limit
  • Workspace settings — API-nøkler og godkjenningsflyt per workspace
  • Admin-panel — Workspace-innstillinger for plattformer og tilgangsstyring

Flyt

Uten godkjenning (workspace-innstilling: approval: none)

Vegard i chat: "Fantastisk intervju med @støre i dag, han innrømmet at han liker brunost på vaffel"
Marte svarer:  /x
              ┌──────────────────────────────────────┐
              │ Post til X:                          │
              │                                      │
              │ Fantastisk intervju med @støre i     │
              │ dag, han innrømmet at han liker      │
              │ brunost på vaffel 🧇                 │
              │                                      │
              │ 156/280 tegn                         │
              │                                      │
              │ [Rediger]  [Avbryt]  [Post nå]       │
              └──────────────────────────────────────┘
→ Jobb opprettes → Rust-worker poster til X
→ Systemmelding i chat: "Marte postet til X: https://x.com/sidelinja/status/..."

Med godkjenning (workspace-innstilling: approval: required)

Marte:  /x
→ Jobb opprettes med status 'pending_approval'
→ Systemmelding: "Marte foreslår X-post: «...» — reager med ✅ for å godkjenne"
→ Admin reagerer med ✅
→ Jobb endres til 'pending', worker poster
→ Systemmelding oppdateres: "Postet av Marte, godkjent av Lars: https://x.com/..."

Med godkjenning fra hvem som helst med riktig rolle (workspace-innstilling: approval: role)

Samme flyt, men approval_role i settings styrer hvem som kan godkjenne (default: admin+owner).

Workspace-innstillinger

Lagres i workspaces.settings under nøkkelen social:

{
  "social": {
    "platforms": {
      "x": {
        "enabled": true,
        "api_key": "...",
        "api_secret": "...",
        "access_token": "...",
        "access_token_secret": "..."
      }
    },
    "approval": "none",
    "approval_role": "admin",
    "default_hashtags": ["#sidelinja"],
    "max_daily_posts": 20
  }
}

approval-verdier:

Verdi Oppførsel
none Alle workspace-medlemmer kan poste direkte
required Alle poster krever godkjenning
role Poster fra brukere med lavere rolle enn approval_role krever godkjenning

Datamodell

Ingen ny tabell — bruker jobbkøen med job_type = 'social_post':

{
  "job_type": "social_post",
  "payload": {
    "platform": "x",
    "text": "Fantastisk intervju med @støre...",
    "source_message_id": "uuid",
    "suggested_by": "authentik_id",
    "approved_by": null,
    "thread_ids": []
  }
}

For godkjenningsflyt brukes en ekstra jobbstatus. Jobber med approval: required opprettes med status = 'pending_approval' (ny enum-verdi) og endres til pending ved godkjenning.

Admin-panel (workspace-innstillinger)

Denne featuren forutsetter et minimalt admin-panel i SvelteKit (/workspace/settings). Første iterasjon trenger kun:

  • Sosiale kontoer: Koble til X (OAuth-flyt), se tilkoblet konto, fjern
  • Godkjenningsflyt: Velg mellom none / required / role
  • Historikk: Liste over poster sendt fra dette workspacet (fra jobbkø-data)

Admin-panelet vil vokse med andre workspace-innstillinger over tid (Whisper-config, AI-prompts, channel-defaults, etc.), men sosial publisering er et godt første bruksområde.

Plattform-abstraksjon

Chat-kommandoen og jobbkøen vet ikke om X spesifikt. Arkitekturen er:

Chat (/x, /bsky, /social)
    │
    ▼
Jobbkø: social_post { platform: "x", text: "..." }
    │
    ▼
Rust worker: matcher platform → riktig API-klient
    ├── X (OAuth 1.0a, v2 API)
    ├── Bluesky (AT Protocol) [fremtidig]
    └── Mastodon (OAuth 2.0, REST) [fremtidig]

Å legge til en ny plattform er å implementere én ny handler i Rust-workeren + legge til credentials i workspace-settings. Ingen endring i chat-koden.

X API: Tekniske detaljer

  • API: X API v2, POST /2/tweets
  • Auth: OAuth 1.0a (User Context) — krever app + bruker-tokens
  • Rate limit: 200 poster/15 min per bruker (mer enn nok)
  • Tråd-støtte: reply.in_reply_to_tweet_id for tråder
  • Pris: Free tier tillater 1500 poster/mnd. Basic ($100/mnd) gir 3000 poster + lesing. Free er nok for start.

Innsats

LavMiddels — X API-integrasjonen er enkel. Chat-kommandoen er en ny handler. Det meste av arbeidet er UI for preview/redigering-popupen og admin-panelet for innstillinger.

Wow-faktor

Høy — Gjør podcast-kontoen levende uten at noen må "huske å poste". Demokratiserer kontoen uten å dele passord.

Åpne spørsmål

  • Skal /x kunne brukes på en hel tråd (flere meldinger → X-tråd)?
  • Bilder/media i poster — fra chat-vedlegg eller kun tekst i v1?
  • Skal poster inkludere en automatisk lenke tilbake til episoden/temaet fra grafen?
  • Bør det finnes en /draft-kommando som legger posten i en kø uten å sende (planlagt posting)?
  • Varsling i chat når en foreslått post venter på godkjenning for lenge?