161 lines
5.2 KiB
Markdown
161 lines
5.2 KiB
Markdown
# 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`
|