mein-sterntours/dev/NEWSLETTER.md

9.3 KiB

Newsletter-Modul Dokumentation

Übersicht

Das Newsletter-Modul ermöglicht die zentrale Verwaltung von Newsletter-Kontakten aus beiden Buchungssystemen (Kulturreisen und Ferienwohnungen). Es synchronisiert automatisch Kundendaten aus Buchungen und bietet Export-Funktionen für Newsletter-Kampagnen.

Features

  • Zentrale Kontaktverwaltung für beide Newsletter-Gruppen
  • Automatische Synchronisation aus Buchungssystemen
  • Duplikat-Erkennung über E-Mail-Adressen
  • Tracking von Buchungsstatistiken
  • Status-Verwaltung (Aktiv, Inaktiv, Abgemeldet, Bounced)
  • Herkunfts-Tracking (Buchung, Newsletter-Anmeldung, etc.)
  • Export-Funktion (CSV)
  • Aktivitäts-Log für jeden Kontakt
  • Filter- und Suchfunktionen

Installation

1. Migrationen ausführen

./vendor/bin/sail artisan migrate

Dies erstellt folgende Tabellen:

  • newsletter_contacts - Haupt-Kontakte-Tabelle
  • newsletter_logs - Aktivitäts-Log

2. Berechtigung hinzufügen

In der Datenbank muss die Berechtigung cms-newsletter für Benutzer aktiviert werden, die Zugriff auf das Newsletter-Modul haben sollen.

-- Beispiel: Berechtigung für einen User aktivieren
-- Dies muss über das bestehende Berechtigungssystem erfolgen

3. Erste Synchronisation

Nach der Installation sollte eine vollständige Synchronisation durchgeführt werden:

# Alle Buchungen synchronisieren
./vendor/bin/sail artisan newsletter:sync-kulturreisen --force
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen --force

Verwendung

Admin-Panel

Das Newsletter-Modul ist im Admin-Panel unter CMS > Inhalte > Newsletter erreichbar.

Hauptfunktionen:

  1. Kontaktliste

    • Übersicht aller Newsletter-Kontakte
    • Filter nach Gruppe, Status, Herkunft
    • Suchfunktion nach E-Mail und Name
    • DataTables mit Sortierung und Pagination
  2. Kontakt-Detail

    • Vollständige Kontaktinformationen
    • Buchungsstatistiken
    • Aktivitäts-Log
    • Verlinkung zu Original-Kundendaten
  3. Kontakt bearbeiten

    • Manuelles Erstellen von Kontakten
    • Bearbeiten von Kontaktdaten
    • Status-Änderung
    • Gruppen-Zuweisung
  4. Synchronisation

    • Manuelle Synchronisation über UI
    • Incremental Sync (letzte 30 Tage)
    • Full Sync (alle Buchungen)
  5. Export

    • Export nach Gruppe
    • Export nach Status
    • CSV-Format
    • Vorkonfigurierte Export-Optionen

Artisan-Befehle

Synchronisation Kulturreisen

# Incremental Sync (letzte 30 Tage)
./vendor/bin/sail artisan newsletter:sync-kulturreisen

# Full Sync (alle Buchungen)
./vendor/bin/sail artisan newsletter:sync-kulturreisen --force

Dieser Befehl:

  • Liest alle Buchungen aus der booking Tabelle
  • Verknüpft mit customer Daten
  • Erstellt oder aktualisiert Newsletter-Kontakte
  • Zählt Buchungen pro Kunde
  • Trackt letzte Buchung

Synchronisation Ferienwohnungen

# Incremental Sync (letzte 30 Tage)
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen

# Full Sync (alle Buchungen)
./vendor/bin/sail artisan newsletter:sync-ferienwohnungen --force

Dieser Befehl:

  • Liest Buchungen aus travel_user_booking_fewos mit invoice_number
  • Nur Buchungen mit reiner Nummer (keine Storno etc.)
  • Verknüpft mit travel_users Daten
  • Erstellt oder aktualisiert Newsletter-Kontakte
  • Zählt Buchungen pro Kunde

Automatische Synchronisation

Für regelmäßige Synchronisation empfiehlt sich ein Cron-Job:

# In der crontab
# Täglich um 2 Uhr morgens
0 2 * * * cd /var/www/html && ./vendor/bin/sail artisan newsletter:sync-kulturreisen
0 2 * * * cd /var/www/html && ./vendor/bin/sail artisan newsletter:sync-ferienwohnungen

Oder im Laravel Scheduler (app/Console/Kernel.php):

protected function schedule(Schedule $schedule)
{
    // Täglich um 2 Uhr
    $schedule->command('newsletter:sync-kulturreisen')->dailyAt('02:00');
    $schedule->command('newsletter:sync-ferienwohnungen')->dailyAt('02:15');
}

Datenmodell

Newsletter Contact

Feld Typ Beschreibung
id bigint Primary Key
email string E-Mail-Adresse (unique)
firstname string Vorname
lastname string Nachname
group_kulturreisen boolean Zugehörigkeit zur Gruppe Kulturreisen
group_ferienwohnungen boolean Zugehörigkeit zur Gruppe Ferienwohnungen
source enum Herkunft des Kontakts
status enum Status (active, inactive, unsubscribed, bounced)
subscribed_at timestamp Zeitpunkt der Anmeldung
unsubscribed_at timestamp Zeitpunkt der Abmeldung
last_booking_at timestamp Zeitpunkt der letzten Buchung
total_bookings_kulturreisen int Anzahl Buchungen Kulturreisen
total_bookings_ferienwohnungen int Anzahl Buchungen Ferienwohnungen
customer_id int Referenz zu customer (Kulturreisen)
travel_user_id int Referenz zu travel_users (Ferienwohnungen)
last_synced_at timestamp Letzte Synchronisation
sync_hash string Hash für Duplikat-Erkennung
notes text Notizen

