Files
pragma-stack/backend/app/models/syndarix/sprint.py
Felipe Cardoso fcb0a5f86a fix(models): add explicit enum names to match migration types
SQLAlchemy's Enum() auto-generates type names from Python class names
(e.g., AutonomyLevel -> autonomylevel), but migrations defined them
with underscores (e.g., autonomy_level). This mismatch caused:

  "type 'autonomylevel' does not exist"

Added explicit name parameters to all enum columns to match the
migration-defined type names:
- autonomy_level, project_status, project_complexity, client_mode
- agent_status, sprint_status
- issue_type, issue_status, issue_priority, sync_status

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 02:48:10 +01:00

87 lines
2.4 KiB
Python

# 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"),
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"<Sprint {self.name} (#{self.number}) "
f"project={self.project_id} status={self.status.value}>"
)