"""Auto-create Problems from ingested events (MVP rules).""" from sqlalchemy import select from sqlalchemy.orm import Session from app.models import Event, Problem, ProblemEvent # event types that always open a problem PROBLEM_TYPES = frozenset( { "ssh.ip.banned", "ssh.bruteforce.mass", } ) HIGH_SEVERITIES = frozenset({"high", "critical"}) def maybe_create_problem(db: Session, event: Event) -> Problem | None: if event.severity not in HIGH_SEVERITIES and event.type not in PROBLEM_TYPES: return None rule_id = "high_severity" if event.severity in HIGH_SEVERITIES else f"type:{event.type}" existing = db.scalar( select(Problem) .join(ProblemEvent) .where( Problem.status == "open", Problem.rule_id == rule_id, Problem.host_id == event.host_id, ProblemEvent.event_id == event.id, ) .limit(1) ) if existing: return existing # dedupe: one open problem per host+rule (append event link) open_problem = db.scalar( select(Problem) .where( Problem.status == "open", Problem.rule_id == rule_id, Problem.host_id == event.host_id, ) .order_by(Problem.created_at.desc()) .limit(1) ) if open_problem: db.add(ProblemEvent(problem_id=open_problem.id, event_id=event.id)) open_problem.updated_at = event.received_at db.flush() return open_problem problem = Problem( host_id=event.host_id, title=event.title, summary=event.summary, severity=event.severity, status="open", rule_id=rule_id, ) db.add(problem) db.flush() db.add(ProblemEvent(problem_id=problem.id, event_id=event.id)) db.flush() return problem