mein-sterntours/dev/NEWSLETTER.md

324 lines
9.3 KiB
Markdown

# 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
```bash
./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.
```sql
-- 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:
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
# 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`):
```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:
```php
// 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:
```php
// 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