"""BGP incident model for aggregated routing events.""" from datetime import datetime from sqlalchemy import Column, DateTime, Float, ForeignKey, Index, Integer, JSON, String, Text from app.core.time import to_iso8601_utc from app.db.session import Base class BGPIncident(Base): __tablename__ = "bgp_incidents" id = Column(Integer, primary_key=True, index=True) snapshot_id = Column(Integer, ForeignKey("data_snapshots.id"), nullable=True, index=True) task_id = Column(Integer, ForeignKey("collection_tasks.id"), nullable=True, index=True) source = Column(String(100), nullable=False, index=True) incident_key = Column(String(255), nullable=False, index=True) incident_type = Column(String(50), nullable=False, index=True) title = Column(String(255), nullable=False) summary = Column(Text, nullable=False) severity = Column(String(20), nullable=False, index=True) status = Column(String(20), nullable=False, default="active", index=True) confidence = Column(Float, nullable=False, default=0.5) started_at = Column(DateTime(timezone=True), nullable=False, default=datetime.utcnow, index=True) ended_at = Column(DateTime(timezone=True), nullable=True) affected_prefixes = Column(JSON, default=list) affected_asns = Column(JSON, default=list) affected_collectors = Column(JSON, default=list) affected_regions = Column(JSON, default=list) related_cables = Column(JSON, default=list) related_ixps = Column(JSON, default=list) evidence_refs = Column(JSON, default=list) created_at = Column(DateTime(timezone=True), nullable=False, default=datetime.utcnow, index=True) __table_args__ = ( Index("idx_bgp_incidents_source_created", "source", "created_at"), Index("idx_bgp_incidents_type_status", "incident_type", "status"), ) def to_dict(self) -> dict: return { "id": self.id, "snapshot_id": self.snapshot_id, "task_id": self.task_id, "source": self.source, "incident_key": self.incident_key, "incident_type": self.incident_type, "title": self.title, "summary": self.summary, "severity": self.severity, "status": self.status, "confidence": self.confidence, "started_at": to_iso8601_utc(self.started_at), "ended_at": to_iso8601_utc(self.ended_at), "affected_prefixes": self.affected_prefixes or [], "affected_asns": self.affected_asns or [], "affected_collectors": self.affected_collectors or [], "affected_regions": self.affected_regions or [], "related_cables": self.related_cables or [], "related_ixps": self.related_ixps or [], "evidence_refs": self.evidence_refs or [], "created_at": to_iso8601_utc(self.created_at), }