Refactor and enhance logging in webhook handlers and Redis client

- Translated comments and docstrings from German to English for better clarity.
- Improved logging consistency across various webhook handlers for create, delete, and update operations.
- Centralized logging functionality by utilizing a dedicated logger utility.
- Added new enums for file and XAI sync statuses in models.
- Updated Redis client factory to use a centralized logger and improved error handling.
- Enhanced API responses to include more descriptive messages and status codes.
This commit is contained in:
bsiggel
2026-03-08 21:50:34 +00:00
parent f392ec0f06
commit a0cf845877
17 changed files with 300 additions and 276 deletions

View File

@@ -1,24 +1,29 @@
"""
Advoware Service Wrapper
Erweitert AdvowareAPI mit höheren Operations
Extends AdvowareAPI with higher-level operations for business logic.
"""
import logging
from typing import Dict, Any, Optional
from services.advoware import AdvowareAPI
logger = logging.getLogger(__name__)
from services.logging_utils import get_service_logger
class AdvowareService:
"""
Service-Layer für Advoware Operations
Verwendet AdvowareAPI für API-Calls
Service layer for Advoware operations.
Uses AdvowareAPI for API calls.
"""
def __init__(self, context=None):
self.api = AdvowareAPI(context)
self.context = context
self.logger = get_service_logger('advoware_service', context)
def _log(self, message: str, level: str = 'info') -> None:
"""Internal logging helper"""
log_func = getattr(self.logger, level, self.logger.info)
log_func(message)
async def api_call(self, *args, **kwargs):
"""Delegate api_call to underlying AdvowareAPI"""
@@ -26,29 +31,29 @@ class AdvowareService:
# ========== BETEILIGTE ==========
async def get_beteiligter(self, betnr: int) -> Optional[Dict]:
async def get_beteiligter(self, betnr: int) -> Optional[Dict[str, Any]]:
"""
Lädt Beteiligten mit allen Daten
Load Beteiligte with all data.
Returns:
Beteiligte-Objekt
Beteiligte object or None
"""
try:
endpoint = f"api/v1/advonet/Beteiligte/{betnr}"
result = await self.api.api_call(endpoint, method='GET')
return result
except Exception as e:
logger.error(f"[ADVO] Fehler beim Laden von Beteiligte {betnr}: {e}", exc_info=True)
self._log(f"[ADVO] Error loading Beteiligte {betnr}: {e}", level='error')
return None
# ========== KOMMUNIKATION ==========
async def create_kommunikation(self, betnr: int, data: Dict[str, Any]) -> Optional[Dict]:
async def create_kommunikation(self, betnr: int, data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
"""
Erstellt neue Kommunikation
Create new Kommunikation.
Args:
betnr: Beteiligten-Nummer
betnr: Beteiligte number
data: {
'tlf': str, # Required
'bemerkung': str, # Optional
@@ -57,68 +62,68 @@ class AdvowareService:
}
Returns:
Neue Kommunikation mit 'id'
New Kommunikation with 'id' or None
"""
try:
endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen"
result = await self.api.api_call(endpoint, method='POST', json_data=data)
if result:
logger.info(f"[ADVO] ✅ Created Kommunikation: betnr={betnr}, kommKz={data.get('kommKz')}")
self._log(f"[ADVO] ✅ Created Kommunikation: betnr={betnr}, kommKz={data.get('kommKz')}")
return result
except Exception as e:
logger.error(f"[ADVO] Fehler beim Erstellen von Kommunikation: {e}", exc_info=True)
self._log(f"[ADVO] Error creating Kommunikation: {e}", level='error')
return None
async def update_kommunikation(self, betnr: int, komm_id: int, data: Dict[str, Any]) -> bool:
"""
Aktualisiert bestehende Kommunikation
Update existing Kommunikation.
Args:
betnr: Beteiligten-Nummer
komm_id: Kommunikation-ID
betnr: Beteiligte number
komm_id: Kommunikation ID
data: {
'tlf': str, # Optional
'bemerkung': str, # Optional
'online': bool # Optional
}
NOTE: kommKz ist READ-ONLY und kann nicht geändert werden
NOTE: kommKz is READ-ONLY and cannot be changed
Returns:
True wenn erfolgreich
True if successful
"""
try:
endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen/{komm_id}"
await self.api.api_call(endpoint, method='PUT', json_data=data)
logger.info(f"[ADVO] ✅ Updated Kommunikation: betnr={betnr}, komm_id={komm_id}")
self._log(f"[ADVO] ✅ Updated Kommunikation: betnr={betnr}, komm_id={komm_id}")
return True
except Exception as e:
logger.error(f"[ADVO] Fehler beim Update von Kommunikation: {e}", exc_info=True)
self._log(f"[ADVO] Error updating Kommunikation: {e}", level='error')
return False
async def delete_kommunikation(self, betnr: int, komm_id: int) -> bool:
"""
Löscht Kommunikation (aktuell 403 Forbidden)
Delete Kommunikation (currently returns 403 Forbidden).
NOTE: DELETE ist in Advoware API deaktiviert
Verwende stattdessen: Leere Slots mit empty_slot_marker
NOTE: DELETE is disabled in Advoware API.
Use empty slots with empty_slot_marker instead.
Returns:
True wenn erfolgreich
True if successful
"""
try:
endpoint = f"api/v1/advonet/Beteiligte/{betnr}/Kommunikationen/{komm_id}"
await self.api.api_call(endpoint, method='DELETE')
logger.info(f"[ADVO] ✅ Deleted Kommunikation: betnr={betnr}, komm_id={komm_id}")
self._log(f"[ADVO] ✅ Deleted Kommunikation: betnr={betnr}, komm_id={komm_id}")
return True
except Exception as e:
# Expected: 403 Forbidden
logger.warning(f"[ADVO] DELETE not allowed (expected): {e}")
self._log(f"[ADVO] DELETE not allowed (expected): {e}", level='warning')
return False