"""Alert notification domain models.""" from __future__ import annotations import json from dataclasses import asdict, dataclass from pathlib import Path from typing import Any @dataclass class AlertEvent: severity: str message: str ltv_ratio: float warning_threshold: float critical_threshold: float spot_price: float updated_at: str email_alerts_enabled: bool def to_dict(self) -> dict[str, Any]: return asdict(self) @classmethod def from_dict(cls, data: dict[str, Any]) -> "AlertEvent": return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__}) @dataclass class AlertStatus: severity: str message: str ltv_ratio: float warning_threshold: float critical_threshold: float email_alerts_enabled: bool history: list[AlertEvent] class AlertHistoryRepository: """File-backed alert history store.""" HISTORY_PATH = Path("data/alert_history.json") def __init__(self, history_path: Path | None = None) -> None: self.history_path = history_path or self.HISTORY_PATH self.history_path.parent.mkdir(parents=True, exist_ok=True) def load(self) -> list[AlertEvent]: if not self.history_path.exists(): return [] try: with self.history_path.open() as f: data = json.load(f) except (json.JSONDecodeError, OSError): return [] if not isinstance(data, list): return [] return [AlertEvent.from_dict(item) for item in data if isinstance(item, dict)] def save(self, events: list[AlertEvent]) -> None: with self.history_path.open("w") as f: json.dump([event.to_dict() for event in events], f, indent=2)