feat: Implement AI Knowledge Sync Utilities and Event Handlers
- Added AIKnowledgeActivationStatus and AIKnowledgeSyncStatus enums to models.py for managing activation and sync states. - Introduced AIKnowledgeSync class in aiknowledge_sync_utils.py for synchronizing CAIKnowledge entities with XAI Collections, including collection lifecycle management, document synchronization, and metadata updates. - Created a daily cron job (aiknowledge_full_sync_cron_step.py) to perform a full sync of CAIKnowledge entities. - Developed an event handler (aiknowledge_sync_event_step.py) to synchronize CAIKnowledge entities with XAI Collections triggered by webhooks and cron jobs. - Implemented a webhook handler (aiknowledge_update_api_step.py) to receive updates from EspoCRM for CAIKnowledge entities and enqueue sync events. - Enhanced xai_service.py with methods for collection management, document listing, and metadata updates.
This commit is contained in:
@@ -473,3 +473,70 @@ class EspoCRMAPI:
|
||||
except aiohttp.ClientError as e:
|
||||
self._log(f"Download failed: {e}", level='error')
|
||||
raise EspoCRMError(f"Download request failed: {e}") from e
|
||||
|
||||
# ========== Junction Table Operations ==========
|
||||
|
||||
async def get_junction_entries(
|
||||
self,
|
||||
junction_entity: str,
|
||||
filter_field: str,
|
||||
filter_value: str,
|
||||
max_size: int = 1000
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
Load junction table entries with filtering.
|
||||
|
||||
Args:
|
||||
junction_entity: Junction entity name (e.g., 'CAIKnowledgeCDokumente')
|
||||
filter_field: Field to filter on (e.g., 'cAIKnowledgeId')
|
||||
filter_value: Value to match
|
||||
max_size: Maximum entries to return
|
||||
|
||||
Returns:
|
||||
List of junction records with ALL additionalColumns
|
||||
|
||||
Example:
|
||||
entries = await espocrm.get_junction_entries(
|
||||
'CAIKnowledgeCDokumente',
|
||||
'cAIKnowledgeId',
|
||||
'kb-123'
|
||||
)
|
||||
"""
|
||||
self._log(f"Loading junction entries: {junction_entity} where {filter_field}={filter_value}")
|
||||
|
||||
result = await self.list_entities(
|
||||
junction_entity,
|
||||
where=[{
|
||||
'type': 'equals',
|
||||
'attribute': filter_field,
|
||||
'value': filter_value
|
||||
}],
|
||||
max_size=max_size
|
||||
)
|
||||
|
||||
entries = result.get('list', [])
|
||||
self._log(f"✅ Loaded {len(entries)} junction entries")
|
||||
return entries
|
||||
|
||||
async def update_junction_entry(
|
||||
self,
|
||||
junction_entity: str,
|
||||
junction_id: str,
|
||||
fields: Dict[str, Any]
|
||||
) -> None:
|
||||
"""
|
||||
Update junction table entry.
|
||||
|
||||
Args:
|
||||
junction_entity: Junction entity name
|
||||
junction_id: Junction entry ID
|
||||
fields: Fields to update
|
||||
|
||||
Example:
|
||||
await espocrm.update_junction_entry(
|
||||
'CAIKnowledgeCDokumente',
|
||||
'jct-123',
|
||||
{'syncstatus': 'synced', 'lastSync': '2026-03-11T20:00:00Z'}
|
||||
)
|
||||
"""
|
||||
await self.update_entity(junction_entity, junction_id, fields)
|
||||
|
||||
Reference in New Issue
Block a user