cms.c2sgmbh/docs/anleitungen/FRONTEND.md
Martin Porwoll d7dfa2e2ea docs: add Community Management APIs to FRONTEND.md and API_ANLEITUNG.md
Add documentation for YouTube/Meta integration:
- YouTube Channels, Content, Series, Notifications APIs
- Social Platforms, Accounts, Community Interactions APIs
- Code examples for frontend integration
- Field documentation with curl examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 17:23:10 +00:00

13 KiB

Frontend-Entwicklung - Payload CMS Multi-Tenant

Server: sv-frontend (LXC 704) - 10.10.181.104 Backend API: https://cms.c2sgmbh.de/api (Production)

Übersicht

Das Frontend wird als separates Next.js-Projekt entwickelt und nutzt Payload CMS als Headless CMS über die REST-API.

Wichtig: Die Frontend-Entwicklung verwendet die Produktions-API und -Datenbank, um mit echten Inhalten zu arbeiten. SEO-Einstellungen und Cookie-Consent-Konfigurationen werden ebenfalls aus der Produktionsumgebung geladen.


Umgebungskonfiguration

Environment Variables (.env.local)

# API-Endpunkte (PRODUKTION)
NEXT_PUBLIC_PAYLOAD_URL=https://cms.c2sgmbh.de
NEXT_PUBLIC_API_URL=https://cms.c2sgmbh.de/api

# Analytics (optional)
NEXT_PUBLIC_UMAMI_HOST=https://analytics.c2sgmbh.de
NEXT_PUBLIC_UMAMI_WEBSITE_ID=<website-id>

# Tenant-Konfiguration (je nach Projekt)
NEXT_PUBLIC_TENANT_ID=4
NEXT_PUBLIC_TENANT_SLUG=c2s

Warum Production-Daten?

Aspekt Grund
Content Echte Inhalte für realistische Entwicklung
SEO Produktions-Meta-Tags und Structured Data
Cookie-Consent Live Cookie-Konfigurationen (DSGVO-relevant)
Media Produktions-Bilder mit allen Größen
Consistency Keine Sync-Probleme zwischen Dev/Prod

API-Dokumentation

Ressource URL
Swagger UI https://cms.c2sgmbh.de/api/docs
OpenAPI JSON https://cms.c2sgmbh.de/api/openapi.json
REST API Base https://cms.c2sgmbh.de/api

Offene Frontend-Tasks

Hohe Priorität

  • Block-Komponenten entwickeln

    • Hero Block
    • Hero Slider Block
    • Text Block
    • Image Text Block
    • Card Grid Block
    • Quote Block
    • CTA Block
    • Contact Form Block
    • Video Block
    • Divider Block
    • Timeline Block
    • Posts List Block
    • Testimonials Block
    • Newsletter Block
    • Process Steps Block
    • FAQ Block
    • Team Block
    • Services Block
  • Newsletter-Anmelde-Formular

    • API: POST /api/newsletter/subscribe
    • Double Opt-In Flow bereits im Backend implementiert
    • Felder: email, firstName (optional), tenantId, source
  • Cookie-Banner implementieren

    • Cookie Configurations aus Production-API laden
    • Consent-Logs an Backend senden
    • DSGVO-konform mit Opt-In

Mittlere Priorität

  • Multi-Tenant Routing

    • Domain-basierte Tenant-Erkennung
    • Locale-Routing (/[locale]/...)
    • Unterstützte Locales: de (default), en
  • SEO-Integration

  • Suche implementieren

    • API: GET /api/search?q=...&locale=de
    • Auto-Complete: GET /api/search/suggestions?q=...
    • Rate-Limit: 30 Requests/Minute

Tenant-spezifische Features

porwoll.de

  • Portfolio-Galerie (Fotografie)
  • Buchungsformular
  • Before/After Bildvergleich

complexcaresolutions.de (C2S)

  • Team-Übersicht
  • Leistungs-Seiten
  • Zertifizierungen
  • Karriere-Seite mit Stellenangeboten

gunshin.de (Game Development)

  • Projekt-Galerie
    • API: GET /api/projects?where[tenant][equals]=5
  • Portfolio-Seiten
  • Referenzen-Slider

zweitmein.ng

  • FAQ-Sektion
  • Preistabellen
  • Kontaktformular

API-Endpoints

Collections

