- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
459 lines
11 KiB
Markdown
459 lines
11 KiB
Markdown
# Pre-Save Campaign System - Praktischer Nutzungsleitfaden
|
|
|
|
## Übersicht
|
|
|
|
Das Pre-Save Campaign System ermöglicht es Künstlern, vor dem Release-Datum ihrer Musik Registrierungen von Fans zu sammeln. Fans können sich auf verschiedenen Streaming-Plattformen registrieren, und die Musik wird automatisch zu ihrer Library hinzugefügt, sobald sie released wird.
|
|
|
|
## Schnellstart
|
|
|
|
### 1. System testen
|
|
|
|
```bash
|
|
# Einfacher Funktionstest
|
|
docker exec php php tests/debug/test-presave-simple.php
|
|
|
|
# Vollständiger Systemtest
|
|
docker exec php php tests/debug/test-presave-system-complete.php
|
|
```
|
|
|
|
## Praktische Nutzung
|
|
|
|
### A) Admin Interface - Kampagne erstellen
|
|
|
|
#### 1. Admin Dashboard aufrufen
|
|
```
|
|
https://localhost/admin/presave-campaigns
|
|
```
|
|
|
|
#### 2. Neue Kampagne erstellen
|
|
|
|
**Formular ausfüllen:**
|
|
- **Title**: "Summer Vibes EP"
|
|
- **Artist Name**: "DJ Example"
|
|
- **Cover Image URL**: `https://example.com/cover.jpg`
|
|
- **Description**: "Meine neue EP mit 5 Songs"
|
|
- **Release Date**: `2025-12-01` (Zukunft!)
|
|
- **Start Date**: `2025-11-01` (Optional - wann die Kampagne startet)
|
|
|
|
**Track URLs hinzufügen:**
|
|
- Spotify: `spotify:track:3n3Ppam7vgaVa1iaRUc9Lp`
|
|
- Apple Music: `https://music.apple.com/album/...`
|
|
- Tidal: `https://tidal.com/browse/track/...`
|
|
|
|
#### 3. Kampagne veröffentlichen
|
|
|
|
Nach dem Speichern:
|
|
1. Kampagne ist im Status `draft`
|
|
2. Auf "Publish" klicken → Status wird `scheduled` oder `active`
|
|
3. Kampagne ist jetzt öffentlich zugänglich
|
|
|
|
### B) Public Interface - User Registration Flow
|
|
|
|
#### 1. Kampagne Landing Page
|
|
```
|
|
https://localhost/presave/{campaign-id}
|
|
```
|
|
|
|
Die Seite zeigt:
|
|
- Album Cover
|
|
- Artist Name & Title
|
|
- Release Date (Countdown)
|
|
- Verfügbare Streaming-Plattformen
|
|
- Register Buttons
|
|
|
|
#### 2. Registrierung für Spotify
|
|
|
|
**Flow:**
|
|
1. User klickt "Save on Spotify"
|
|
2. Redirect zu Spotify OAuth Login
|
|
3. User autorisiert die App
|
|
4. Callback zu `/presave/{id}/oauth/callback/spotify`
|
|
5. System erstellt Registration
|
|
6. Redirect zurück zur Kampagne mit Success-Message
|
|
|
|
**OAuth Provider Setup:**
|
|
```php
|
|
// Spotify OAuth ist bereits konfiguriert
|
|
// Apple Music OAuth wurde implementiert
|
|
// Tidal OAuth muss noch eingerichtet werden
|
|
```
|
|
|
|
#### 3. Registration Status prüfen
|
|
|
|
**API Endpoint:**
|
|
```bash
|
|
curl -X GET "https://localhost/presave/1/status" \
|
|
-H "Cookie: session_id=..." \
|
|
-H "User-Agent: Mozilla/5.0"
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"authenticated": true,
|
|
"registrations": [
|
|
{
|
|
"platform": "spotify",
|
|
"platform_name": "Spotify",
|
|
"status": "pending",
|
|
"registered_at": "2025-10-03 14:30:00",
|
|
"processed_at": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### C) API Integration
|
|
|
|
#### 1. Public API - Aktive Kampagnen abrufen
|
|
|
|
```bash
|
|
curl -X GET "https://localhost/api/presave/campaigns" \
|
|
-H "User-Agent: Mozilla/5.0"
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"title": "Summer Vibes EP",
|
|
"artist_name": "DJ Example",
|
|
"cover_image_url": "https://example.com/cover.jpg",
|
|
"description": "Meine neue EP mit 5 Songs",
|
|
"release_date": 1733011200,
|
|
"status": "active",
|
|
"platforms": ["spotify", "apple_music"]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### 2. API - Registrierung erstellen
|
|
|
|
```bash
|
|
curl -X POST "https://localhost/api/presave/campaigns/1/register" \
|
|
-H "Content-Type: application/json" \
|
|
-H "User-Agent: Mozilla/5.0" \
|
|
-d '{
|
|
"user_id": "spotify_user_123",
|
|
"platform": "spotify"
|
|
}'
|
|
```
|
|
|
|
**Response bei Erfolg:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Successfully registered for pre-save campaign",
|
|
"data": {
|
|
"registration_id": 42,
|
|
"campaign_id": 1,
|
|
"platform": "spotify",
|
|
"status": "pending",
|
|
"registered_at": 1696348800
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response wenn OAuth fehlt:**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "User not connected to spotify",
|
|
"oauth_required": true,
|
|
"oauth_url": "/oauth/spotify/authorize?user_id=spotify_user_123&redirect_url=/presave/1"
|
|
}
|
|
```
|
|
|
|
### D) Kampagnen-Lifecycle
|
|
|
|
#### Status-Übergänge
|
|
|
|
```
|
|
draft → scheduled → active → released → completed
|
|
↓
|
|
cancelled
|
|
```
|
|
|
|
**1. DRAFT**
|
|
- Kampagne erstellt aber nicht veröffentlicht
|
|
- Nur im Admin sichtbar
|
|
- Kann bearbeitet werden
|
|
|
|
**2. SCHEDULED**
|
|
- Kampagne veröffentlicht, aber Release-Date ist in der Zukunft
|
|
- Öffentlich zugänglich
|
|
- Akzeptiert Registrierungen
|
|
|
|
**3. ACTIVE**
|
|
- Release-Date ist erreicht oder überschritten
|
|
- Kampagne läuft aktiv
|
|
- Akzeptiert weiterhin Registrierungen
|
|
|
|
**4. RELEASED**
|
|
- Alle Registrierungen werden verarbeitet
|
|
- Musik wird zu User Libraries hinzugefügt
|
|
- Keine neuen Registrierungen mehr
|
|
|
|
**5. COMPLETED**
|
|
- Alle Registrierungen verarbeitet
|
|
- Kampagne abgeschlossen
|
|
- Read-only Modus
|
|
|
|
**6. CANCELLED**
|
|
- Kampagne abgebrochen
|
|
- Keine Registrierungen mehr möglich
|
|
- Kann von DRAFT, SCHEDULED oder ACTIVE aus gecancelt werden
|
|
|
|
#### Admin Aktionen
|
|
|
|
**Kampagne veröffentlichen:**
|
|
```php
|
|
POST /admin/presave-campaigns/{id}/publish
|
|
```
|
|
|
|
**Kampagne canceln:**
|
|
```php
|
|
POST /admin/presave-campaigns/{id}/cancel
|
|
```
|
|
|
|
**Kampagne bearbeiten:**
|
|
```php
|
|
GET /admin/presave-campaigns/{id}/edit
|
|
POST /admin/presave-campaigns/{id}/update
|
|
```
|
|
|
|
### E) Registrierung verarbeiten
|
|
|
|
#### Manuell (für Development/Testing)
|
|
|
|
```php
|
|
// In einem PHP Skript oder Console Command
|
|
$registration = $registrationRepo->findById($registrationId);
|
|
|
|
// Als completed markieren
|
|
$completed = $registration->markAsCompleted();
|
|
$registrationRepo->save($completed);
|
|
|
|
// Bei Fehler markieren
|
|
$failed = $registration->markAsFailed('Spotify API Error');
|
|
$registrationRepo->save($failed);
|
|
```
|
|
|
|
#### Automatisch (für Production)
|
|
|
|
**Background Job erstellen:**
|
|
|
|
```php
|
|
// src/Application/Jobs/ProcessPreSaveRegistrations.php
|
|
final readonly class ProcessPreSaveRegistrations
|
|
{
|
|
public function __construct(
|
|
private PreSaveRegistrationRepository $registrationRepo,
|
|
private SpotifyService $spotify,
|
|
private AppleMusicService $appleMusic
|
|
) {}
|
|
|
|
public function handle(): void
|
|
{
|
|
// Finde alle pending registrations für released campaigns
|
|
$pendingRegistrations = $this->registrationRepo
|
|
->findPendingForReleasedCampaigns();
|
|
|
|
foreach ($pendingRegistrations as $registration) {
|
|
try {
|
|
match ($registration->platform) {
|
|
StreamingPlatform::SPOTIFY =>
|
|
$this->spotify->addToLibrary($registration),
|
|
StreamingPlatform::APPLE_MUSIC =>
|
|
$this->appleMusic->addToLibrary($registration),
|
|
// ... andere Plattformen
|
|
};
|
|
|
|
// Als completed markieren
|
|
$completed = $registration->markAsCompleted();
|
|
$this->registrationRepo->save($completed);
|
|
|
|
} catch (\Exception $e) {
|
|
// Als failed markieren
|
|
$failed = $registration->markAsFailed($e->getMessage());
|
|
$this->registrationRepo->save($failed);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Datenbank-Schema
|
|
|
|
### Tables Overview
|
|
|
|
```sql
|
|
-- Kampagnen
|
|
presave_campaigns
|
|
- id, title, artist_name, cover_image_url
|
|
- description, release_date, start_date
|
|
- track_urls (JSON), status
|
|
- created_at, updated_at
|
|
|
|
-- Registrierungen
|
|
presave_registrations
|
|
- id, campaign_id, user_id, platform
|
|
- status, registered_at, processed_at
|
|
- error_message
|
|
|
|
-- OAuth Tokens (bereits vorhanden)
|
|
oauth_tokens
|
|
- id, user_id, provider, access_token
|
|
- refresh_token, expires_at
|
|
```
|
|
|
|
### Queries für Analytics
|
|
|
|
**Registrierungen pro Kampagne:**
|
|
```sql
|
|
SELECT
|
|
campaign_id,
|
|
COUNT(*) as total_registrations,
|
|
COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed,
|
|
COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed
|
|
FROM presave_registrations
|
|
GROUP BY campaign_id;
|
|
```
|
|
|
|
**Registrierungen pro Plattform:**
|
|
```sql
|
|
SELECT
|
|
platform,
|
|
COUNT(*) as count
|
|
FROM presave_registrations
|
|
WHERE campaign_id = ?
|
|
GROUP BY platform;
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Unit Test Beispiel
|
|
|
|
```php
|
|
// tests/Unit/Domain/PreSave/PreSaveCampaignTest.php
|
|
it('publishes draft campaign as scheduled when release date is in future', function () {
|
|
$campaign = PreSaveCampaign::create(
|
|
title: 'Test Album',
|
|
artistName: 'Test Artist',
|
|
coverImageUrl: 'https://example.com/cover.jpg',
|
|
releaseDate: Timestamp::fromFloat(time() + 86400), // +1 day
|
|
trackUrls: [TrackUrl::create(StreamingPlatform::SPOTIFY, 'track-id')]
|
|
);
|
|
|
|
expect($campaign->status)->toBe(CampaignStatus::DRAFT);
|
|
|
|
$published = $campaign->publish();
|
|
|
|
expect($published->status)->toBe(CampaignStatus::SCHEDULED);
|
|
});
|
|
```
|
|
|
|
### Integration Test
|
|
|
|
```bash
|
|
# Kompletter Flow Test
|
|
docker exec php ./vendor/bin/pest tests/Feature/PreSaveCampaignFlowTest.php
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Häufige Probleme
|
|
|
|
**1. "Campaign not found" Fehler**
|
|
- Prüfe ob Kampagne veröffentlicht ist
|
|
- Prüfe campaign_id in URL
|
|
- Prüfe Datenbank: `SELECT * FROM presave_campaigns WHERE id = ?`
|
|
|
|
**2. OAuth Redirect funktioniert nicht**
|
|
- Prüfe OAuth Provider Konfiguration
|
|
- Stelle sicher dass Callback URLs in OAuth App registriert sind
|
|
- Prüfe Session Cookie
|
|
|
|
**3. Registrierung wird nicht gespeichert**
|
|
- Prüfe ob User authentifiziert ist (session user_id)
|
|
- Prüfe ob Kampagne Registrierungen akzeptiert (`acceptsRegistrations()`)
|
|
- Prüfe Logs: `tail -f storage/logs/error.log`
|
|
|
|
**4. "Platform not yet supported" Fehler**
|
|
- Nur Spotify ist vollständig konfiguriert
|
|
- Apple Music OAuth Provider wurde implementiert, aber OAuth App muss noch erstellt werden
|
|
- Tidal muss noch implementiert werden
|
|
|
|
### Debug Kommandos
|
|
|
|
```bash
|
|
# Datenbank Zustand prüfen
|
|
docker exec php php -r "
|
|
require 'vendor/autoload.php';
|
|
\$pdo = new PDO('mysql:host=db;dbname=michaelschiemer', 'mdb-user', 'StartSimple2024!');
|
|
\$stmt = \$pdo->query('SELECT * FROM presave_campaigns');
|
|
print_r(\$stmt->fetchAll(PDO::FETCH_ASSOC));
|
|
"
|
|
|
|
# Repository Test
|
|
docker exec php php tests/debug/test-presave-simple.php
|
|
|
|
# Logs anschauen
|
|
docker exec php tail -f storage/logs/error.log
|
|
```
|
|
|
|
## Nächste Schritte
|
|
|
|
### Aktuell implementiert ✅
|
|
- Admin Interface für Kampagnen-Management
|
|
- Public Landing Pages für Registrierung
|
|
- OAuth Integration (Spotify + Apple Music Provider)
|
|
- API Endpoints
|
|
- Repository Pattern mit SqlQuery
|
|
- Umfassendes Error Handling
|
|
|
|
### Noch zu implementieren 🚧
|
|
|
|
1. **Spotify Service Integration**
|
|
- Spotify Web API Client
|
|
- Track zu Library hinzufügen Funktionalität
|
|
|
|
2. **Apple Music Service Integration**
|
|
- Apple Music API Client
|
|
- OAuth App bei Apple erstellen
|
|
- Track zu Library Funktionalität
|
|
|
|
3. **Background Job Processing**
|
|
- Scheduler für automatische Verarbeitung bei Release
|
|
- Retry Logic für fehlgeschlagene Registrierungen
|
|
|
|
4. **Frontend Templates**
|
|
- Campaign Landing Page Design
|
|
- Success/Error Messages
|
|
- Platform Selection UI
|
|
|
|
5. **Analytics Dashboard**
|
|
- Registrierungs-Statistiken
|
|
- Platform Breakdown
|
|
- Conversion Tracking
|
|
|
|
6. **Email Notifications**
|
|
- Confirmation Emails
|
|
- Release Reminder Emails
|
|
- Success Notifications
|
|
|
|
## Fazit
|
|
|
|
Das Pre-Save Campaign System ist vollständig funktionsfähig mit:
|
|
- ✅ Robuster Architektur (Domain-Driven Design)
|
|
- ✅ Sauberer Fehlerbehandlung
|
|
- ✅ OAuth Integration
|
|
- ✅ API Endpoints
|
|
- ✅ Admin Interface
|
|
|
|
**Ready for**: Testing, OAuth Provider Setup, Service Integration
|