From 7a7a3223890e4e795b8170ce8451fc701cc91791 Mon Sep 17 00:00:00 2001 From: bitbylaw Date: Sat, 7 Feb 2026 22:29:33 +0000 Subject: [PATCH] feat: Remove redundant update filtering logic in VMH Webhook handler --- .../vmh/webhook/beteiligte_update_api_step.py | 59 ++----------------- 1 file changed, 5 insertions(+), 54 deletions(-) diff --git a/bitbylaw/steps/vmh/webhook/beteiligte_update_api_step.py b/bitbylaw/steps/vmh/webhook/beteiligte_update_api_step.py index bf285dce..c1c83764 100644 --- a/bitbylaw/steps/vmh/webhook/beteiligte_update_api_step.py +++ b/bitbylaw/steps/vmh/webhook/beteiligte_update_api_step.py @@ -1,44 +1,8 @@ import json import datetime -def should_skip_update(entity_data): - """ - Prüft ob Update gefiltert werden soll (verhindert Webhook-Loop) - - SKIP wenn: - - Nur Sync-Felder geändert UND - - syncStatus ist "clean" oder "syncing" (normale Sync-Completion) - - EMIT wenn: - - Echte Datenänderung (nicht nur Sync-Felder) ODER - - syncStatus ist "dirty", "failed", "pending_sync" (braucht Sync) - """ - if not isinstance(entity_data, dict): - return False - - # Felder die von Sync-Handler gesetzt werden - sync_fields = {'syncStatus', 'advowareLastSync', 'syncErrorMessage', 'syncRetryCount'} - # Meta-Felder die immer vorhanden sind - meta_fields = {'id', 'modifiedAt', 'modifiedById', 'modifiedByName'} - # Alle ignorierbaren Felder - ignorable = sync_fields | meta_fields - - # Prüfe ob es relevante (nicht-sync) Felder gibt - entity_keys = set(entity_data.keys()) - relevant_keys = entity_keys - ignorable - - # Wenn echte Datenänderung → Emit (nicht skippen) - if len(relevant_keys) > 0: - return False - - # Nur Sync-Felder vorhanden → Prüfe syncStatus - sync_status = entity_data.get('syncStatus') - - # Skip nur wenn Status "clean" oder "syncing" (normale Completion) - # Emit wenn "dirty", "failed", "pending_sync" (braucht Sync) - should_skip = sync_status in ['clean', 'syncing'] - - return should_skip +# HINWEIS: Loop-Prevention wurde auf EspoCRM-Seite implementiert +# rowId-Updates triggern keine Webhooks mehr, daher keine Filterung nötig config = { 'type': 'api', @@ -57,30 +21,17 @@ async def handler(req, context): context.logger.info("VMH Webhook Beteiligte Update empfangen") context.logger.info(f"Payload: {json.dumps(payload, indent=2, ensure_ascii=False)}") - # Sammle alle IDs aus dem Batch (filtere Sync-Only-Updates) + # Sammle alle IDs aus dem Batch entity_ids = set() - filtered_count = 0 if isinstance(payload, list): for entity in payload: if isinstance(entity, dict) and 'id' in entity: - # Prüfe ob Update gefiltert werden soll (verhindert Loop) - if should_skip_update(entity): - context.logger.info(f"Sync-Completion gefiltert: {entity['id']} (syncStatus={entity.get('syncStatus')})") - filtered_count += 1 - continue entity_ids.add(entity['id']) elif isinstance(payload, dict) and 'id' in payload: - if not should_skip_update(payload): - entity_ids.add(payload['id']) - else: - context.logger.info(f"Sync-Completion gefiltert: {payload['id']} (syncStatus={payload.get('syncStatus')})") - filtered_count += 1 + entity_ids.add(payload['id']) - if filtered_count > 0: - context.logger.info(f"{len(entity_ids)} IDs zum Update-Sync gefunden ({filtered_count} Sync-Completions gefiltert)") - else: - context.logger.info(f"{len(entity_ids)} IDs zum Update-Sync gefunden") + context.logger.info(f"{len(entity_ids)} IDs zum Update-Sync gefunden") # Emittiere Events direkt (Deduplizierung erfolgt im Event-Handler via Lock) for entity_id in entity_ids: