# RapidMail API Client - Refactored with Value Objects

## Übersicht

Diese refactorierte Version des RapidMail API Clients folgt Domain-Driven Design Prinzipien und trennt klar zwischen **Commands** (für Schreiboperationen) und **Read Models** (für Leseoperationen).

## 🆕 Neue Architektur

### Value Objects für IDs
```php
$recipientId = new RecipientId(123);
$recipientListId = new RecipientListId(776);
$mailingId = new MailingId(456);
```

### Commands für Create/Update
```php
// Neuen Recipient erstellen
$command = new CreateRecipientCommand(
    email: 'user@example.com',
    firstname: 'John',
    lastname: 'Doe',
    recipientListId: $recipientListId
);

// Bestehenden Recipient aktualisieren
$updateCommand = new UpdateRecipientCommand(
    id: $recipientId,
    email: 'updated@example.com',
    firstname: 'Jane'
);
```

### Read Models für Abfragen
```php
// Read Models haben IMMER eine ID
$recipient = $recipientService->get($recipientId);
echo $recipient->id->value; // Garantiert vorhanden
echo $recipient->getFullName(); // Helper methods
echo $recipient->isActive(); // Business logic
```

## 🔧 Quick Start

```php
// 1. Services injizieren lassen (über DI Container)
$recipientService = $container->get(RecipientService::class);
$recipientListService = $container->get(RecipientListService::class);

// 2. Recipient List erstellen oder holen
$list = $recipientListService->create('Newsletter', 'Main subscriber list');

// 3. Recipient erstellen
$command = new CreateRecipientCommand(
    email: 'test@example.com',
    firstname: 'Test',
    lastname: 'User',
    recipientListId: $list->id
);

$recipient = $recipientService->createWithCommand($command);
echo "Created: {$recipient->getFullName()}";
```

## 📚 API Reference

### RecipientService

#### Neue Methoden (empfohlen)
```php
// Erstellen
$recipient = $recipientService->createWithCommand($createCommand);

// Lesen
$recipient = $recipientService->get($recipientId);
$recipients = $recipientService->search(['status' => 'active']);
$recipient = $recipientService->findByEmail('test@example.com', $recipientListId);

// Aktualisieren
$recipient = $recipientService->updateWithCommand($updateCommand);

// Löschen
$recipientService->delete($recipientId);
```

#### Legacy Methoden (deprecated, aber funktional)
```php
$recipient = $recipientService->getById(123); // ❌ Deprecated
$recipient = $recipientService->get(new RecipientId(123)); // ✅ Neu
```

### RecipientListService

```php
// Erstellen
$list = $recipientListService->create('Name', 'Description');

// Alle listen
$lists = $recipientListService->getAll();

// Einzelne Liste
$list = $recipientListService->get($recipientListId);

// Aktualisieren
$list = $recipientListService->update($recipientListId, 'New Name');

// Löschen
$recipientListService->delete($recipientListId);
```

### Command Factory

```php
// Aus Array erstellen
$command = RecipientCommandFactory::createFromArray([
    'email' => 'test@example.com',
    'firstname' => 'John'
], $recipientListId);

// Aus bestehendem Recipient
$updateCommand = RecipientCommandFactory::updateFromRecipient($recipient);

// Mit Änderungen
$updateCommand = RecipientCommandFactory::updateFromRecipientWithChanges(
    $recipient, 
    ['company' => 'New Company']
);
```

## 🎯 Vorteile der neuen Architektur

### 1. Type Safety
```php
// ❌ Alte API: Fehleranfällig
function processRecipient(int $id) {
    // Ist das eine RecipientId oder RecipientListId?
}

// ✅ Neue API: Typsicher
function processRecipient(RecipientId $id) {
    // Klar definiert, was erwartet wird
}
```

### 2. Klare Trennung
```php
// ❌ Alte API: Verwirrung
$recipient = new Recipient(); // Hat das eine ID oder nicht?

// ✅ Neue API: Eindeutig
$command = new CreateRecipientCommand(...); // Für CREATE
$recipient = $recipientService->get($id);   // Hat IMMER eine ID
```

### 3. Business Logic
```php
$recipient = $recipientService->get($recipientId);

// Helper methods für bessere Lesbarkeit
echo $recipient->getFullName();
echo $recipient->isActive() ? 'Active' : 'Inactive';
echo $list->isDefault() ? 'Default list' : 'Custom list';
```

### 4. Validation
```php
// Value Objects validieren automatisch
$id = new RecipientId(-1); // ❌ Exception: ID muss positiv sein
$command = new CreateRecipientCommand('invalid-email'); // ❌ Exception: Ungültige E-Mail
```

## 🔄 Migration Guide

### Von alter API zu neuer API

**Alt:**
```php
$recipient = new Recipient(null, 'test@example.com', 'John');
$saved = $recipientService->create($recipient);
```

**Neu:**
```php
$command = new CreateRecipientCommand('test@example.com', 'John');
$saved = $recipientService->createWithCommand($command);
```

**Alt:**
```php
$recipient = $recipientService->get(123);
```

**Neu:**
```php
$recipient = $recipientService->get(new RecipientId(123));
```

## 🐛 Debugging & Troubleshooting

### Häufige Probleme

1. **"Recipient data must contain ID"**
   - Lösung: Verwende Commands für CREATE, Read Models nur für Responses

2. **"RecipientId must be positive"**
   - Lösung: Überprüfe, dass IDs gültig sind

3. **API-Struktur Probleme**
   - Alte Services verwenden noch `$data['data']` statt `$data['_embedded']`
   - Neue Services sind bereits korrigiert

### Debug Helpers
```php
// Value Object Informationen
echo "Recipient ID: {$recipientId}";
echo "Equal? " . $recipientId->equals($otherRecipientId);

// Read Model Informationen  
echo "Full name: {$recipient->getFullName()}";
echo "Has list: " . $recipient->hasRecipientList();
```

## 📋 API Corrections Applied

### Fixed Issues:
1. ✅ **Data Structure**: `$data['_embedded']['recipientlists']` statt `$data['data']`
2. ✅ **Field Names**: `created`/`updated` statt `created_at`/`updated_at`  
3. ✅ **Return Types**: Direkte Arrays von Objekten statt verschachtelte Strukturen
4. ✅ **Pagination**: Korrekte API-Struktur implementiert
5. ✅ **Value Objects**: Typisierte IDs für bessere Type Safety
6. ✅ **Command/Query**: Saubere Trennung zwischen Commands und Read Models

## 🔮 Roadmap

- [ ] MailingService refactoring
- [ ] StatisticsService improvement
- [ ] Event-driven architecture integration
- [ ] Caching layer
- [ ] Rate limiting
- [ ] Bulk operations

## 💡 Best Practices

1. **Verwende immer Value Objects für IDs**
2. **Commands für Schreiboperationen, Read Models für Leseoperationen**
3. **Factory Pattern für komplexe Command-Erstellung**
4. **Helper Methods in Read Models für Business Logic**
5. **Backward Compatibility während der Migration**

## 📖 Weitere Beispiele

Siehe `Examples/UsageExamples.php` für detaillierte Anwendungsbeispiele und `Examples/QuickStartGuide.php` für einen schnellen Einstieg.
