From f9a72fcb34f201f5045573e7838ff82fcf4e1aae Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Tue, 6 Jan 2026 02:53:45 +0100 Subject: [PATCH] fix(models): use enum values instead of names for PostgreSQL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add values_callable to all enum columns so SQLAlchemy serializes using the enum's .value (lowercase) instead of .name (uppercase). PostgreSQL enum types defined in migrations use lowercase values. Fixes: invalid input value for enum autonomy_level: "MILESTONE" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- backend/app/models/syndarix/agent_instance.py | 6 ++++- backend/app/models/syndarix/issue.py | 22 +++++++++++++---- backend/app/models/syndarix/project.py | 24 +++++++++++++++---- backend/app/models/syndarix/sprint.py | 6 ++++- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/backend/app/models/syndarix/agent_instance.py b/backend/app/models/syndarix/agent_instance.py index 0bb26fb..9a452fd 100644 --- a/backend/app/models/syndarix/agent_instance.py +++ b/backend/app/models/syndarix/agent_instance.py @@ -62,7 +62,11 @@ class AgentInstance(Base, UUIDMixin, TimestampMixin): # Status tracking status: Column[AgentStatus] = Column( - Enum(AgentStatus, name="agent_status"), + Enum( + AgentStatus, + name="agent_status", + values_callable=lambda x: [e.value for e in x], + ), default=AgentStatus.IDLE, nullable=False, index=True, diff --git a/backend/app/models/syndarix/issue.py b/backend/app/models/syndarix/issue.py index 1fff0fa..1dce9a5 100644 --- a/backend/app/models/syndarix/issue.py +++ b/backend/app/models/syndarix/issue.py @@ -59,7 +59,9 @@ class Issue(Base, UUIDMixin, TimestampMixin): # Issue type (Epic, Story, Task, Bug) type: Column[IssueType] = Column( - Enum(IssueType, name="issue_type"), + Enum( + IssueType, name="issue_type", values_callable=lambda x: [e.value for e in x] + ), default=IssueType.TASK, nullable=False, index=True, @@ -78,14 +80,22 @@ class Issue(Base, UUIDMixin, TimestampMixin): # Status and priority status: Column[IssueStatus] = Column( - Enum(IssueStatus, name="issue_status"), + Enum( + IssueStatus, + name="issue_status", + values_callable=lambda x: [e.value for e in x], + ), default=IssueStatus.OPEN, nullable=False, index=True, ) priority: Column[IssuePriority] = Column( - Enum(IssuePriority, name="issue_priority"), + Enum( + IssuePriority, + name="issue_priority", + values_callable=lambda x: [e.value for e in x], + ), default=IssuePriority.MEDIUM, nullable=False, index=True, @@ -132,7 +142,11 @@ class Issue(Base, UUIDMixin, TimestampMixin): # Sync status with external tracker sync_status: Column[SyncStatus] = Column( - Enum(SyncStatus, name="sync_status"), + Enum( + SyncStatus, + name="sync_status", + values_callable=lambda x: [e.value for e in x], + ), default=SyncStatus.SYNCED, nullable=False, # Note: Index defined in __table_args__ as ix_issues_sync_status diff --git a/backend/app/models/syndarix/project.py b/backend/app/models/syndarix/project.py index e30d975..0a4bf98 100644 --- a/backend/app/models/syndarix/project.py +++ b/backend/app/models/syndarix/project.py @@ -35,28 +35,44 @@ class Project(Base, UUIDMixin, TimestampMixin): description = Column(Text, nullable=True) autonomy_level: Column[AutonomyLevel] = Column( - Enum(AutonomyLevel, name="autonomy_level"), + Enum( + AutonomyLevel, + name="autonomy_level", + values_callable=lambda x: [e.value for e in x], + ), default=AutonomyLevel.MILESTONE, nullable=False, index=True, ) status: Column[ProjectStatus] = Column( - Enum(ProjectStatus, name="project_status"), + Enum( + ProjectStatus, + name="project_status", + values_callable=lambda x: [e.value for e in x], + ), default=ProjectStatus.ACTIVE, nullable=False, index=True, ) complexity: Column[ProjectComplexity] = Column( - Enum(ProjectComplexity, name="project_complexity"), + Enum( + ProjectComplexity, + name="project_complexity", + values_callable=lambda x: [e.value for e in x], + ), default=ProjectComplexity.MEDIUM, nullable=False, index=True, ) client_mode: Column[ClientMode] = Column( - Enum(ClientMode, name="client_mode"), + Enum( + ClientMode, + name="client_mode", + values_callable=lambda x: [e.value for e in x], + ), default=ClientMode.AUTO, nullable=False, index=True, diff --git a/backend/app/models/syndarix/sprint.py b/backend/app/models/syndarix/sprint.py index 04db131..024d919 100644 --- a/backend/app/models/syndarix/sprint.py +++ b/backend/app/models/syndarix/sprint.py @@ -57,7 +57,11 @@ class Sprint(Base, UUIDMixin, TimestampMixin): # Status status: Column[SprintStatus] = Column( - Enum(SprintStatus, name="sprint_status"), + Enum( + SprintStatus, + name="sprint_status", + values_callable=lambda x: [e.value for e in x], + ), default=SprintStatus.PLANNED, nullable=False, index=True,