docs: add YouTube thumbnail download design document

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-14 11:51:13 +00:00
parent 2d4f43e780
commit 5aef72f72b

View file

@ -0,0 +1,96 @@
# YouTube Thumbnail Download — Design
**Datum:** 14.02.2026
**Status:** Approved
## Ziel
Automatischer Download von YouTube-Video-Thumbnails und Kanalbildern als Payload Media, damit diese offline verfügbar sind und von Payload's Sharp-Pipeline optimiert werden.
## Scope
- **Video-Thumbnails:** Auto-Download bei Sync + Bulk-Import für bestehende Einträge
- **Kanalbilder:** Profilbilder und Banner beim Channel-Sync
- **Nicht im Scope:** Kommentar-Autor-Avatare (bleiben als externe URLs)
## Qualität
- YouTube-Thumbnails: `hqdefault` (480x360)
- Payload generiert daraus automatisch alle responsive Sizes (thumbnail, small, medium, etc.)
## Architektur: Inline beim Sync
Download direkt im Sync-Flow integriert, kein separater Queue-Job.
### 1. Kern-Utility: `downloadAndUploadImage()`
**Datei:** `src/lib/utils/media-download.ts`
```typescript
interface DownloadOptions {
url: string
filename: string
alt?: string
tenantId?: number
}
async function downloadAndUploadImage(
payload: Payload,
options: DownloadOptions
): Promise<number | null>
```
- Lädt Bild von URL herunter
- Erstellt Payload Media-Dokument (mit Tenant-Zuordnung)
- Sharp-Pipeline generiert alle 11 responsive Sizes automatisch
- Duplikat-Erkennung: Prüft ob Media mit gleichem Dateinamen + Tenant existiert
- Fehler → `null` (kein harter Fehler, Sync läuft weiter)
### 2. Integration in YouTube-Sync
**YouTubeContent** (beim Erstellen/Updaten):
- Wenn `thumbnail`-Feld leer → Download von `https://img.youtube.com/vi/{videoId}/hqdefault.jpg`
- Media-ID in `thumbnail`-Feld speichern
- Manuell hochgeladene Thumbnails werden nie überschrieben
**YouTubeChannels** (beim Channel-Sync):
- Profilbild und Banner aus YouTube API herunterladen (falls Felder leer)
- In entsprechende Media-Felder speichern
### 3. Bulk-Import Endpoint
**Route:** `POST /api/youtube/thumbnails/bulk`
**Auth:** Super-Admin erforderlich
- Findet alle `YouTubeContent`-Einträge ohne Thumbnail
- Downloadet sequentiell mit 500ms Delay (Rate-Limit-Schutz)
- Response: `{ processed, downloaded, skipped, errors }`
- Optional: `?dryRun=true`
### 4. Fehlerbehandlung
| Aspekt | Verhalten |
|--------|-----------|
| Rate-Limiting | 500ms Delay zwischen Downloads (Bulk) |
| Timeout | 10s pro Download |
| Retry | Kein Retry (YouTube CDN zuverlässig) |
| 404/Fehler | `null` zurückgeben, Sync fortsetzen |
| Duplikate | Existierendes Media zurückgeben |
| Manuelle Uploads | Nie überschreiben |
| Logging | Console.log (nicht AuditLogs) |
## Betroffene Dateien
### Neu
- `src/lib/utils/media-download.ts` — Kern-Utility
- `src/app/(payload)/api/youtube/thumbnails/bulk/route.ts` — Bulk-Endpoint
### Modifiziert
- YouTube-Sync-Services — Thumbnail-Download nach Content-Erstellung
- YouTubeChannels-Sync — Kanalbild-Download nach Channel-Update
## Nicht-Ziele
- Keine Kommentar-Avatare herunterladen
- Kein Queue-basierter Download
- Keine automatische Aktualisierung bestehender Thumbnails