241 lines
7 KiB
Markdown
241 lines
7 KiB
Markdown
# Domain Management System - Optimierte Architektur
|
|
|
|
## Übersicht
|
|
|
|
Dieses optimierte Domain Management System löst die Session-Probleme des aktuellen Systems und bietet eine saubere, wartbare Architektur für Multi-Domain-Anwendungen.
|
|
|
|
## Hauptprobleme der aktuellen Implementierung
|
|
|
|
1. **Session-Konflikte**: DomainResolver wird zu früh ausgeführt, bevor die Session-Middleware verfügbar ist
|
|
2. **Zwei Sessions**: Dadurch werden zwei separate Sessions erstellt
|
|
3. **Komplexe Logik**: Domain-Auflösung und Session-Management sind eng gekoppelt
|
|
4. **Performance**: Ineffizientes Caching und wiederholte DB-Abfragen
|
|
|
|
## Neue Architektur
|
|
|
|
### Kernkomponenten
|
|
|
|
```
|
|
├── DomainResolver (Middleware) - Reine Domain-Auflösung
|
|
├── DomainContext (DTO) - Unveränderlicher Domain-Kontext
|
|
├── DomainService - Zentraler Service für Domain-Logik
|
|
├── SessionHandler - Event-basiertes Session-Management
|
|
├── RouteService - Domain-aware Route-Loading
|
|
└── CacheManager - Optimiertes Caching
|
|
```
|
|
|
|
### Middleware-Reihenfolge (Behoben)
|
|
|
|
```php
|
|
'web' => [
|
|
\App\Http\Middleware\EncryptCookies::class,
|
|
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
|
\App\Http\Middleware\DomainResolver::class, // ✅ Nach Cookies, vor Session
|
|
\Illuminate\Session\Middleware\StartSession::class,
|
|
\App\Http\Middleware\DomainSessionHandler::class, // ✅ Nach Session-Start
|
|
// ... weitere Middleware
|
|
]
|
|
```
|
|
|
|
## Hauptverbesserungen
|
|
|
|
### 1. Session-Problem gelöst
|
|
|
|
- **DomainResolver**: Läuft nach Cookie-Encryption, aber vor Session-Start
|
|
- **DomainSessionHandler**: Verarbeitet Session-Updates nach Session-Initialisierung
|
|
- **Event-basierte Kommunikation**: Domain-Änderungen werden als Events behandelt
|
|
|
|
### 2. Saubere Trennung der Verantwortlichkeiten
|
|
|
|
- **DomainResolver**: Nur Domain-Auflösung und Kontext-Erstellung
|
|
- **DomainSessionHandler**: Nur Session-Management
|
|
- **DomainService**: Reine Geschäftslogik
|
|
|
|
### 3. Performance-Optimierungen
|
|
|
|
- **Intelligentes Caching**: Mehrere Cache-Schichten
|
|
- **Lazy Loading**: UserShop-Daten werden nur bei Bedarf geladen
|
|
- **Batch-Operations**: Mehrere Domain-Validierungen in einem Durchgang
|
|
|
|
### 4. Domain-Types
|
|
|
|
```php
|
|
enum DomainType: string {
|
|
case MAIN = 'main'; // mivita.care
|
|
case SHOP = 'shop'; // mivita.shop
|
|
case CRM = 'crm'; // my.mivita.care
|
|
case PORTAL = 'portal'; // in.mivita.care
|
|
case CHECKOUT = 'checkout'; // checkout.mivita.care
|
|
case USER_SHOP = 'user-shop'; // {slug}.mivita.care
|
|
case UNKNOWN = 'unknown';
|
|
}
|
|
```
|
|
|
|
## Implementierung
|
|
|
|
### DomainResolver (Neue Middleware)
|
|
|
|
```php
|
|
class DomainResolver
|
|
{
|
|
public function handle(Request $request, Closure $next)
|
|
{
|
|
// 1. Domain parsen und Context erstellen
|
|
$context = $this->resolveDomain($request->getHost());
|
|
|
|
// 2. Context in Request speichern (nicht Session!)
|
|
$request->merge(['domain_context' => $context]);
|
|
|
|
// 3. Session-Domain setzen für Cookies
|
|
$this->setSessionDomain($context);
|
|
|
|
// 4. Domain-Changed Event auslösen (falls nötig)
|
|
if ($this->domainChanged($context)) {
|
|
event(new DomainChangedEvent($context));
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
}
|
|
```
|
|
|
|
### DomainSessionHandler (Neue Middleware)
|
|
|
|
```php
|
|
class DomainSessionHandler
|
|
{
|
|
public function handle(Request $request, Closure $next)
|
|
{
|
|
$response = $next($request);
|
|
|
|
// Session nur updaten, wenn Domain-Context verfügbar
|
|
if ($context = $request->get('domain_context')) {
|
|
$this->updateSessionForDomain($context);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
private function updateSessionForDomain(DomainContext $context): void
|
|
{
|
|
// UserShop in Session setzen/behalten
|
|
if ($context->isUserShop()) {
|
|
Session::put('user_shop', $context->userShop);
|
|
Session::put('user_shop_domain', $context->host);
|
|
}
|
|
|
|
// Session-Domain aktualisieren
|
|
Config::set('session.domain', $this->getSessionDomain($context));
|
|
}
|
|
}
|
|
```
|
|
|
|
### DomainService (Optimierte Version)
|
|
|
|
```php
|
|
class DomainService
|
|
{
|
|
public function resolveDomain(string $host): DomainContext
|
|
{
|
|
// 1. Host normalisieren
|
|
$normalizedHost = $this->normalizeHost($host);
|
|
|
|
// 2. Domain-Info parsen
|
|
$domainInfo = $this->parseDomain($normalizedHost);
|
|
|
|
// 3. Domain-Type bestimmen
|
|
$type = $this->determineDomainType($domainInfo);
|
|
|
|
// 4. UserShop laden (nur bei Bedarf)
|
|
$userShop = $this->loadUserShopIfNeeded($type, $domainInfo);
|
|
|
|
return new DomainContext($type, $normalizedHost, $domainInfo['subdomain'], $userShop);
|
|
}
|
|
|
|
private function loadUserShopIfNeeded(DomainType $type, array $domainInfo): ?UserShop
|
|
{
|
|
if (!$type->isUserShop()) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getUserShop($domainInfo['subdomain']);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Migration Guide
|
|
|
|
### Schritt 1: Neue Dateien hinzufügen
|
|
|
|
```bash
|
|
# Neue Middleware
|
|
cp dev/subdomain-optimization-grok/src/Middleware/DomainResolver.php app/Http/Middleware/
|
|
cp dev/subdomain-optimization-grok/src/Middleware/DomainSessionHandler.php app/Http/Middleware/
|
|
|
|
# Neue Services
|
|
cp dev/subdomain-optimization-grok/src/Services/DomainService.php app/Services/
|
|
cp dev/subdomain-optimization-grok/src/Services/DomainCacheManager.php app/Services/
|
|
|
|
# Neue Domain-Klassen
|
|
cp dev/subdomain-optimization-grok/src/Domain/DomainContext.php app/Domain/
|
|
cp dev/subdomain-optimization-grok/src/Domain/DomainType.php app/Domain/
|
|
```
|
|
|
|
### Schritt 2: Kernel.php aktualisieren
|
|
|
|
```php
|
|
'web' => [
|
|
// ... existing middleware ...
|
|
\App\Http\Middleware\DomainResolver::class, // Nach Cookies
|
|
\Illuminate\Session\Middleware\StartSession::class,
|
|
\App\Http\Middleware\DomainSessionHandler::class, // Nach Session
|
|
// ... rest of middleware ...
|
|
],
|
|
```
|
|
|
|
### Schritt 3: DomainServiceProvider aktualisieren
|
|
|
|
```php
|
|
// Alte DomainResolver-Middleware entfernen
|
|
// Neue Services registrieren
|
|
```
|
|
|
|
## Vorteile der neuen Architektur
|
|
|
|
1. **Session-Konflikte behoben**: Klare Trennung zwischen Domain-Auflösung und Session-Management
|
|
2. **Bessere Performance**: Optimiertes Caching und Lazy Loading
|
|
3. **Wartbarkeit**: Klare Trennung der Verantwortlichkeiten
|
|
4. **Testbarkeit**: Jede Komponente kann isoliert getestet werden
|
|
5. **Skalierbarkeit**: Einfache Erweiterung um neue Domain-Types
|
|
6. **Event-Driven**: Lose Kopplung durch Events
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
# Unit Tests
|
|
php artisan test tests/Unit/Domain/
|
|
|
|
# Feature Tests
|
|
php artisan test tests/Feature/DomainRouting/
|
|
|
|
# Integration Tests
|
|
php artisan test tests/Feature/SessionDomainSwitching/
|
|
```
|
|
|
|
## Monitoring
|
|
|
|
Das neue System integriert sich nahtlos mit Laravel's Logging und Monitoring:
|
|
|
|
```php
|
|
// Domain-Resolution Metrics
|
|
Log::channel('domain')->info('Domain resolved', [
|
|
'host' => $host,
|
|
'type' => $context->type,
|
|
'resolution_time' => $time,
|
|
'cache_hit' => $cacheHit
|
|
]);
|
|
```
|
|
|
|
## Fazit
|
|
|
|
Diese optimierte Architektur löst alle identifizierten Probleme und bietet eine solide Grundlage für zukünftige Erweiterungen des Domain-Systems.
|