mivita/dev/subdomain-optimization-claude/README.md
2025-10-20 17:42:08 +02:00

7.4 KiB
Raw Blame History

Domain-Routing Optimierung - Sauberes Session-Handling

📋 Problemanalyse

Das Kernproblem

Das aktuelle Domain-Routing-System von Mivita hat ein Session-Timing-Problem:

  1. DomainResolver-Middleware läuft VOR der Laravel StartSession-Middleware
  2. Sie versucht Session-Daten zu setzen (Session::put, Session::save)
  3. Dadurch wird eine "provisorische" Session erstellt
  4. StartSession-Middleware läuft danach und erstellt eine neue Session
  5. Resultat: Session-Daten gehen verloren, UserShop-Wechsel funktionieren nicht

Aktuelle Architektur

Request → DomainResolver → StartSession → AuthenticateSession → Controller
           ↑ Setzt Session-Daten     ↑ Erstellt neue Session
           ❌ Session-Daten verloren

Multi-Domain-Setup

  • Hauptdomain: mivita.test / mivita.care
  • Feste Subdomains:
    • in.mivita.care - Kundenbackend (Portal)
    • my.mivita.care - Beraterbackend (CRM)
    • checkout.mivita.care - Zahlungsseite
  • Dynamische Subdomains: 500+ UserShop-Domains ({berater}.mivita.care)

Session-Anforderungen

  • UserShop-Persistenz: UserShop muss beim Domain-Wechsel erhalten bleiben
  • Warenkorb-Kontinuität: Checkout-Domain benötigt vollständigen Session-Zugriff
  • Zurück-zum-Shop: Portal/CRM brauchen UserShop-Referenz

🎯 Optimierte Lösung

Neue Architektur

Request → DomainContextResolver → StartSession → DomainSessionManager → Controller
           ↑ Nur Domain-Analyse        ↑ Session Start   ↑ Session-Management
           ✅ Kein Session-Zugriff                       ✅ Sichere Session-Ops

Prinzip der Trennung

  1. DomainContextResolver (vor Session):

    • Analysiert nur Domain/Subdomain
    • Speichert Kontext im Request-Objekt
    • Konfiguriert Session-Domain für Cookies
    • Kein Session-Zugriff!
  2. DomainSessionManager (nach Session):

    • Übernimmt Session-Management
    • Setzt/erhält UserShop-Daten
    • Verwaltet Domain-spezifische Session-Logik

Vorteile

  • Keine doppelten Sessions
  • Saubere Trennung der Verantwortlichkeiten
  • Besseres Caching (Domain-Parsing vs Session-Management)
  • Einfacheres Testing
  • Performance-Verbesserung
  • Bessere Wartbarkeit

Wichtige Verbesserungen (gegenüber dem ursprünglichen Claude-Ansatz)

  • Event-Gesteuerte Echtzeit-Cache-Invalidierung: Anstatt auf den Ablauf des Caches (TTL) zu warten, wird der UserShop-Cache nun durch einen UserShopObserver sofort geleert, wenn sich relevante Daten in der Datenbank ändern (z.B. ein Shop wird deaktiviert). Das erhöht die Datenkonsistenz massiv.
  • 🧩 Strategy Pattern für Session-Management: Die Logik zur Behandlung der Session für verschiedene Domain-Typen wurde aus dem DomainSessionManager in dedizierte, austauschbare Strategie-Klassen ausgelagert. Das macht das System extrem sauber, erweiterbar (neue Domain-Typen erfordern keine Änderung am Kern) und entspricht dem Open/Closed-Prinzip.

🏗️ Implementation

1. Domain Context System

// Erweiterte DomainContext-Klasse
class DomainContext
{
    public readonly DomainType $type;
    public readonly string $host;
    public readonly ?string $subdomain;
    public readonly ?UserShop $userShop;

    // Neue Methoden für Session-Handling
    public function shouldPreserveUserShop(): bool;
    public function getSessionDomain(): string;
    public function toArray(): array;
}

