# Optimierung des Domain-Routings und Session-Handlings Dieses Dokument beschreibt eine vorgeschlagene Optimierung für die bestehende Domain-Routing- und Session-Verwaltungslogik. ## 1. Analyse der aktuellen Architektur Die Anwendung nutzt eine komplexe, aber leistungsstarke Multi-Domain-Architektur, um verschiedene Anwendungsbereiche (Hauptseite, CRM, Partner-Portal, Checkout, User-Shops) voneinander zu trennen. - **Konfiguration**: Die Domain-Struktur wird zentral in `config/domains.php` definiert. - **Service Provider (`DomainServiceProvider`)**: - Registriert den `DomainService` (zuständig für Domain-Analyse und UserShop-Logik). - Registriert den `DomainContext` als Singleton, der pro Request Informationen über die aktuelle Domain enthält (Typ, Host, Subdomain, UserShop-Objekt). - **Wichtig**: Er registriert die `DomainResolver`-Middleware und fügt sie an den _Anfang_ der `web`-Middleware-Gruppe hinzu. - **Middleware (`DomainResolver`)**: - Nutzt den `DomainContext`, um die Anfrage zu validieren. - Leitet ungültige Domains auf die Hauptdomain um. - Prüft den Status von User-Shops (aktiv, Zahlung etc.). - **Problembereich**: Schreibt `UserShop`-Daten aktiv in die Session (`Session::put`, `Session::save`). - **Routing (`RouteServiceProvider`)**: Lädt die passenden Routen-Dateien basierend auf dem `type` im `DomainContext`. ## 2. Identifiziertes Problem: Konflikte bei der Session-Erstellung Das Kernproblem liegt in der Reihenfolge, in der die Middleware ausgeführt wird. 1. Der `DomainServiceProvider` registriert die `DomainResolver`-Middleware mit `prependMiddlewareToGroup('web', ...)`. 2. Dadurch wird `DomainResolver` **vor** der Standard-Laravel-Middleware `StartSession` ausgeführt, die ebenfalls Teil der `web`-Gruppe ist. 3. Die `DomainResolver`-Middleware versucht, auf die Session zuzugreifen und sie zu modifizieren (`Session::put`, `Session::save`). Da die `StartSession`-Middleware noch nicht gelaufen ist, wird hier möglicherweise eine "provisorische" Session gestartet. 4. Anschließend läuft die `StartSession`-Middleware, die die "offizielle" Session aus dem Cookie lädt. 5. Dies kann zu einem Konflikt führen, bei dem zwei verschiedene Session-Instanzen pro Anfrage existieren oder die in `DomainResolver` gespeicherten Daten nicht in der finalen Session-Response an den Client gesendet werden. Das Resultat ist, dass der `UserShop`-Kontext beim Wechsel zwischen Domains (z.B. vom Shop zum `in.`-Portal) verloren geht. ## 3. Vorgeschlagene Lösung: Saubere Trennung und korrekte Reihenfolge Die vorgeschlagene Lösung zielt darauf ab, die Logik zu entzerren und die Middleware in der korrekten, von Laravel vorgesehenen Reihenfolge auszuführen. ### Schritt 1: Korrektur der Middleware-Reihenfolge Die `DomainResolver`-Middleware darf nicht mehr per `prependMiddlewareToGroup` im Service Provider registriert werden. Stattdessen sollte sie im `app/Http/Kernel.php` innerhalb der `web`-Gruppe **nach** der `\Illuminate\Session\Middleware\StartSession`-Middleware platziert werden. Dadurch wird sichergestellt, dass die Session immer korrekt initialisiert ist, bevor unsere anwendungsspezifische Logik darauf zugreift. ### Schritt 2: Aufteilung der Middleware-Verantwortlichkeiten Die `DomainResolver`-Middleware hat aktuell zu viele Aufgaben. Eine Aufteilung verbessert die Lesbarkeit, Wartbarkeit und Einhaltung des Single-Responsibility-Prinzips. **Vorschlag für neue Middleware-Struktur:** 1. **`InitializeDomainContext` (Neue Middleware)**: - Diese Middleware läuft sehr früh (kann global oder am Anfang der `web`-Gruppe stehen). - Ihre **einzige** Aufgabe ist es, den `DomainContext` zu initialisieren, indem sie `app(DomainContext::class)` aufruft. Sie führt **keine** Session-Operationen oder Umleitungen durch. Dies stellt sicher, dass der Kontext für alle nachfolgenden Teile der Anwendung (auch andere Middleware) verfügbar ist. 2. **`HandleDomainLogic` (Umbenannter `DomainResolver`)**: - Diese Middleware läuft **nach** `StartSession`. - Sie nutzt den bereits initialisierten `DomainContext`. - **Aufgaben**: - Umleitung bei `isUnknown()`. - Validierung des `UserShop` (aktiv, bezahlt etc.). - Persistierung des `UserShop`-Kontexts in der Session. Die Logik hierfür wird verfeinert, um den Shop-Kontext über Domain-Grenzen hinweg intelligent zu erhalten. Zum Beispiel wird der `user_shop` nicht mehr gelöscht, nur weil man die `main`-Domain besucht. Er wird nur überschrieben, wenn ein neuer Shop-Kontext explizit gesetzt wird. ### Schritt 3: Vereinfachung des Session-Handlings Die `setupLegacyContext`-Methode wird überarbeitet. Das Ziel ist ein klares und vorhersehbares Verhalten: - **Auf einer User-Shop-Domain**: Der `UserShop` wird in die Session geschrieben. - **Auf einer Nicht-Shop-Domain (`crm`, `portal`, `checkout`, `main`)**: Die Session wird **nicht angerührt**. Der bestehende `UserShop` aus der Session bleibt erhalten, sodass eine Rückkehr zum Shop jederzeit möglich ist. - **Wechsel zu einem anderen User-Shop**: Der neue `UserShop` überschreibt den alten Wert in der Session. ## 4. Vorteile der neuen Architektur - **Stabilität**: Das Session-Problem wird an der Wurzel behoben, indem die Middleware-Reihenfolge korrigiert wird. - **Klarheit**: Die Verantwortlichkeiten sind sauber getrennt. Eine Middleware für die Kontext-Initialisierung, eine für die Domain-Logik. - **Wartbarkeit**: Einfacher zu verstehen und zu erweitern. Das `TECH-DEBT` in `setupLegacyContext` wird reduziert. - **Performance**: Die Logik zur Domain-Analyse im `DomainServiceProvider` wird nur einmal ausgeführt, wenn der Kontext das erste Mal benötigt wird (lazy-loading), was beibehalten wird. Die folgenden Dateien in diesem Ordner enthalten eine beispielhafte Implementierung dieses Vorschlags.