Collection Endpoint Beschreibung
Pages GET /api/pages Seiten mit Blocks
Posts GET /api/posts Blog, News, Presse
Categories GET /api/categories Post-Kategorien
Testimonials GET /api/testimonials Kundenbewertungen
Team GET /api/team Team-Mitglieder
Services GET /api/services Leistungen
FAQs GET /api/faqs FAQ-Einträge
Portfolios GET /api/portfolios Portfolio-Projekte
Media GET /api/media Medien/Bilder
Videos GET /api/videos Video-Bibliothek
Timelines GET /api/timelines Chronologische Events
Workflows GET /api/workflows Prozess-Darstellungen
Favorites GET /api/favorites Affiliate-Produkte (BlogWoman)
Series GET /api/series YouTube-Serien (BlogWoman)

Community Management (YouTube/Meta)

Collection Endpoint Beschreibung
YouTube Channels GET /api/youtube-channels Multi-Kanal-Verwaltung
YouTube Content GET /api/youtube-content Videos + Shorts mit Kommentaren
YT Series GET /api/yt-series Serien mit Branding (Logo, Farben)
YT Notifications GET /api/yt-notifications Handlungsbedarf-System
Social Platforms GET /api/social-platforms Plattform-Konfiguration
Social Accounts GET /api/social-accounts OAuth-Verbindungen
Community Interactions GET /api/community-interactions Kommentare/Nachrichten

Site Settings & Navigation (Tenant-isolierte Collections)

Hinweis: SiteSettings und Navigations wurden zu tenant-spezifischen Collections umgewandelt.

Collection Endpoint Beschreibung
Site Settings GET /api/site-settings?where[tenant][equals]=4 Logo, Name, Kontakt, Adresse
Navigation GET /api/navigations?where[tenant][equals]=4 Menü-Struktur
Privacy Policy GET /api/privacy-policy-settings?where[tenant][equals]=4 Datenschutz

Globals (Systemweit)

Global Endpoint Beschreibung
SEO Settings GET /api/globals/seo-settings Default SEO (Production)

Spezielle Endpoints

Endpoint Methode Beschreibung
/api/search GET Volltextsuche
/api/search/suggestions GET Auto-Complete
/api/newsletter/subscribe POST Newsletter-Anmeldung
/api/timelines GET Timeline-Daten
/api/workflows GET Workflow-Daten

Tenant-Filterung

Alle Collection-Anfragen sollten nach Tenant gefiltert werden:

// Beispiel: Posts für Tenant "c2s" (ID: 4)
fetch('https://cms.c2sgmbh.de/api/posts?where[tenant][equals]=4&locale=de')

// Beispiel: Pages für Tenant "gunshin" (ID: 5)
fetch('https://cms.c2sgmbh.de/api/pages?where[tenant][equals]=5&locale=de')

// Beispiel: SEO-Settings (Global, kein Tenant-Filter)
fetch('https://cms.c2sgmbh.de/api/globals/seo-settings')

Tenant-IDs

ID Name Slug Domain
1 porwoll.de porwoll porwoll.de
4 Complex Care Solutions GmbH c2s complexcaresolutions.de
5 Gunshin gunshin gunshin.de

Bild-Optimierung

Media-Objekte enthalten mehrere Größen:

interface Media {
  url: string           // Original
  sizes: {
    thumbnail: { url, width, height }    // 150x150
    small: { url, width, height }        // 300x300
    medium: { url, width, height }       // 600x600
    large: { url, width, height }        // 1200x1200
    xlarge: { url, width, height }       // 1920x1920
    '2k': { url, width, height }         // 2560x2560
    og: { url, width, height }           // 1200x630 (Social)
    // + AVIF-Varianten
    thumbnail_avif: { url, width, height }
    small_avif: { url, width, height }
    // ...
  }
  focalX?: number       // Fokuspunkt X (0-100)
  focalY?: number       // Fokuspunkt Y (0-100)
}

Lokalisierung

Unterstützte Locales: de (default), en

// Deutsch (default)
fetch('https://cms.c2sgmbh.de/api/posts?locale=de')

// Englisch
fetch('https://cms.c2sgmbh.de/api/posts?locale=en')

// Fallback: Wenn EN nicht vorhanden, wird DE zurückgegeben

Newsletter-Integration

Anmeldung

const response = await fetch('https://cms.c2sgmbh.de/api/newsletter/subscribe', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'user@example.com',
    firstName: 'Max',           // optional
    tenantId: 4,                // Pflicht
    source: 'footer'            // optional: Herkunft
  })
})

// Response: { success: true, message: '...' }

Flow

  1. User gibt E-Mail ein → POST /api/newsletter/subscribe
  2. Backend sendet Double Opt-In E-Mail
  3. User klickt Bestätigungs-Link
  4. Backend sendet Willkommens-E-Mail
  5. User kann sich über Link in E-Mails abmelden

Konfiguration laden

// Cookie-Konfiguration aus Production laden
const config = await fetch('https://cms.c2sgmbh.de/api/cookie-configurations?where[tenant][equals]=4')
  .then(r => r.json())

