# Migration Report: Competitor Analysis Agent ## Status: Jan 09, 2026 The `competitor-analysis` application has been successfully migrated to the local Docker stack and integrated into the `gemini-gateway` (Nginx). ### 1. Vorgehen (Process) 1. **Dateistruktur:** * Erstellung des Verzeichnisses `competitor-analysis-app/`. * Kopie aller Dateien aus dem Original-Verzeichnis. 2. **Frontend-Anpassung:** * `vite.config.ts`: `base: './'` gesetzt, um korrektes Routing unter dem Sub-Pfad `/ca/` zu ermöglichen. * `geminiService.ts`: Direkte Aufrufe an `@google/genai` entfernt. Alle Funktionen nutzen nun `fetch()` an den neuen Python-Backend-Endpunkt `/api/...`. 3. **Backend-Orchestrator (Python/FastAPI):** * Erstellung von `competitor_analysis_orchestrator.py`. * Portierung aller Prompts und Schemata aus dem TypeScript-Code in Python (Pydantic & Google Generative AI SDK). * Implementierung einer robusten JSON-Parsing-Logik (`parse_json_response`), die Markdown-Blöcke entfernt und inkonsistente LLM-Antworten korrigiert. * Implementierung einer Modell-Kandidaten-Liste (`gemini-1.5-pro` mit Fallback), um regionale Verfügbarkeit sicherzustellen. * Integration von `StaticFiles`, um das fertig gebaute Frontend direkt über den Python-Server auszuliefern. 4. **Docker-Integration:** * `Dockerfile`: Multi-Stage Build (Node.js zum Bauen, Python zum Ausführen). * `docker-compose.yml`: Neuer Service `competitor-analysis` hinzugefügt, inklusive Volume-Mounts für API-Keys und Live-Debugging des Orchestrators. * `nginx-proxy.conf`: Routing für `/ca/` konfiguriert. ### 2. Next Steps * **Persistenz:** Aktuell werden Analysen nur im App-State (RAM) gehalten. Eine Anbindung an die SQLite-Datenbank (ähnlich wie beim `b2b-app`) wäre sinnvoll, um Analysen zu speichern und später wieder aufzurufen. * **Fehlermanagement:** Verfeinerung der Error-Handler im Frontend, um spezifische Backend-Fehler (z.B. API-Limits) besser anzuzeigen. * **Weitere Schritte im Orchestrator:** Implementierung der verbleibenden Steps (4-8), falls diese noch nicht vollständig in Python abgebildet sind (derzeit sind Step 1, 2, 3, 4, 5, 6, 7 und 8 bereits im Code vorbereitet oder implementiert). ### 3. Lessons Learned * **Python SDK-Versionskonflikte (`google-generativeai==0.3.0`):** Das im Projekt verwendete Python SDK (`google-generativeai` Version `0.3.0`) ist nicht mit neueren API-Schnittstellen kompatibel. * `ImportError: cannot import name 'Schema' from 'google.generativeai.types'` und `ImportError: cannot import name 'Content' from 'google.generativeai.types'` treten auf, da diese Klassen in dieser SDK-Version an diesen Importpfaden nicht existieren oder anders implementiert sind. * **Lösung:** Schemata müssen direkt als Python-Dictionaries an die `generation_config` übergeben werden. Alle Importe für `Schema` und `Content` müssen entfernt werden. * **Frontend Build (`package.json` `devDependencies`):** Build-Tools wie `vite`, `@vitejs/plugin-react` und `typescript` müssen in den `dependencies` der `package.json` stehen, nicht in `devDependencies`. Andernfalls schlägt `npm install` im Docker-Build fehl, was zu einem leeren oder fehlenden `dist`-Ordner und einem 404-Fehler des Python-Servers führt. * **Syntaxfehler in mehrzeiligen Prompts (`f-strings`):** Besonders bei älteren Python-Versionen und komplexen mehrzeiligen Prompts mit `f-strings` können subtile Fehler (z.B. falsch platzierte Anführungszeichen oder unbeabsichtigter deutscher Text in englischen Prompts) zu `SyntaxError: unterminated string literal` führen. * **Lösung:** Die robusteste Methode ist, mehrzeilige Prompts als Liste von Strings zu definieren und mit `"\n".join()` zusammenzufügen. * **SDK-Unterschiede:** Das Python SDK (`google-generativeai`) verhält sich bei der Schema-Validierung strikter als die JS-Variante. Prompts mussten leicht angepasst werden, um sicherzustellen, dass die AI wirklich valides JSON liefert. * **Vite Base Path:** Ohne `base: './'` in `vite.config.ts` schlagen alle Asset-Requests fehl, wenn die App hinter einem Proxy unter `/ca/` läuft. * **Double JSON Trap:** LLMs neigen dazu, JSON in Markdown zu packen. Der Backend-Orchestrator muss dies proaktiv bereinigen, bevor `json.loads()` aufgerufen wird. * **Proxy-Routing:** Der Trailing Slash in Nginx (`proxy_pass http://.../`) ist kritisch, damit die Pfade innerhalb der App korrekt aufgelöst werden. --- *Dokumentation erstellt am 09.01.2026*