# 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`:

```json
{
  "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'`:

```json
{
  "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
**Lav–Middels** — 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?
