""" Error Summary Value Object - Zusammenfassung von Fehlerinformationen """ from dataclasses import dataclass from datetime import datetime from typing import List, Dict, Any @dataclass(frozen=True) class ErrorSummary: """ Zusammenfassung von Fehlerinformationen für Berichte und Analysen. Frozen dataclass macht es unveränderlich (Value Object). """ error_type: str error_count: int first_occurrence: datetime last_occurrence: datetime affected_sessions: List[str] affected_accounts: List[str] # Statistiken avg_recovery_time: float # in Sekunden recovery_success_rate: float # 0.0 - 1.0 # Häufigste Kontexte most_common_urls: List[str] most_common_actions: List[str] most_common_steps: List[str] # Impact total_user_impact: int total_system_impact: int data_loss_incidents: int def __post_init__(self): """Validierung der Summary-Daten""" if self.error_count < 0: raise ValueError("Error count kann nicht negativ sein") if not 0.0 <= self.recovery_success_rate <= 1.0: raise ValueError("Recovery success rate muss zwischen 0.0 und 1.0 liegen") if self.first_occurrence > self.last_occurrence: raise ValueError("First occurrence kann nicht nach last occurrence liegen") @property def duration(self) -> float: """Zeitspanne zwischen erstem und letztem Auftreten in Stunden""" delta = self.last_occurrence - self.first_occurrence return delta.total_seconds() / 3600 @property def frequency(self) -> float: """Fehler pro Stunde""" if self.duration > 0: return self.error_count / self.duration return self.error_count @property def severity_score(self) -> float: """ Berechnet einen Schweregrad-Score basierend auf: - Häufigkeit - Impact - Wiederherstellungsrate """ frequency_factor = min(self.frequency / 10, 1.0) # Normalisiert auf 0-1 impact_factor = min((self.total_user_impact + self.total_system_impact) / 100, 1.0) recovery_factor = 1.0 - self.recovery_success_rate data_loss_factor = min(self.data_loss_incidents / 10, 1.0) return (frequency_factor * 0.3 + impact_factor * 0.3 + recovery_factor * 0.2 + data_loss_factor * 0.2) def to_dict(self) -> Dict[str, Any]: """Konvertiert zu Dictionary für Serialisierung""" return { 'error_type': self.error_type, 'error_count': self.error_count, 'first_occurrence': self.first_occurrence.isoformat(), 'last_occurrence': self.last_occurrence.isoformat(), 'duration_hours': self.duration, 'frequency_per_hour': self.frequency, 'affected_sessions': self.affected_sessions, 'affected_accounts': self.affected_accounts, 'avg_recovery_time': self.avg_recovery_time, 'recovery_success_rate': self.recovery_success_rate, 'most_common_urls': self.most_common_urls[:5], 'most_common_actions': self.most_common_actions[:5], 'most_common_steps': self.most_common_steps[:5], 'total_user_impact': self.total_user_impact, 'total_system_impact': self.total_system_impact, 'data_loss_incidents': self.data_loss_incidents, 'severity_score': self.severity_score }