This commit is contained in:
team 1
2026-04-15 10:49:21 +02:00
parent 21b60b8542
commit 51bc781826
5 changed files with 1374 additions and 975 deletions

View File

@@ -1,42 +1,84 @@
# RAG-System Enterprise Installationsanleitung
# RetrieX Installationsanleitung
Stand: Februar 2026
Architektur: Symfony (PHP 8.2+) + MariaDB 10.11 + Python Vector Service (FAISS) + Ollama LLM
Betriebsmodus: On-Prem / Containerfähig / CPU-basiert
Stand: 15.04.2026
Quelle: aktuelle `rag.zip` (Single Source of Truth)
Diese Anleitung beschreibt eine vollständige Neuinstallation auf sauberer Infrastruktur.
Diese Anleitung beschreibt die **codebasierte Neuinstallation** des aktuellen Systems. Sie ersetzt ältere Installationsstände. Alle Angaben unten wurden an den tatsächlich vorhandenen Dateien, Services, Commands und Pfaden aus dem ZIP ausgerichtet.
---
# 1. Systemvoraussetzungen
## 1. Architektur des aktuellen Stands
## 1.1 Betriebssystem
RetrieX besteht aktuell aus diesen Hauptbausteinen:
- **Symfony 7.4** auf **PHP 8.2+**
- **Doctrine ORM + Doctrine Migrations**
- **MariaDB/MySQL** als operative Datenbank
- **Python-Vektorlayer** mit `faiss-cpu`, `sentence-transformers`, `fastapi`, `uvicorn`
- **Ollama-kompatibler LLM-Endpunkt** über `AI_LLM_API_URL`
- **NDJSON + FAISS** im Dateisystem unter `var/knowledge`
- **Adminoberfläche** für Dokumente, Ingest-Profile, System Prompt, Modellkonfiguration und Jobs
- **SSE-Streaming** für den Browser-Chat
Wichtige Betriebsordner im aktuellen Code:
- `var/knowledge/` → NDJSON, FAISS-Indizes, Uploads
- `var/log/` → System-, Agent- und Ingest-Logs
- `var/run/` → PID-Dateien des Python-Services
- `var/locks/` → Ingest-Lock
- `python/vector/` → Python-Control-, Search- und Service-Skripte
---
## 2. Wichtige Korrekturen gegenüber älteren Installationsständen
Die frühere `INSTALL.md` passt nicht mehr zum aktuellen Code. Für den aktuellen Stand gelten insbesondere diese Punkte:
- Der Wissensspeicher liegt unter **`var/knowledge/`**, nicht unter `var/vector/`.
- Der Python-Code liegt unter **`python/vector/`**, nicht unter `vector/`.
- Die Python-Abhängigkeiten kommen aus der Datei **`requirements.txt` im Projektroot**.
- Der korrekte Rebuild-Befehl ist **`mto:agent:system:rebuild --hard`**, nicht `mto:agent:ingest:global`.
- Das LLM-Modell kommt **nicht** mehr aus einer `AI_LLM_MODEL`-Umgebungsvariable, sondern aus der **aktiven ModelGenerationConfig** in der Adminoberfläche.
- Für den Chat sind **zwingend** nötig:
- ein **aktiver System Prompt**
- eine **aktive ModelGenerationConfig**
- mindestens ein erfolgreich indexiertes Dokument für wissensbasiertes Retrieval
- Die Upload-UI erwähnt mehrere Dateitypen, der aktuelle Extractor-Code unterstützt jedoch **faktisch nur PDF**.
---
## 3. Systemvoraussetzungen
## 3.1 Betriebssystem
Empfohlen:
- Ubuntu 22.04 LTS (Server)
Alternativ:
- Debian 12
- macOS (Entwicklung)
- Windows nur via WSL2
- Ubuntu 22.04 LTS oder neuer
- Debian 12 ist ebenfalls passend
Für lokale Entwicklung sind auch macOS oder Linux-Container-Setups möglich.
---
## 1.2 PHP
## 3.2 PHP
Version:
- PHP 8.2 oder höher
Erforderlich:
Erforderliche Extensions:
- pdo
- pdo_mysql
- mbstring
- intl
- curl
- json
- zip
- **PHP 8.2 oder höher**
Prüfung:
Benötigte bzw. praktisch notwendige Extensions aus dem aktuellen Projektstand:
- `ctype`
- `curl`
- `dom`
- `iconv`
- `libxml`
- `pdo`
- `pdo_mysql`
- `mbstring`
- `zip`
Prüfen:
```bash
php -v
@@ -45,32 +87,33 @@ php -m
---
## 1.3 Composer
## 3.3 Composer
Prüfen:
```bash
composer --version
```
Falls nicht vorhanden:
```bash
sudo apt install composer
```
Falls Composer nicht global vorhanden ist, kann lokal installiert werden. Für den regulären Betrieb ist ein globaler Composer aber sinnvoll.
---
## 1.4 Datenbank
## 3.4 Datenbank
Version:
- MariaDB 10.11.x (entspricht aktueller ENV)
Der aktuelle Projektstand ist praktisch auf **MariaDB/MySQL** ausgerichtet.
Installation:
Empfohlen:
- **MariaDB 10.11.x**
Beispielinstallation:
```bash
sudo apt install mariadb-server
```
Datenbank und Benutzer anlegen:
Beispiel für Datenbank und Benutzer:
```sql
CREATE DATABASE db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
@@ -79,12 +122,18 @@ GRANT ALL PRIVILEGES ON db.* TO 'db'@'%';
FLUSH PRIVILEGES;
```
Hinweis:
Die mitgelieferte `.env` enthält derzeit noch eine PostgreSQL-Placeholder-URL. Für den realen Betrieb muss `DATABASE_URL` auf **MariaDB/MySQL** gesetzt werden.
---
## 1.5 Python
## 3.5 Python
Version:
- Python 3.10 oder höher
Erforderlich:
- **Python 3.10 oder höher**
- `python3-venv`
- `python3-pip`
Installation:
@@ -100,49 +149,63 @@ python3 --version
---
## 1.6 Ollama (LLM Backend)
## 3.6 Ollama oder kompatibler Generate-Endpunkt
Installation:
RetrieX spricht den LLM-Endpunkt über `AI_LLM_API_URL` an. Erwartet wird ein **Ollama-kompatibler `/api/generate`-Endpoint**.
Beispiel mit Ollama:
```bash
curl -fsSL https://ollama.com/install.sh | sh
```
Modell bereitstellen:
Ein Modell muss lokal vorhanden sein, zum Beispiel:
```bash
ollama pull qwen3
oder
ollama pull mto-model (Wenn eigens KI-Model erstellt wurde)
```
oder ein projektspezifisches Modell, falls vorhanden.
Verfügbarkeit prüfen:
```bash
curl http://127.0.0.1:11434/api/tags
```
---
# 2. Projektbereitstellung
## 2.1 Entpacken
```bash
unzip rag.zip
cd rag
```
oder via Git:
```bash
git clone <repository>
cd <repository>
```
Wichtig:
Welches Modell tatsächlich benutzt wird, bestimmt später die **aktive ModelGenerationConfig im Admin**, nicht eine `.env`-Variable.
---
## 2.2 PHP-Abhängigkeiten installieren
## 3.7 Optional: Shopware Store API
Der Commerce-Pfad ist im aktuellen Code **standardmäßig aktiviert**. Für produktbezogene Anfragen nutzt das System optional die Shopware Store API.
Dafür werden diese Variablen verwendet:
- `SHOPWARE_STORE_API_BASE_URL`
- `SHOPWARE_SALES_CHANNEL_ACCESS_KEY`
- `SHOPWARE_STORE_API_MAX_RESULT`
Wenn keine Shopware-Suche gewünscht ist, sollte der Commerce-Pfad vor produktivem Einsatz bewusst deaktiviert oder sauber konfiguriert werden.
---
## 4. Projekt bereitstellen
ZIP entpacken und ins Projekt wechseln:
```bash
unzip rag.zip -d retriex
cd retriex
```
Alternativ über Repository-Checkout, falls das Projekt aus Git bereitgestellt wird.
---
## 5. PHP-Abhängigkeiten installieren
```bash
composer install --no-interaction
@@ -151,121 +214,91 @@ composer install --no-interaction
Für Produktion:
```bash
composer install --no-dev --optimize-autoloader
composer install --no-dev --optimize-autoloader --no-interaction
```
Erst nach diesem Schritt funktionieren `bin/console` und die Symfony-Commands.
---
# 3. Environment-Konfiguration
## 6. Umgebung konfigurieren
Datei `.env` im Projektroot konfigurieren.
## 6.1 Grundregel
## 3.1 Symfony Core
Lokale oder serverbezogene Overrides sollten in **`.env.local`** gepflegt werden, nicht direkt in der committeten `.env`.
```env
APP_ENV=dev
APP_SECRET=09333662211af45850ff13d68a40f8e3
```
---
Produktion:
## 6.2 Minimale `.env.local`
Beispiel für einen lokalen oder servernahen MariaDB-Betrieb:
```env
APP_ENV=prod
```
APP_SECRET=change-me
---
DATABASE_URL="mysql://db:db@127.0.0.1:3306/db?serverVersion=10.11.0-mariadb&charset=utf8mb4"
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
## 3.2 AI Agent Core
```env
AI_LLM_API_URL=http://host.docker.internal:11434/api/generate
AI_LLM_MODEL=mto-model
AI_LLM_API_URL=http://127.0.0.1:11434/api/generate
AI_LLM_TIMEOUT=600
AI_HISTORY_DIR=var/agent-history
AI_CONTEXT_LINES=20
AI_CONTEXT_LINES_FULL=500
```
Hinweise:
- Timeout unter 600 Sekunden wird nicht empfohlen.
- API-URL an Infrastruktur anpassen (Docker vs. Localhost).
---
## 3.3 Debug-Konfiguration
```env
AI_DEBUG=false
AI_LOG_PROMPT=false
AI_LOG_CONTEXT=false
SHOPWARE_STORE_API_BASE_URL="https://example.invalid"
SHOPWARE_SALES_CHANNEL_ACCESS_KEY="replace-me"
SHOPWARE_STORE_API_MAX_RESULT=25
```
In Entwicklungsumgebung optional aktivieren.
Hinweise:
- `APP_ENV=prod` ist im aktuellen `.env` bereits voreingestellt.
- `DATABASE_URL` muss auf MariaDB/MySQL zeigen.
- `AI_LLM_API_URL` muss auf einen funktionierenden `/api/generate`-Endpoint zeigen.
- `AI_LLM_TIMEOUT=600` ist mit dem aktuellen Code konsistent.
- `AI_LLM_MODEL` wird **nicht** verwendet.
---
## 3.4 Datenbank (aktive Konfiguration)
## 6.3 Shopware deaktivieren, wenn nicht benötigt
Nur diese DATABASE_URL verwenden:
Im aktuellen Code ist `mto.commerce.enabled` in `config/services.yaml` auf `true` gesetzt. Wer die Shopware-Suche nicht einsetzen will, sollte vor produktivem Einsatz bewusst einen dieser Wege wählen:
```env
DATABASE_URL="mysql://db:db@db:3306/db?sslmode=disable&charset=utf8mb4&serverVersion=10.11.0-mariadb"
DATABASE_VERSION="10.11.0-mariadb"
DATABASE_DRIVER="mysql"
DATABASE_HOST="db"
DATABASE_PORT="3306"
DATABASE_USER="db"
DATABASE_PASSWORD="db"
DATABASE_NAME="db"
DATABASE_SERVER="mysql://db:3306"
```
1. gültige Shopware-Zugangsdaten hinterlegen, oder
2. `config/services.yaml` gezielt anpassen und Commerce deaktivieren.
Wichtig:
- PostgreSQL-Konfiguration entfernen.
- Nur eine DATABASE_URL definieren.
Für reine Wissens- und Dokumentinstallation ist die Shopware-Anbindung nicht zwingend, sollte aber nicht unklar halbkonfiguriert bleiben.
---
## 3.5 Messenger
## 7. Datenbank initialisieren
```env
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
```
Queue läuft über Datenbank.
---
## 3.6 Mailer (optional)
```env
MAILER_DSN="smtp://127.0.0.1:1025"
MAILER_HOST="127.0.0.1"
MAILER_PORT="1025"
MAILER_DRIVER="smtp"
MAILER_AUTH_MODE=""
MAILER_USERNAME=""
MAILER_PASSWORD=""
MAILER_CATCHER="1"
MAILER_WEB_URL="https://rag.ddev.site:8026"
```
Nur relevant wenn Mailfunktionen aktiv genutzt werden.
---
# 4. Datenbankmigration
Migrationen ausführen:
```bash
php bin/console doctrine:migrations:migrate --no-interaction
```
Damit werden unter anderem diese zentralen Tabellen angelegt:
- `user`
- `document`
- `document_version`
- `ingest_job`
- `system_prompt`
- `ingest_profile`
- `model_generation_config`
- `knowledge_tag`
- `document_tag`
- `tag_rebuild_job`
---
# 5. Python Vector Service
## 8. Python-Umgebung aufbauen
## 5.1 Virtual Environment anlegen
## 8.1 Virtuelle Umgebung anlegen
```bash
python3 -m venv .venv
@@ -274,25 +307,29 @@ source .venv/bin/activate
---
## 5.2 Abhängigkeiten installieren
## 8.2 Python-Abhängigkeiten installieren
Automatisiert:
Manuell:
```bash
pip install --upgrade pip
pip install -r requirements.txt
```
Alternativ nach angelegter `.venv` über den Symfony-Wrapper:
```bash
php bin/console mto:agent:vector:control --install
```
Alternativ manuell:
```bash
pip install fastapi uvicorn sentence-transformers faiss-cpu numpy
```
CPU-Version von FAISS ist ausreichend.
Wichtig:
Der Wrapper erwartet bereits eine existierende `.venv`. Er erzeugt sie **nicht** selbst.
---
## 5.3 Vector Service starten
## 9. Vector Service starten
Start:
```bash
php bin/console mto:agent:vector:control --start
@@ -304,99 +341,329 @@ Status prüfen:
php bin/console mto:agent:vector:control --status
```
---
# 6. Initialer Reindex
Vor produktiver Nutzung zwingend erforderlich:
Optionaler Reload:
```bash
php bin/console mto:agent:ingest:global
php bin/console mto:agent:vector:control --reload
```
Ohne Reindex ist kein Retrieval möglich.
Der Service startet aktuell standardmäßig auf:
- Host: `0.0.0.0`
- Port: `8090`
Der PHP-Code spricht standardmäßig gegen:
- `http://127.0.0.1:8090`
---
# 7. Anwendung starten
## 10. Admin-Benutzer anlegen
Entwicklung:
Ohne Admin-Benutzer lässt sich das System nicht fertig konfigurieren.
CLI-Befehl:
```bash
php bin/console mto:agent:user:create
```
Der Command fragt interaktiv ab:
- E-Mail
- Passwort
- Rolle
Für die Erstinstallation ist typischerweise sinnvoll:
- `ROLE_SUPER_ADMIN`
---
## 11. Anwendung starten
Für einen einfachen lokalen Test:
```bash
php -S 127.0.0.1:8000 -t public
```
Produktion:
- Über Nginx oder Apache bereitstellen
- APP_ENV=prod setzen
- Cache warmup durchführen
Danach sind typischerweise relevant:
- Chat-Frontend: `http://127.0.0.1:8000/`
- Admin-Login: `http://127.0.0.1:8000/admin/login`
Für Produktion sollte stattdessen ein regulärer Webserver genutzt werden, zum Beispiel Nginx + PHP-FPM.
---
## 12. Pflicht-Initialisierung im Admin
Nach der technischen Grundinstallation ist das System **noch nicht vollständig betriebsbereit**. Es müssen im Admin zwingend Inhalte angelegt werden.
## 12.1 System Prompt anlegen und aktivieren
Pfad im Admin:
- `/admin/system/prompt`
Ohne aktiven System Prompt wirft der PromptBuilder zur Laufzeit einen Fehler.
---
## 12.2 ModelGenerationConfig anlegen und aktivieren
Pfad im Admin:
- `/admin/model-config/`
Ohne aktive ModelGenerationConfig schlägt das Retrieval fehl, weil `NdjsonHybridRetriever` explizit eine aktive Konfiguration verlangt.
Sinnvolle Minimalwerte für einen stabilen Start:
- Modellname: exakt wie im Ollama-Endpunkt verfügbar, z. B. `qwen3:latest`
- Streaming: aktiv
- Temperature: `0.2` bis `0.4`
- Top K: `40`
- Top P: `0.9`
- Repeat Penalty: `1.1`
- num_ctx: `8192`
- Retrieval Max Chunks: `25`
- Retrieval Vector Top K: `25`
---
## 12.3 Optional: Ingest-Profil anlegen
Pfad im Admin:
- `/admin/ingest-profiles/`
Wenn kein Profil aktiv ist, fällt das System auf die Parameter aus `config/services.yaml` zurück:
- Chunk Size: `800`
- Chunk Overlap: `100`
- Embedding Model: `intfloat/multilingual-e5-base`
- Embedding Dimension: `768`
- Scoring Version: `1`
Das ist für einen ersten Start ausreichend. Ein eigenes Ingest-Profil ist also **optional**, solange man die Fallback-Werte bewusst akzeptiert.
---
## 13. Erste Dokumente ingestieren
## 13.1 Wichtiger Format-Hinweis
Die Upload-Maske nennt mehrere Formate, aber der aktuelle Extractor-Code enthält nur einen **`PdfExtractor`**. Für einen sicheren Erstbetrieb sollten daher aktuell **nur PDF-Dateien** hochgeladen werden.
---
## 13.2 Erstes Dokument hochladen
Pfad im Admin:
- `/admin/documents/new`
Beim Upload passiert im aktuellen Code folgendes:
1. Datei wird nach `var/knowledge/uploads` verschoben.
2. Dokument und Version 1 werden in der DB angelegt.
3. Die neue Version wird aktiv gesetzt.
4. Ein Ingest-Job vom Typ `DOCUMENT_VERSION_ACTIVATE` wird erstellt.
5. Der Job wird **asynchron per `exec()`** gestartet.
---
## 13.3 Wenn `exec()` deaktiviert ist
Der Admin-Flow für Upload, Aktivierung und Löschen setzt im aktuellen Code Hintergrundstarts über `exec()` voraus.
Ist `exec()` serverseitig deaktiviert, werden Jobs zwar angelegt, aber nicht automatisch ausgeführt. In diesem Fall muss der Job manuell gestartet werden:
```bash
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod
php bin/console mto:agent:ingest:run <jobId>
```
Die `jobId` ist in der Job-Ansicht im Admin nachvollziehbar.
---
## 14. Rebuild und Konsistenzprüfung
## 14.1 Vollständiger System-Rebuild
Sobald aktive Dokumente vorhanden sind, kann ein vollständiger Rebuild ausgeführt werden:
```bash
php bin/console mto:agent:system:rebuild --hard
```
Dieser Ablauf umfasst aktuell:
1. globalen Reindex der aktiven Dokumente
2. Tag-Export und Tag-Index-Rebuild
3. Reload des Vector Service
4. Health-Checks
Wichtig:
Der Befehl bricht absichtlich ab, wenn **keine aktiven Dokumente** vorhanden sind.
---
## 14.2 Vector Health prüfen
```bash
php bin/console mto:agent:vector:health
```
Mögliche gesunde Zustände:
- `OK_EMPTY` → noch keine Wissensdaten vorhanden
- `OK` → NDJSON und FAISS konsistent
---
## 14.3 Tag Health prüfen
```bash
php bin/console mto:agent:tag:health
```
---
# 8. Funktionstest
## 15. Wichtige Commands im aktuellen Stand
1. Datenbank erreichbar
2. Migration erfolgreich
3. Vector Service aktiv
4. Ollama erreichbar
5. Global Reindex durchgeführt
6. Dokument hochgeladen
7. Version aktiviert
8. Chat liefert Antwort
---
# 9. Betriebsrelevante Hinweise
## Modellwechsel
Bei Änderung von:
- AI_LLM_MODEL
Kein Reindex erforderlich.
Bei Änderung von:
- Embedding-Modell (Python-Seite)
- Embedding-Dimension
- Chunking-Parametern
Global Reindex zwingend erforderlich.
---
## NDJSON und Vector Index
Speicherort:
```
var/vector/
```bash
php bin/console mto:agent:user:create
php bin/console mto:agent:vector:control --install
php bin/console mto:agent:vector:control --start
php bin/console mto:agent:vector:control --status
php bin/console mto:agent:vector:control --reload
php bin/console mto:agent:vector:rebuild
php bin/console mto:agent:vector:health
php bin/console mto:agent:ingest:run <jobId>
php bin/console mto:agent:ingest:version <versionId> <userId>
php bin/console mto:agent:system:rebuild --hard
php bin/console mto:agent:tags:export
php bin/console mto:agent:tags:rebuild
php bin/console mto:agent:tag:health
php bin/console mto:agent:chat
php bin/console mto:agent:test:shop-search "deine Anfrage"
```
Nicht manuell verändern.
Index ist deterministisch und wird vollständig neu aufgebaut.
---
## 16. Minimaler Go-Live-Check
Eine Installation ist im aktuellen Stand erst dann wirklich lauffähig, wenn alle folgenden Punkte erfüllt sind:
- Composer-Abhängigkeiten installiert
- Datenbankmigrationen erfolgreich durchgelaufen
- `.env.local` korrekt gesetzt
- `.venv` vorhanden und Python-Abhängigkeiten installiert
- Vector Service läuft auf Port `8090`
- Admin-Benutzer existiert
- aktiver System Prompt vorhanden
- aktive ModelGenerationConfig vorhanden
- mindestens ein PDF erfolgreich ingestiert
- `mto:agent:vector:health` liefert `OK` oder `OK_EMPTY`
- Chat-Frontend und Admin-Login sind erreichbar
---
## Produktionsbetrieb
## 17. Häufige Fehlerbilder
Empfohlen:
- Reverse Proxy (Nginx)
- Systemd Service für Vector Service
- Eigener Service für Ollama
- Backup von Datenbank + var/vector/
## 17.1 `No active system prompt configured.`
Ursache:
Es existiert kein aktiver System Prompt.
Lösung:
Im Admin unter `/admin/system/prompt` eine Version speichern und aktivieren.
---
# Installation abgeschlossen
## 17.2 `No active ModelGenerationConfig found.`
Das System ist betriebsbereit für:
Ursache:
Es existiert keine aktive Modellkonfiguration.
- Versionierte Dokumentverwaltung
- Deterministischen NDJSON-Ingest
- FAISS-Vektorindex
- Hybrid Retrieval
- LLM-gestützte Antwortgenerierung
Lösung:
Im Admin unter `/admin/model-config/` eine Konfiguration anlegen und aktivieren.
---
## 17.3 Vector Service startet nicht
Typische Ursachen:
- `.venv` fehlt
- Python-Pakete fehlen
- Port `8090` ist schon belegt
- `uvicorn` ist nicht in der virtuellen Umgebung installiert
Prüfen:
```bash
php bin/console mto:agent:vector:control --status
```
---
## 17.4 Rebuild bricht mit „no active documents found“ ab
Ursache:
Es wurde noch kein aktives Dokument erfolgreich angelegt.
Lösung:
Zuerst ein PDF hochladen und ingestieren, danach den Rebuild erneut starten.
---
## 17.5 Upload klappt, Ingest startet aber nicht
Ursache:
`exec()` ist auf dem Server deaktiviert.
Lösung:
Job manuell mit `mto:agent:ingest:run <jobId>` starten oder Serverkonfiguration anpassen.
---
## 17.6 Dokument-Ingest schlägt bei Nicht-PDF fehl
Ursache:
Der aktuelle Code enthält nur einen `PdfExtractor`.
Lösung:
Für den aktuellen Stand ausschließlich PDFs ingestieren oder Extractor-Layer erweitern.
---
## 18. Empfohlene Produktionshinweise
Für stabilen produktiven Betrieb sind sinnvoll:
- Nginx oder Apache vor Symfony/PHP-FPM
- eigener Service-Start für den Python-Vector-Service
- eigener Service für Ollama
- Backup von Datenbank und `var/knowledge/`
- Monitoring der Logs unter `var/log/`
- bewusstes Governance-Handling für Ingest-Profile, System Prompts und Model-Konfigurationen
---
## 19. Ergebnis
Nach erfolgreicher Installation bietet der aktuelle Stand von RetrieX:
- dokumentenbasierte Wissensverwaltung
- versionierte Dokumente
- asynchronen Ingest über Jobs
- NDJSON als Wissensspeicher
- FAISS-basiertes Retrieval
- optionales Tag-Routing
- optionalen Shopware-Commerce-Pfad
- browserbasierten SSE-Chat
- Symfony-Adminoberfläche für Betrieb und Governance