# YouTube Operations Hub - Erweiterungen Design **Datum:** 2026-02-14 **Status:** Genehmigt **Geschätzter Aufwand:** ~80 Stunden (4 Phasen) ## Zusammenfassung Implementierung der 4 Erweiterungsmöglichkeiten aus dem YouTube Operations Hub (Abschnitt 11): 1. **YouTube API Integration** - Metriken-Sync, Video-Upload, Kommentar-Import 2. **Analytics Dashboard** - Performance-Vergleich, Trend-Analyse, ROI 3. **Workflow-Automatisierung** - Status-Änderungen, Deadline-Erinnerungen, Kapazitätsplanung 4. **Content-Kalender** - Visuelle Übersicht, Drag & Drop, Konflikt-Erkennung ## Bestandsanalyse ### Vorhandene Infrastruktur - **YouTubeClient** (`src/lib/integrations/youtube/YouTubeClient.ts`) - nur Comment-Methoden - **OAuth 2.0** - funktioniert, Scopes: `youtube.readonly`, `youtube.force-ssl`, `youtube` - **YouTubeContent Collection** - `performance.*` Felder existieren (nie befüllt) - **YouTubeChannels Collection** - `currentMetrics.*` Felder (nur bei OAuth-Connect aktualisiert) - **BullMQ** - Email/PDF-Worker laufen, Queue-Infrastruktur vorhanden - **Recharts 3.6.0** - bereits installiert - **YouTubeAnalyticsDashboard** - existiert mit 4 Tabs (Daten nur aus CMS) - **CommentsSyncService** - importiert nur Top-Level-Kommentare ### Fehlende Komponenten - `youtube.videos.list()` API-Aufrufe (Metriken) - `youtube.videos.insert()` API-Aufrufe (Upload) - `youtubeAnalytics` API v2 (detaillierte Analytics) - OAuth-Scopes: `youtube.upload`, `yt-analytics.readonly` - Reply-Thread-Import bei Kommentaren - Deadline-Scheduler/Cron - Kalender-Bibliothek (FullCalendar) --- ## Phase 1: YouTube API Integration (~30h) ### 1.1 Metriken-Sync Service **Neue Datei:** `src/lib/integrations/youtube/VideoMetricsSyncService.ts` ``` YouTubeClient.getVideoStatistics(videoIds[]) → youtube.videos.list({ part: 'statistics,snippet', id: videoIds }) → Batch-Update: YouTubeContent.performance.* Felder ``` **Sync-Strategie:** - Batch-Verarbeitung: Max 50 Video-IDs pro API-Call (YouTube-Limit) - Inkrementeller Sync: Nur Videos mit Status `published` oder `tracked` - Frequenz: Alle 6 Stunden via Cron (`/api/cron/youtube-metrics-sync`) - Quota-Budget: ~300 Einheiten/Tag (bei 150 Videos = 3 Calls x 100 Quota) **Befüllte Felder in YouTubeContent:** | Feld | API-Quelle | Typ | |------|-----------|-----| | `performance.views` | `statistics.viewCount` | number | | `performance.likes` | `statistics.likeCount` | number | | `performance.comments` | `statistics.commentCount` | number | | `performance.estimatedMinutesWatched` | Analytics API | number | | `performance.averageViewDuration` | Analytics API | number | | `performance.ctr` | Analytics API | number | | `performance.impressions` | Analytics API | number | | `performance.subscribersGained` | Analytics API | number | **Neue Datei:** `src/lib/integrations/youtube/ChannelMetricsSyncService.ts` ``` YouTubeClient.getChannelStatistics(channelId) → youtube.channels.list({ part: 'statistics', id: channelId }) → Update: YouTubeChannels.currentMetrics.* Felder ``` ### 1.2 Erweiterter Kommentar-Import **Änderung:** `src/lib/integrations/youtube/CommentsSyncService.ts` Erweiterungen: - Reply-Threads importieren (youtube.comments.list für parentId) - `parentComment` Relationship-Feld in CommunityInteractions nutzen - Thread-Tiefe: Max 2 Ebenen (YouTube-Limit) - Neue Kommentare seit letztem Sync (publishedAfter-Filter) ### 1.3 Video-Upload Service **Neue Datei:** `src/lib/integrations/youtube/VideoUploadService.ts` **Upload-Flow:** ``` Admin UI "Veröffentlichen" Button → API Route POST /api/youtube/upload → BullMQ Job in youtube-upload Queue → VideoUploadWorker: 1. Media-Datei aus Payload laden 2. youtube.videos.insert() mit Resumable Upload 3. YouTubeContent Status → 'published' 4. YouTube-Video-ID speichern 5. Notification erstellen ``` **Neue Dateien:** - `src/lib/queue/jobs/youtube-upload-job.ts` - `src/lib/queue/workers/youtube-upload-worker.ts` - `src/app/(payload)/api/youtube/upload/route.ts` **OAuth-Scope hinzufügen:** - `src/lib/integrations/youtube/oauth.ts`: Scope `https://www.googleapis.com/auth/youtube.upload` **Upload-Metadaten (aus YouTubeContent-Feldern):** - `youtube.metadata.title` → Video-Titel - `youtube.metadata.description` → Beschreibung - `youtube.metadata.tags` → Tags - `youtube.metadata.categoryId` → Kategorie - `youtube.metadata.visibility` → public/unlisted/private - `youtube.metadata.language` → Sprache - `scheduledPublishDate` → Geplante Veröffentlichung **Quota-Tracking:** - Neue Collection oder Felder in YouTubeChannels: `quotaUsedToday`, `quotaResetAt` - Video-Upload: ~1.600 Quota-Einheiten pro Upload - Tägliches Limit: 10.000 Einheiten (Standard) - Warnung bei >80% Auslastung via NotificationService ### 1.4 Cron-Jobs | Endpoint | Schedule | Beschreibung | |----------|----------|--------------| | `/api/cron/youtube-metrics-sync` | `0 */6 * * *` | Video-Metriken alle 6h | | `/api/cron/youtube-channel-sync` | `0 4 * * *` | Kanal-Statistiken täglich | **Änderung:** `vercel.json` - Neue Cron-Einträge --- ## Phase 2: Analytics Dashboard (~16h) ### 2.1 YouTube Analytics API Client **Neue Datei:** `src/lib/integrations/youtube/YouTubeAnalyticsClient.ts` ```typescript // Methoden: getVideoAnalytics(videoId, startDate, endDate, metrics[]) getChannelAnalytics(channelId, startDate, endDate, metrics[]) getTopVideos(channelId, metric, limit) getDemographics(channelId, startDate, endDate) ``` **OAuth-Scope hinzufügen:** - `yt-analytics.readonly` in `src/lib/integrations/youtube/oauth.ts` ### 2.2 Performance-Vergleich Tab **Erweiterung:** `src/components/admin/YouTubeAnalyticsDashboard.tsx` Neuer Tab "Vergleich" mit: - Multi-Select für Videos (max 5) - Metriken-Auswahl: Views, Likes, CTR, Watch Time - Zeitreihen-Chart (Recharts LineChart mit mehreren Serien) - Normalisierte Ansicht (prozentual) für unterschiedliche Größenordnungen - Tabelle mit Delta-Werten ### 2.3 Trend-Analyse Tab Neuer Tab "Trends" mit: - Automatische Trend-Erkennung (gleitender Durchschnitt, 7/30 Tage) - Wachstumsrate pro Metrik (WoW, MoM) - Prognose-Linie (lineare Regression, nächste 30 Tage) - Saisonalitäts-Erkennung (Wochentag-Heatmap) - Best/Worst Performer Ranking **Berechnung im Backend:** `src/app/(payload)/api/youtube/analytics/route.ts` - Neuer Query-Parameter: `tab=trends` - Berechnungen serverseitig für Performance ### 2.4 ROI-Berechnung Tab Neuer Tab "ROI" mit: - Neue Felder in YouTubeContent: - `costs.estimatedProductionHours` (number) - `costs.estimatedProductionCost` (number, EUR) - `costs.estimatedRevenue` (number, EUR - manuell oder via Analytics API) - ROI-Formel: `(Revenue - Cost) / Cost * 100` - CPV (Cost per View): `Cost / Views` - Revenue per View: `Revenue / Views` - Break-Even-Analyse - Chart: Kosten vs. Einnahmen über Zeit **Keine separate Collection** - pragmatischer Ansatz mit Feldern direkt in YouTubeContent. ### 2.5 API-Erweiterungen **Änderung:** `src/app/(payload)/api/youtube/analytics/route.ts` Neue Query-Parameter: - `tab=comparison&videoIds=id1,id2,id3` - `tab=trends&metric=views&period=30d` - `tab=roi&channelId=X` --- ## Phase 3: Workflow-Automatisierung (~14h) ### 3.1 Automatische Status-Übergänge **Neue Datei:** `src/hooks/youtubeContent/autoStatusTransitions.ts` Regeln (konfigurierbar): | Bedingung | Aktion | |-----------|--------| | Alle Checklisten-Items erledigt | Status → nächste Phase | | Video auf YouTube veröffentlicht | Status → `published` | | 7 Tage nach Veröffentlichung | Status → `tracked` | | Upload-Job abgeschlossen | Status → `published` | **Hook-Typ:** `afterChange` auf YouTubeContent - Prüft Checklisten-Completion via YtTasks - Erstellt Notification bei automatischem Übergang - Audit-Log-Eintrag ### 3.2 Deadline-Erinnerungen **Neue Datei:** `src/app/(payload)/api/cron/deadline-reminders/route.ts` **Schedule:** `0 9 * * 1-5` (Mo-Fr 9:00 UTC) **Prüfungen:** 1. `editDeadline` in 2 Tagen → Erinnerung 2. `editDeadline` überschritten → Warnung (Priorität: high) 3. `reviewDeadline` in 1 Tag → Erinnerung 4. `scheduledPublishDate` in 3 Tagen → Erinnerung 5. Batch-Deadline (`YtBatches.targetCompletionDate`) in 3 Tagen → Erinnerung **Notification-Typen:** Nutzt bestehendes `NotificationService` + `YtNotifications`: - `task_due` - Deadline naht - `task_overdue` - Deadline überschritten - Neuer Typ: `deadline_warning` (3 Tage vorher) **Zustellung:** - YtNotifications Collection (Admin-Inbox) - Optional: E-Mail via AlertService (konfigurierbar pro User) ### 3.3 Team-Kapazitätsplanung **Neue Datei:** `src/app/(payload)/api/youtube/capacity/route.ts` **Datenquellen:** - YtTasks (zugewiesene Aufgaben pro User) - YouTubeContent (Videos in Produktion pro Assignee) - YtBatches (geplante Batches) **Berechnung:** ``` Pro Team-Mitglied: - Aktive Tasks (status: in_progress, pending) - Geschätzte Stunden (aus Tasks estimatedHours) - Videos in Pipeline (zugewiesen, nicht abgeschlossen) - Auslastung = aktive Stunden / verfügbare Stunden (40h/Woche default) ``` **UI-Komponente:** Integration in YouTubeAnalyticsDashboard - Neuer Tab "Team" oder Widget im bestehenden "Pipeline" Tab - Balkendiagramm: Auslastung pro Person - Farbcodierung: Grün (<70%), Gelb (70-90%), Rot (>90%) - Warnung bei Überbelastung via NotificationService --- ## Phase 4: Content-Kalender (~20h) ### 4.1 Bibliothek & Setup **Neue Dependency:** `@fullcalendar/react` + Plugins - `@fullcalendar/core` - `@fullcalendar/daygrid` - `@fullcalendar/timegrid` - `@fullcalendar/interaction` (Drag & Drop) - `@fullcalendar/list` ### 4.2 Kalender API **Neue Datei:** `src/app/(payload)/api/youtube/calendar/route.ts` **GET** - Events abrufen: ``` ?channelId=X&start=2026-01-01&end=2026-02-28 ``` **Response-Format:** ```typescript { events: [{ id: string, // YouTubeContent ID title: string, // Video-Titel start: string, // scheduledPublishDate (ISO) end: string, // scheduledPublishDate + 1h color: string, // Channel branding.primaryColor extendedProps: { status: string, contentType: 'video' | 'short', channelName: string, seriesName?: string, hasConflict: boolean, } }] } ``` **PATCH** - Datum per Drag & Drop ändern: ``` { contentId: string, newDate: string } ``` - Validierung: Nur Videos mit Status vor `published` - Konflik-Prüfung vor Speicherung - Audit-Log-Eintrag ### 4.3 Content-Kalender Komponente **Neue Datei:** `src/components/admin/ContentCalendar.tsx` Features: - Monats-, Wochen-, Tages-, Listen-Ansicht - Farbcodierung nach Kanal (`branding.primaryColor`) - Status-Icons auf Events (Draft, Review, Ready, Published) - Tooltip mit Video-Details bei Hover - Click → Navigation zum YouTubeContent-Dokument **Neue Datei:** `src/components/admin/ContentCalendar.module.scss` - BEM-Konventionen - Payload CSS-Variablen für Dark/Light Mode - Responsive Layout ### 4.4 Drag & Drop FullCalendar's eingebautes `interaction` Plugin: - Event-Verschiebung → PATCH API-Call - Bestätigungsdialog vor Speicherung - Undo-Möglichkeit (vorheriges Datum merken) - Nur für Videos vor Status `published` ### 4.5 Konflikt-Erkennung **Neue Datei:** `src/lib/youtube/ConflictDetectionService.ts` **Regeln:** 1. **Zeitkonflikt:** Zwei Videos am selben Tag auf demselben Kanal 2. **Serien-Konflikt:** Serien-Folge vor vorheriger Folge geplant 3. **Frequenz-Konflikt:** Mehr Videos als `publishingSchedule.longformPerWeek` / `shortsPerWeek` 4. **Wochenend-Warnung:** Video am Wochenende geplant (konfigurierbar) **Anzeige:** - Rote Markierung auf Kalender-Events mit Konflikten - Warnung-Banner im Kalender - Konflikte als Tooltip auf betroffenen Events - API-Response enthält `hasConflict: boolean` pro Event ### 4.6 Admin View Registrierung **Änderung:** `src/payload.config.ts` Neuer Custom View: `/admin/content-calendar` - Registrierung analog zu `YouTubeAnalyticsDashboard` - Navigation-Link via `afterNavLinks` --- ## Technische Querschnittsthemen ### OAuth-Scope-Erweiterungen **Datei:** `src/lib/integrations/youtube/oauth.ts` Neue Scopes: ```typescript const SCOPES = [ 'https://www.googleapis.com/auth/youtube.readonly', 'https://www.googleapis.com/auth/youtube.force-ssl', 'https://www.googleapis.com/auth/youtube', 'https://www.googleapis.com/auth/youtube.upload', // NEU 'https://www.googleapis.com/auth/yt-analytics.readonly', // NEU ] ``` **Hinweis:** Bestehende OAuth-Tokens müssen nach Scope-Änderung neu autorisiert werden. Re-Auth-Flow in Admin UI einbauen. ### Quota-Management YouTube Data API v3 Quota: 10.000 Einheiten/Tag (Standard) | Operation | Kosten | Häufigkeit | Tägliche Kosten | |-----------|--------|------------|-----------------| | videos.list (50 IDs) | 100 | 4x/Tag | 400 | | channels.list | 100 | 1x/Tag | 100 | | commentThreads.list | 100 | 4x/Tag | 400 | | comments.list (Replies) | 100 | 4x/Tag | 400 | | videos.insert (Upload) | 1.600 | ~2/Tag | 3.200 | | **Gesamt** | | | **~4.500** | Budget: ~45% des Tageslimits. Spielraum für manuelle API-Calls. ### Migration Neue Felder in YouTubeContent (Phase 2 ROI): ```sql ALTER TABLE youtube_content ADD COLUMN IF NOT EXISTS "costs_estimated_production_hours" numeric, ADD COLUMN IF NOT EXISTS "costs_estimated_production_cost" numeric, ADD COLUMN IF NOT EXISTS "costs_estimated_revenue" numeric; ``` ### Error Handling Alle neuen Services folgen bestehendem Pattern: - Try/Catch mit strukturiertem Logging (SafeLogger) - YouTube API-Fehler: Retry mit exponential Backoff (max 3) - Quota-Exceeded (403): Job delayed auf nächsten Tag - Token-Expired (401): Auto-Refresh via TokenRefreshService - Upload-Fehler: Resumable Upload mit Checkpoint --- ## Abhängigkeiten zwischen Phasen ``` Phase 1 (API) ──────────► Phase 2 (Analytics) │ │ │ Metriken-Daten │ Dashboard-Patterns │ verfügbar │ ▼ ▼ Phase 3 (Workflow) ──────► Phase 4 (Kalender) │ │ │ Status-Logik │ Scheduling-Daten │ Deadline-System │ Konflikt-Erkennung └──────────────────────────┘ ``` Phase 1 muss zuerst abgeschlossen werden (Datengrundlage für Analytics). Phasen 3 und 4 können teilweise parallel entwickelt werden. --- ## Neue Dateien (Übersicht) ### Phase 1 - `src/lib/integrations/youtube/VideoMetricsSyncService.ts` - `src/lib/integrations/youtube/ChannelMetricsSyncService.ts` - `src/lib/integrations/youtube/VideoUploadService.ts` - `src/lib/queue/jobs/youtube-upload-job.ts` - `src/lib/queue/workers/youtube-upload-worker.ts` - `src/app/(payload)/api/youtube/upload/route.ts` - `src/app/(payload)/api/cron/youtube-metrics-sync/route.ts` - `src/app/(payload)/api/cron/youtube-channel-sync/route.ts` ### Phase 2 - `src/lib/integrations/youtube/YouTubeAnalyticsClient.ts` ### Phase 3 - `src/hooks/youtubeContent/autoStatusTransitions.ts` - `src/app/(payload)/api/cron/deadline-reminders/route.ts` - `src/app/(payload)/api/youtube/capacity/route.ts` ### Phase 4 - `src/components/admin/ContentCalendar.tsx` - `src/components/admin/ContentCalendar.module.scss` - `src/lib/youtube/ConflictDetectionService.ts` - `src/app/(payload)/api/youtube/calendar/route.ts` ### Geänderte Dateien - `src/lib/integrations/youtube/YouTubeClient.ts` (neue Methoden) - `src/lib/integrations/youtube/oauth.ts` (neue Scopes) - `src/lib/integrations/youtube/CommentsSyncService.ts` (Reply-Threads) - `src/collections/YouTubeContent.ts` (ROI-Felder) - `src/app/(payload)/api/youtube/analytics/route.ts` (neue Tabs) - `src/components/admin/YouTubeAnalyticsDashboard.tsx` (neue Tabs) - `src/lib/queue/queue-service.ts` (youtube-upload Queue) - `src/payload.config.ts` (Content Calendar View) - `vercel.json` (neue Cron-Jobs) - `package.json` (FullCalendar Dependencies)