""" Deployment model for tracking software and configuration deployments. Tracks deployments of code, configuration, database changes, containers, and service restarts with version control and rollback capabilities. """ from datetime import datetime from typing import TYPE_CHECKING, Optional from sqlalchemy import Boolean, CHAR, CheckConstraint, ForeignKey, Index, String, Text, TIMESTAMP from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from .base import Base, UUIDMixin if TYPE_CHECKING: from .infrastructure import Infrastructure from .service import Service from .session import Session from .work_item import WorkItem class Deployment(Base, UUIDMixin): """ Deployment model for tracking software and configuration deployments. Records deployments of code, configuration files, database changes, containers, and service restarts. Includes version tracking, source/ destination paths, and rollback procedures for operational safety. Attributes: work_item_id: Foreign key to work_items table (required) session_id: Foreign key to sessions table (required) infrastructure_id: Foreign key to infrastructure table service_id: Foreign key to services table deployment_type: Type of deployment (code, config, database, etc.) version: Version identifier for this deployment description: Detailed description of what was deployed deployed_from: Source path or repository deployed_to: Destination path or target system rollback_available: Whether rollback is possible rollback_procedure: Instructions for rolling back this deployment created_at: When the deployment occurred work_item: Relationship to WorkItem model session: Relationship to Session model infrastructure: Relationship to Infrastructure model service: Relationship to Service model """ __tablename__ = "deployments" # Foreign keys work_item_id: Mapped[str] = mapped_column( CHAR(36), ForeignKey("work_items.id", ondelete="CASCADE"), nullable=False, doc="Foreign key to work_items table (required)" ) session_id: Mapped[str] = mapped_column( CHAR(36), ForeignKey("sessions.id", ondelete="CASCADE"), nullable=False, doc="Foreign key to sessions table (required)" ) infrastructure_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("infrastructure.id", ondelete="SET NULL"), doc="Foreign key to infrastructure table" ) service_id: Mapped[Optional[str]] = mapped_column( CHAR(36), ForeignKey("services.id", ondelete="SET NULL"), doc="Foreign key to services table" ) # Deployment details deployment_type: Mapped[Optional[str]] = mapped_column( String(50), doc="Type of deployment: code, config, database, container, service_restart" ) version: Mapped[Optional[str]] = mapped_column( String(100), doc="Version identifier for this deployment" ) description: Mapped[Optional[str]] = mapped_column( Text, doc="Detailed description of what was deployed" ) # Source and destination deployed_from: Mapped[Optional[str]] = mapped_column( String(500), doc="Source path or repository (e.g., /home/user/app, git@github.com:user/repo)" ) deployed_to: Mapped[Optional[str]] = mapped_column( String(500), doc="Destination path or target system (e.g., /var/www/app, container-name)" ) # Rollback capability rollback_available: Mapped[bool] = mapped_column( Boolean, default=False, server_default="0", nullable=False, doc="Whether rollback is possible for this deployment" ) rollback_procedure: Mapped[Optional[str]] = mapped_column( Text, doc="Instructions for rolling back this deployment" ) # Timestamp created_at: Mapped[datetime] = mapped_column( TIMESTAMP, nullable=False, server_default=func.now(), doc="When the deployment occurred" ) # Relationships work_item: Mapped["WorkItem"] = relationship( "WorkItem", back_populates="deployments", doc="Relationship to WorkItem model" ) session: Mapped["Session"] = relationship( "Session", back_populates="deployments", doc="Relationship to Session model" ) infrastructure: Mapped[Optional["Infrastructure"]] = relationship( "Infrastructure", back_populates="deployments", doc="Relationship to Infrastructure model" ) service: Mapped[Optional["Service"]] = relationship( "Service", back_populates="deployments", doc="Relationship to Service model" ) # Constraints and indexes __table_args__ = ( CheckConstraint( "deployment_type IN ('code', 'config', 'database', 'container', 'service_restart')", name="ck_deployments_type" ), Index("idx_deployments_work_item", "work_item_id"), Index("idx_deployments_infrastructure", "infrastructure_id"), Index("idx_deployments_service", "service_id"), ) def __repr__(self) -> str: """String representation of the deployment.""" return f""