""" CrossSwitchRoute model for storing cross-switching history and current state """ from sqlalchemy import Column, String, Integer, DateTime, ForeignKey, Index from sqlalchemy.dialects.postgresql import UUID, JSONB from datetime import datetime import uuid from models import Base class CrossSwitchRoute(Base): """ Model for cross-switch routing records Stores both current routing state and historical routing changes """ __tablename__ = "crossswitch_routes" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Route information camera_id = Column(Integer, nullable=False, index=True, comment="Camera ID (source)") monitor_id = Column(Integer, nullable=False, index=True, comment="Monitor ID (destination)") mode = Column(Integer, default=0, comment="Cross-switch mode (0=normal, other modes per SDK)") # Execution tracking executed_at = Column(DateTime, nullable=False, default=datetime.utcnow, index=True) executed_by = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True) # Status tracking is_active = Column(Integer, default=1, nullable=False, index=True, comment="1=active route, 0=cleared/historical") cleared_at = Column(DateTime, nullable=True, comment="When this route was cleared (if cleared)") cleared_by = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True) # Additional metadata details = Column(JSONB, nullable=True, comment="Additional route details (camera name, monitor name, etc.)") # SDK response tracking sdk_success = Column(Integer, default=1, nullable=False, comment="1=SDK reported success, 0=SDK reported failure") sdk_error = Column(String(500), nullable=True, comment="SDK error message if failed") # Indexes for common queries __table_args__ = ( # Index for getting current active routes Index('idx_active_routes', 'is_active', 'monitor_id'), # Index for getting route history by camera Index('idx_camera_history', 'camera_id', 'executed_at'), # Index for getting route history by monitor Index('idx_monitor_history', 'monitor_id', 'executed_at'), # Index for getting user's routing actions Index('idx_user_routes', 'executed_by', 'executed_at'), ) def __repr__(self): return f"" @classmethod def create_route( cls, camera_id: int, monitor_id: int, executed_by: uuid.UUID, mode: int = 0, sdk_success: bool = True, sdk_error: str = None, details: dict = None ): """ Factory method to create a new route record Args: camera_id: Camera ID monitor_id: Monitor ID executed_by: User ID who executed the route mode: Cross-switch mode (default: 0) sdk_success: Whether SDK reported success sdk_error: SDK error message if failed details: Additional metadata Returns: CrossSwitchRoute instance """ return cls( camera_id=camera_id, monitor_id=monitor_id, mode=mode, executed_by=executed_by, executed_at=datetime.utcnow(), is_active=1 if sdk_success else 0, sdk_success=1 if sdk_success else 0, sdk_error=sdk_error, details=details or {} ) def clear_route(self, cleared_by: uuid.UUID): """ Mark this route as cleared Args: cleared_by: User ID who cleared the route """ self.is_active = 0 self.cleared_at = datetime.utcnow() self.cleared_by = cleared_by def to_dict(self): """Convert to dictionary for API responses""" return { "id": str(self.id), "camera_id": self.camera_id, "monitor_id": self.monitor_id, "mode": self.mode, "executed_at": self.executed_at.isoformat() if self.executed_at else None, "executed_by": str(self.executed_by) if self.executed_by else None, "is_active": bool(self.is_active), "cleared_at": self.cleared_at.isoformat() if self.cleared_at else None, "cleared_by": str(self.cleared_by) if self.cleared_by else None, "details": self.details, "sdk_success": bool(self.sdk_success), "sdk_error": self.sdk_error }