# Document Sync mit xAI Collections - Implementierungs-Status ## ✅ Implementiert ### 1. Webhook Endpunkte - **POST** `/vmh/webhook/document/create` - **POST** `/vmh/webhook/document/update` - **POST** `/vmh/webhook/document/delete` ### 2. Event Handler (`document_sync_event_step.py`) - Queue Topics: `vmh.document.{create|update|delete}` - Redis Distributed Locking - Vollständiges Document Loading von EspoCRM ### 3. Sync Utilities (`document_sync_utils.py`) - **✅ Datei-Status Prüfung**: "Neu", "Geändert" → xAI-Sync erforderlich - **✅ Hash-basierte Change Detection**: MD5/SHA Vergleich für Updates - **✅ Related Entities Discovery**: Many-to-Many Attachments durchsuchen - **✅ Collection Requirements**: Automatische Ermittlung welche Collections nötig sind ## ⏳ In Arbeit ### 4. Preview-Generierung (`generate_thumbnail()`) **✅ Implementiert** - Bereit zum Installieren der Dependencies **Konfiguration:** - **Feld in EspoCRM**: `preview` (Attachment) - **Format**: **WebP** (bessere Kompression als PNG/JPEG) - **Größe**: **600x800px** (behält Aspect Ratio) - **Qualität**: 85% (guter Kompromiss zwischen Qualität und Dateigröße) **Unterstützte Formate:** - ✅ PDF: Erste Seite als Preview - ✅ DOCX/DOC: Konvertierung zu PDF, dann erste Seite - ✅ Images (JPG, PNG, etc.): Resize auf Preview-Größe - ❌ Andere: Kein Preview (TODO: Generic File-Icons) **Benötigte Dependencies:** ```bash # Python Packages pip install pdf2image Pillow docx2pdf # System Dependencies (Ubuntu/Debian) apt-get install poppler-utils libreoffice ``` **Installation:** ```bash cd /opt/motia-iii/bitbylaw /opt/bin/uv pip install pdf2image Pillow docx2pdf # System packages sudo apt-get update sudo apt-get install -y poppler-utils libreoffice ``` ## ❌ Noch nicht implementiert ### 5. xAI Service (`xai_service.py`) **Anforderungen:** - File Upload zu xAI (basierend auf `test_xai_collections_api.py`) - Add File zu Collections - Remove File von Collections - File Download von EspoCRM **Referenz-Code vorhanden:** - `/opt/motia-iii/bitbylaw/test_xai_collections_api.py` (630 Zeilen, alle xAI Operations getestet) **Implementierungs-Plan:** ```python class XAIService: def __init__(self, context=None): self.management_key = os.getenv('XAI_MANAGEMENT_KEY') self.api_key = os.getenv('XAI_API_KEY') self.context = context async def upload_file(self, file_content: bytes, filename: str) -> str: """Upload File zu xAI → returns file_id""" # Multipart/form-data upload # POST https://api.x.ai/v1/files pass async def add_to_collection(self, collection_id: str, file_id: str): """Add File zu Collection""" # POST https://management-api.x.ai/v1/collections/{collection_id}/documents/{file_id} pass async def remove_from_collection(self, collection_id: str, file_id: str): """Remove File von Collection""" # DELETE https://management-api.x.ai/v1/collections/{collection_id}/documents/{file_id} pass async def download_from_espocrm(self, attachment_id: str) -> bytes: """Download File von EspoCRM Attachment""" # GET https://crm.bitbylaw.com/api/v1/Attachment/file/{attachment_id} pass ``` ## 📋 Integration Checklist ### Vollständiger Upload-Flow: 1. ✅ Webhook empfangen → Event emittieren 2. ✅ Event Handler: Lock acquire 3. ✅ Document laden von EspoCRM 4. ✅ Entscheidung: Sync nötig? (Datei-Status, Hash-Check, Collections) 5. ⏳ Download File von EspoCRM 6. ⏳ Hash berechnen (MD5/SHA) 7. ⏳ Thumbnail generieren 8. ❌ Upload zu xAI (falls neu oder Hash changed) 9. ❌ Add zu Collections 10. ⏳ Update EspoCRM Metadaten (xaiFileId, xaiCollections, xaiSyncedHash, thumbnail) 11. ✅ Lock release ### Datei-Stati in EspoCRM: - **"Neu"**: Komplett neue Datei → xAI Upload + Collection Add - **"Geändert"**: File-Inhalt geändert → xAI Re-Upload + Collection Update - **"Gesynct"**: Erfolgreich gesynct, keine Änderungen - **"Fehler"**: Sync fehlgeschlagen (mit Error-Message) ### EspoCRM Custom Fields: **Erforderlich für Document Entity:** - `dateiStatus` (Enum): "Neu", "Geändert", "Gesynct", "Fehler" - `md5` (String): MD5 Hash des Files - `sha` (String): SHA Hash des Files - `xaiFileId` (String): xAI File ID - `xaiCollections` (Array): JSON Array von Collection IDs - `xaiSyncedHash` (String): Hash beim letzten erfolgreichen Sync - `xaiSyncStatus` (Enum): "syncing", "synced", "failed" - `xaiSyncError` (Text): Fehlermeldung bei Sync-Fehler - **`preview` (Attachment)**: Vorschaubild im WebP-Format (600x800px) ## 🚀 Nächste Schritte **Priorität 1: xAI Service** - Code aus `test_xai_collections_api.py` extrahieren - In `services/xai_service.py` übertragen - EspoCRM Download-Funktion implementieren **Priorität 2: Thumbnail-Generator** - Dependencies installieren - PDF-Thumbnail implementieren - EspoCRM Upload-Methode erweitern **Priorität 3: Integration testen** - Document in EspoCRM anlegen - Datei-Status auf "Neu" setzen - Webhook triggern - Logs analysieren ## 📚 Referenzen - **xAI API Tests**: `/opt/motia-iii/bitbylaw/test_xai_collections_api.py` - **EspoCRM API**: `services/espocrm.py` - **Beteiligte Sync** (Referenz-Implementierung): `steps/vmh/beteiligte_sync_event_step.py`