- Omorganiser docs/: konsepter, features, infra og proposals i egne mapper - Ny docs/erfaringer/ med lærdommer fra chat-implementering (Svelte 5, SpacetimeDB, adapter-mønster) - Oppdater ARCHITECTURE.md: Lag 1 status, ny §10 Erfaringslogg, SpacetimeDB i lokal dev - Oppdater synkronisering.md med implementeringsstatus og designvalg - Oppdater lokal.md med SpacetimeDB og AI Gateway - Utvid PG-skjema med channels, messages, media_files, message_revisions - Legg til seed_dev.sql, migration_safety.md, .env.example - Nye feature-specs: chat, kanban, whiteboard, live_ai, lydmeldinger m.fl. - Nye konsept-specs: studioet, møterommet, redaksjonen, den asynkrone gjesten m.fl. - SpacetimeDB og AI Gateway i docker-compose.dev.yml - collect-docs.sh inkluderer erfaringer/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
150 lines
6.4 KiB
Markdown
150 lines
6.4 KiB
Markdown
# 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?
|