Newsletter Log

Feld Typ Beschreibung
id bigint Primary Key
newsletter_contact_id bigint Foreign Key zu newsletter_contacts
action enum Aktion (subscribed, unsubscribed, etc.)
description string Beschreibung der Aktion
metadata json Zusätzliche Daten
user_id int Admin-User der die Aktion ausgeführt hat

Status-Typen

  • active: Aktiver Newsletter-Empfänger
  • inactive: Inaktiv (z.B. temporär deaktiviert)
  • unsubscribed: Abgemeldet vom Newsletter
  • bounced: E-Mail nicht zustellbar (Bounced)

Herkunfts-Typen

  • booking_kulturreisen: Aus Kulturreisen-Buchung
  • booking_ferienwohnungen: Aus Ferienwohnungs-Buchung
  • newsletter_signup: Newsletter-Anmeldung über Formular
  • manual: Manuell erstellt
  • import: Über Import hinzugefügt

Export-Formate

CSV-Export

Der CSV-Export enthält folgende Spalten:

  1. ID
  2. E-Mail
  3. Vorname
  4. Nachname
  5. Gruppe Kulturreisen (Ja/Nein)
  6. Gruppe Ferienwohnungen (Ja/Nein)
  7. Status
  8. Herkunft
  9. Buchungen Kulturreisen
  10. Buchungen Ferienwohnungen
  11. Letzte Buchung
  12. Angemeldet am
  13. Abgemeldet am
  14. Erstellt am

Best Practices

Duplikat-Vermeidung

Das System verwendet einen Hash basierend auf E-Mail und Quelle zur Duplikat-Erkennung. Kontakte werden automatisch zusammengeführt, wenn:

  • Dieselbe E-Mail-Adresse in beiden Systemen vorkommt
  • Der neuere Datensatz wird bevorzugt
  • Gruppenzugehörigkeiten werden kombiniert

Datenschutz

  • Soft-Delete: Gelöschte Kontakte werden nicht permanent entfernt
  • Log-Tracking: Alle Änderungen werden protokolliert
  • Abmelde-Funktion: Kontakte können sich jederzeit abmelden
  • Export-Kontrolle: Nur autorisierte Benutzer können exportieren

Performance

  • Incremental Sync: Standardmäßig werden nur die letzten 30 Tage synchronisiert
  • Indexierung: E-Mail, Status und Gruppen sind indexiert
  • DataTables: Server-Side Processing für große Datenmengen
  • Batch-Processing: Synchronisation verarbeitet Datensätze effizient

Troubleshooting

Problem: Synchronisation schlägt fehl

Lösung:

  1. Prüfe Datenbankverbindungen (beide Datenbanken müssen erreichbar sein)
  2. Prüfe Logs: storage/logs/laravel.log
  3. Führe Sync mit --force aus für vollständige Synchronisation

Problem: Duplikate in der Liste

Lösung:

  1. Prüfe sync_hash Spalte
  2. Führe manuelle Bereinigung durch
  3. Kontakte können manuell zusammengeführt werden

Problem: Export enthält keine Daten

Lösung:

  1. Prüfe Filter-Einstellungen
  2. Prüfe Status der Kontakte
  3. Prüfe Berechtigungen

API-Endpunkte

Alle Routen sind unter dem Middleware-Schutz ['admin', '2fa', 'auth.permission:cms-newsletter'].

Methode Route Beschreibung
GET /newsletter Liste aller Kontakte
GET /newsletter/datatable DataTables AJAX
GET /newsletter/{id} Detail eines Kontakts
GET /newsletter/{id}/edit Bearbeitungsformular
POST /newsletter/{id}/store Speichern
DELETE /newsletter/{id} Löschen (soft delete)
POST /newsletter/{id}/unsubscribe Abmelden
POST /newsletter/{id}/resubscribe Wieder aktivieren
POST /newsletter/sync Synchronisation starten
GET /newsletter/export Export

Erweiterungen

Integration mit Newsletter-Diensten

Das Modul kann einfach mit externen Newsletter-Diensten (Mailchimp, SendGrid, etc.) integriert werden:

// Beispiel: Export für Mailchimp
$contacts = NewsletterContact::active()->kulturreisen()->get();
foreach ($contacts as $contact) {
    // Mailchimp API Call
}

Webhook für Abmeldungen

Eine öffentliche Abmelde-Route kann hinzugefügt werden:

// routes/web.php
Route::get('/newsletter/unsubscribe/{token}', 'NewsletterPublicController@unsubscribe');

Double-Opt-In

Für Newsletter-Anmeldungen kann ein Double-Opt-In Prozess implementiert werden.

Support

Bei Fragen oder Problemen:

  1. Prüfe diese Dokumentation
  2. Prüfe Laravel Logs
  3. Prüfe Artisan Command Output
  4. Kontaktiere das Entwickler-Team

Changelog

Version 1.0.0 (2025-11-07)

  • Initiales Release
  • Kontaktverwaltung
  • Synchronisation Kulturreisen
  • Synchronisation Ferienwohnungen
  • Export-Funktion
  • Admin-Panel Integration