# app/models/syndarix/sprint.py """ Sprint model for Syndarix AI consulting platform. A Sprint represents a time-boxed iteration for organizing and delivering work. """ from sqlalchemy import ( Column, Date, Enum, ForeignKey, Index, Integer, String, Text, UniqueConstraint, ) from sqlalchemy.dialects.postgresql import UUID as PGUUID from sqlalchemy.orm import relationship from app.models.base import Base, TimestampMixin, UUIDMixin from .enums import SprintStatus class Sprint(Base, UUIDMixin, TimestampMixin): """ Sprint model representing a time-boxed iteration. Tracks: - Sprint metadata (name, number, goal) - Date range (start/end) - Progress metrics (planned vs completed points) """ __tablename__ = "sprints" # Foreign key to project project_id = Column( PGUUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, index=True, ) # Sprint identification name = Column(String(255), nullable=False) number = Column(Integer, nullable=False) # Sprint number within project # Sprint goal (what we aim to achieve) goal = Column(Text, nullable=True) # Date range start_date = Column(Date, nullable=False, index=True) end_date = Column(Date, nullable=False, index=True) # Status status: Column[SprintStatus] = Column( Enum( SprintStatus, name="sprint_status", values_callable=lambda x: [e.value for e in x], ), default=SprintStatus.PLANNED, nullable=False, index=True, ) # Progress metrics planned_points = Column(Integer, nullable=True) # Sum of story points at start velocity = Column(Integer, nullable=True) # Sum of completed story points # Relationships project = relationship("Project", back_populates="sprints") issues = relationship("Issue", back_populates="sprint") __table_args__ = ( Index("ix_sprints_project_status", "project_id", "status"), Index("ix_sprints_project_number", "project_id", "number"), Index("ix_sprints_date_range", "start_date", "end_date"), # Ensure sprint numbers are unique within a project UniqueConstraint("project_id", "number", name="uq_sprint_project_number"), ) def __repr__(self) -> str: return ( f"" )