""" Repository für Alert Rules (Filterregeln). """ import uuid from datetime import datetime from typing import Optional, List, Dict, Any from sqlalchemy.orm import Session as DBSession from sqlalchemy import or_ from .models import AlertRuleDB, RuleActionEnum class RuleRepository: """Repository für Alert Rules (Filterregeln).""" def __init__(self, db: DBSession): self.db = db # ==================== CREATE ==================== def create( self, name: str, conditions: List[Dict], action_type: str = "keep", action_config: Dict = None, topic_id: str = None, user_id: str = None, description: str = "", priority: int = 0, ) -> AlertRuleDB: """Erstellt eine neue Regel.""" rule = AlertRuleDB( id=str(uuid.uuid4()), topic_id=topic_id, user_id=user_id, name=name, description=description, conditions=conditions, action_type=RuleActionEnum(action_type), action_config=action_config or {}, priority=priority, ) self.db.add(rule) self.db.commit() self.db.refresh(rule) return rule # ==================== READ ==================== def get_by_id(self, rule_id: str) -> Optional[AlertRuleDB]: """Holt eine Regel nach ID.""" return self.db.query(AlertRuleDB).filter( AlertRuleDB.id == rule_id ).first() def get_active( self, topic_id: str = None, user_id: str = None, ) -> List[AlertRuleDB]: """Holt alle aktiven Regeln, sortiert nach Priorität.""" query = self.db.query(AlertRuleDB).filter( AlertRuleDB.is_active == True ) if topic_id: # Topic-spezifische und globale Regeln query = query.filter( or_( AlertRuleDB.topic_id == topic_id, AlertRuleDB.topic_id.is_(None) ) ) if user_id: query = query.filter( or_( AlertRuleDB.user_id == user_id, AlertRuleDB.user_id.is_(None) ) ) return query.order_by(AlertRuleDB.priority.desc()).all() def get_all( self, user_id: str = None, topic_id: str = None, is_active: bool = None, ) -> List[AlertRuleDB]: """Holt alle Regeln mit optionalen Filtern.""" query = self.db.query(AlertRuleDB) if user_id: query = query.filter(AlertRuleDB.user_id == user_id) if topic_id: query = query.filter(AlertRuleDB.topic_id == topic_id) if is_active is not None: query = query.filter(AlertRuleDB.is_active == is_active) return query.order_by(AlertRuleDB.priority.desc()).all() # ==================== UPDATE ==================== def update( self, rule_id: str, name: str = None, description: str = None, conditions: List[Dict] = None, action_type: str = None, action_config: Dict = None, priority: int = None, is_active: bool = None, ) -> Optional[AlertRuleDB]: """Aktualisiert eine Regel.""" rule = self.get_by_id(rule_id) if not rule: return None if name is not None: rule.name = name if description is not None: rule.description = description if conditions is not None: rule.conditions = conditions if action_type is not None: rule.action_type = RuleActionEnum(action_type) if action_config is not None: rule.action_config = action_config if priority is not None: rule.priority = priority if is_active is not None: rule.is_active = is_active self.db.commit() self.db.refresh(rule) return rule def increment_match_count(self, rule_id: str) -> Optional[AlertRuleDB]: """Erhöht den Match-Counter einer Regel.""" rule = self.get_by_id(rule_id) if not rule: return None rule.match_count += 1 rule.last_matched_at = datetime.utcnow() self.db.commit() self.db.refresh(rule) return rule # ==================== DELETE ==================== def delete(self, rule_id: str) -> bool: """Löscht eine Regel.""" rule = self.get_by_id(rule_id) if not rule: return False self.db.delete(rule) self.db.commit() return True # ==================== CONVERSION ==================== def to_dict(self, rule: AlertRuleDB) -> Dict[str, Any]: """Konvertiert DB-Model zu Dictionary.""" return { "id": rule.id, "topic_id": rule.topic_id, "user_id": rule.user_id, "name": rule.name, "description": rule.description, "conditions": rule.conditions, "action_type": rule.action_type.value, "action_config": rule.action_config, "priority": rule.priority, "is_active": rule.is_active, "stats": { "match_count": rule.match_count, "last_matched_at": rule.last_matched_at.isoformat() if rule.last_matched_at else None, }, "created_at": rule.created_at.isoformat() if rule.created_at else None, "updated_at": rule.updated_at.isoformat() if rule.updated_at else None, }