Files
AccountForger-neuerUpload/domain/value_objects/error_summary.py
Claude Project Manager 04585e95b6 Initial commit
2025-08-01 23:50:28 +02:00

98 Zeilen
3.5 KiB
Python

"""
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
}