// Type-Safe Enum für Domain-Typen
enum DomainType: string
{
    case MAIN = 'main';
    case SHOP = 'shop';
    case USER_SHOP = 'user-shop';
    case CRM = 'crm';
    case PORTAL = 'portal';
    case CHECKOUT = 'checkout';
    case UNKNOWN = 'unknown';
}

2. Services Layer & Session-Strategien

// Optimierter DomainService mit verbessertem Caching
class DomainService
{
    // Trennung von Domain-Parsing und UserShop-Loading
    public function parseDomain(string $host): DomainParseResult;
    public function loadUserShop(string $slug): ?UserShop;

    // Verbessertes Caching mit Echtzeit-Invalidierung
    public function clearUserShopCache(string $slug): void;
    public function warmUpCache(array $slugs): void;
}

// Refaktorisierter Session-Manager Service (nutzt Strategy Pattern)
class DomainSessionManager
{
    // Delegiert die Logik an die passende Strategie
    public function handleDomainSpecificSession(DomainContext $context, Request $request): void;
}

// NEU: Saubere, gekapselte Logik pro Domain-Typ
interface DomainSessionStrategyInterface {
    public function handle(DomainContext $context): void;
}
class UserShopSessionStrategy implements DomainSessionStrategyInterface { /* ... */ }
class CrmSessionStrategy implements DomainSessionStrategyInterface { /* ... */ }
// ... etc.

3. Middleware Stack

// 1. DomainContextResolver (vor Session)
class DomainContextResolver
{
    public function handle($request, $next) {
        // Nur Domain-Analyse, kein Session-Zugriff
        $context = $this->domainService->resolveDomain($request->getHost());
        $request->attributes->set('domain_context', $context);

        // Session-Domain für Cookies konfigurieren
        Config::set('session.domain', $context->getSessionDomain());

        return $next($request);
    }
}

// 2. DomainSessionManager (nach Session)
class DomainSessionManager
{
    public function handle($request, $next) {
        $response = $next($request);

        // Jetzt ist Session verfügbar
        $context = $request->attributes->get('domain_context');
        $this->sessionManager->handleDomainSpecificSession($context, $request);

        return $response;
    }
}

🚀 Migration Plan

Phase 1: Neue Struktur implementieren

  • Neue DomainContext mit Session-Methoden
  • DomainService refactoring
  • Neue Middleware implementieren

Phase 2: Testing

  • Unit Tests für alle Komponenten
  • Integration Tests für Session-Wechsel
  • Performance-Tests

Phase 3: Rollout

  • Neue Middleware parallel registrieren
  • Schrittweise Migration
  • Alte Middleware entfernen

Phase 4: Cleanup

  • Legacy-Code entfernen
  • Dokumentation aktualisieren

📊 Performance Verbesserungen

Caching Strategie

  1. Domain-Parsing: Caching der Domain-Analyse
  2. UserShop-Lookups: Intelligentes Caching mit Tags und sofortiger Invalidierung bei Änderungen durch einen Model-Observer.
  3. Session-State: Reduzierte Session-Zugriffe

Erwartete Verbesserungen

  • 20-30% weniger DB-Queries durch besseres Caching
  • 50% schnellere Domain-Resolution durch optimierten Parser
  • Keine Session-Konflikte mehr

📝 Implementierung Details

Siehe /src Verzeichnis für die vollständige Implementation:

  • src/Domain/ - Domain Context und Types
  • src/Services/ - Optimierte Services
  • src/Services/SessionStrategies/ - Gekapselte Session-Logik pro Domain-Typ
  • src/Middleware/ - Neue Middleware
  • src/Observers/ - Echtzeit-Cache-Invalidierung
  • src/Contracts/ - Interfaces
  • config/ - Konfiguration
  • tests/ - Comprehensive Tests

🔧 Configuration

Die Lösung ist vollständig rückwärtskompatibel mit der bestehenden config/domains.php.

📋 Testing

Umfassende Test-Suite für alle Szenarien:

  • Domain-Wechsel mit Session-Erhaltung
  • UserShop-Persistenz
  • Performance unter Last
  • Edge Cases

Entwickelt für: Mivita.care
Status: Ready for Implementation
Geschätzte Implementierungszeit: 2-3 Tage