server/docs/features/podcastfabrikken.md

3.5 KiB

Feature Spec: Podcastfabrikken (Lyd & Publiserings-Pipeline)

Filsti: docs/features/podcastfabrikken.md

1. Konsept

Den automatiserte "samlebåndet" som tar over når en ferdigklippet episode er klar, samt verktøyet for å oppdatere eksisterende episoder (f.eks. en rullerende intro-episode). Målet er at maskinen gjør 90 % av grovarbeidet (transkripsjon, metadata, kapittelinndeling), men at redaksjonen alltid kan overstyre resultatet manuelt før publisering.

2. Arkitektur & Dataflyt

Dette er en asynkron arbeidsflyt som kombinerer filsystem, AI, databaser og CI/CD.

  1. Trigger (Opplasting/Oppdatering): Brukeren laster opp en .mp3-fil via SvelteKit-grensesnittet. Dette rutes enten som en ny episode (INSERT), eller en oppdatering av en eksisterende (UPDATE).
  2. Kø-system (PostgreSQL jobbkø): Siden lydprosessering tar tid (CPU-intensivt), legges oppgaven i den felles jobbkøen (se docs/features/jobbkø.md). Opplastingen oppretter to jobber i sekvens: først whisper_transcribe, deretter openrouter_analyze (som trigges automatisk ved fullført transkripsjon).
  3. Transkripsjon (faster-whisper): Rust-worker trigger faster-whisper lokalt på serveren og genererer rå tekst med tidsstempler.
  4. AI-Analyse (OpenRouter): Transkripsjonen sendes til OpenRouter (Claude-modell) for uttrekk av forslag til tittel, sammendrag, show notes og kapittler.
  5. Manuell Godkjenning & Fletting (SvelteKit):
    • For nye episoder: Presenteres som et ferskt utkast.
    • For oppdateringer: Viser AI-ens nye forslag side-om-side med eksisterende metadata. Redaksjonen kan da velge hva som skal beholdes eller flettes (merge).
  6. Publisering (PostgreSQL): Ved "Godkjenn" lagres metadataene permanent i databasen.
  7. RSS-Generering: SvelteKit-appen genererer en oppdatert /feed.xml.

3. Spesialhåndtering: Oppdatering av eksisterende episoder (Cache-busting)

Podcast-apper (Apple, Spotify) og CDN-er cacher innhold aggressivt. For at en endring i f.eks. "Introepisoden" skal slå gjennom hos lytterne, MÅ følgende tekniske regler følges:

  • Filnavn-versjonering (Viktigst!): Den nye lydfilen skal aldri overskrive det gamle filnavnet på disken. Systemet må legge til en hash, UUID eller et tidsstempel (f.eks. intro_v2_1710289000.mp3). Dette tvinger appene til å laste ned filen på nytt.
  • RSS <guid> (Global Unique Identifier): Denne taggen MÅ forbli 100% statisk/uendret fra originalepisoden. Den forteller appene at "Dette er fortsatt samme episode, ikke lag en duplikat".
  • RSS <enclosure>: URL-en i enclosure-taggen (som peker på .mp3-filen) oppdateres i databasen til å reflektere det nye filnavnet.
  • RSS <pubDate>: SvelteKit-grensesnittet skal gi redaksjonen en toggle-knapp ved oppdatering:
    • Alternativ A: "Behold opprinnelig dato" (Episoden oppdateres i det stille for nye lyttere).
    • Alternativ B: "Sett dato til NÅ" (Episoden spretter til toppen av feeden som en ny utgivelse).

4. Instruks for Claude Code

  • Lydfiler: Håndter filopplasting i SvelteKit strømmende (streaming) for filer >100MB for å unngå minne-lekkasjer.
  • Feilhåndtering: Hvis OpenRouter timer ut eller Whisper feiler, må oppgaven flagges med status error i databasen slik at brukeren kan trigge jobben på nytt manuelt via UI.
  • Opprydding (Disk): Når en fil oppdateres vellykket, skal den gamle/foreldede .mp3-filen enten slettes fra Hetzner-serveren automatisk, eller flyttes til en /archive/-mappe basert på en miljøvariabel.