// config.docs enthält:
// - Kategorien (necessary, analytics, marketing, etc.)
// - Cookie-Details pro Kategorie
// - Texte für Banner (lokalisiert)
await fetch('https://cms.c2sgmbh.de/api/consent-logs', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    tenant: 4,
    consentGiven: true,
    categories: ['necessary', 'analytics'],
    ipAddress: '...',           // Optional, für DSGVO
    userAgent: navigator.userAgent
  })
})

SEO-Integration (Production-Daten)

Global SEO-Settings

// SEO-Defaults aus Production laden
const seoSettings = await fetch('https://cms.c2sgmbh.de/api/globals/seo-settings')
  .then(r => r.json())

// Enthält:
// - defaultTitle, titleTemplate
// - defaultDescription
// - defaultImage (OG-Image)
// - robotsDefault

Page-spezifische SEO

// SEO-Daten aus Page laden
const page = await fetch('https://cms.c2sgmbh.de/api/pages?where[slug][equals]=about&where[tenant][equals]=4')
  .then(r => r.json())

// page.docs[0].meta enthält:
// - title, description
// - image (OG-Image Override)
// - noIndex, noFollow

Sitemap

Die Sitemap wird automatisch von Payload generiert:


Kontaktformular

Formular-Submissions werden über die Forms-Collection verarbeitet:

await fetch('https://cms.c2sgmbh.de/api/form-submissions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    form: 1,                    // Form-ID
    submissionData: [
      { field: 'name', value: 'Max Mustermann' },
      { field: 'email', value: 'max@example.com' },
      { field: 'message', value: 'Ihre Nachricht...' }
    ]
  })
})

Authentifizierung (optional)

Falls User-Authentifizierung benötigt wird:

// Login
const { token, user } = await fetch('https://cms.c2sgmbh.de/api/users/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password })
}).then(r => r.json())

// Authentifizierte Requests
fetch('https://cms.c2sgmbh.de/api/...', {
  headers: { 'Authorization': `JWT ${token}` }
})

Entwicklungshinweise

TypeScript-Typen

Die Payload-Typen können aus dem Backend exportiert werden:

# Auf dem Payload-Server (Production)
ssh payload@162.55.85.18
cd ~/payload-cms
pnpm payload generate:types

# Datei: src/payload-types.ts

Diese Datei kann ins Frontend-Projekt kopiert werden für typsichere API-Calls.

Rate-Limits

Endpoint Limit
Öffentliche API 60/min
Suche 30/min
Newsletter 5/10min
Formulare 5/10min

Caching

  • API-Responses werden serverseitig gecacht (Redis)
  • TTL: 60 Sekunden für Suche
  • Cache wird bei Content-Änderungen invalidiert

CORS

Die Production-API erlaubt Requests von:

  • *.porwoll.tech (Development)
  • porwoll.de, complexcaresolutions.de, gunshin.de (Production)

Development Server (sv-frontend)

SSH-Zugang

ssh frontend@10.10.181.104

Projekt starten

cd ~/frontend.porwoll.de
pnpm dev
# Läuft auf Port 3000 → https://porwoll-dev.porwoll.tech

AI-Tools

claude      # Claude Code CLI
codex       # Codex CLI
gemini      # Gemini CLI

Service-Management

# Systemd Service starten
systemctl start frontend-porwoll

# Service stoppen
systemctl stop frontend-porwoll

# Logs anzeigen
journalctl -u frontend-porwoll -f

Community Management Integration

YouTube-Inhalte abrufen

// Alle Videos eines Kanals
const videos = await fetch(
  'https://cms.c2sgmbh.de/api/youtube-content?where[channel][equals]=1&where[contentType][equals]=video'
).then(r => r.json())

// Serien eines Kanals
const series = await fetch(
  'https://cms.c2sgmbh.de/api/yt-series?where[channel][equals]=1&where[isActive][equals]=true'
).then(r => r.json())

// Videos einer Serie
const seriesVideos = await fetch(
  'https://cms.c2sgmbh.de/api/youtube-content?where[series][equals]=1'
).then(r => r.json())

Kommentare/Interaktionen (Auth erforderlich)

// Kommentare eines Videos
const comments = await fetch(
  'https://cms.c2sgmbh.de/api/community-interactions?where[contentId][equals]=VIDEO_ID',
  { headers: { 'Authorization': `JWT ${token}` } }
).then(r => r.json())

// Ungelesene Benachrichtigungen
const notifications = await fetch(
  'https://cms.c2sgmbh.de/api/yt-notifications?where[status][equals]=unread',
  { headers: { 'Authorization': `JWT ${token}` } }
).then(r => r.json())

Ressourcen


Letzte Aktualisierung: 17.01.2026