fix(backend): critical bug fixes for agent termination and sprint validation
Bug Fixes:
- bulk_terminate_by_project now unassigns issues before terminating agents
to prevent orphaned issue assignments
- PATCH /issues/{id} now validates sprint status - cannot assign issues
to COMPLETED or CANCELLED sprints
- archive_project now performs cascading cleanup:
- Terminates all active agent instances
- Cancels all planned/active sprints
- Unassigns issues from terminated agents
Added edge case tests for all fixed bugs (19 new tests total):
- TestBulkTerminateEdgeCases
- TestSprintStatusValidation
- TestArchiveProjectCleanup
- TestDataIntegrityEdgeCases (IDOR protection)
Coverage: 93% (1836 tests passing)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,13 @@ from app.crud.syndarix.agent_instance import agent_instance as agent_instance_cr
|
||||
from app.crud.syndarix.issue import issue as issue_crud
|
||||
from app.crud.syndarix.project import project as project_crud
|
||||
from app.crud.syndarix.sprint import sprint as sprint_crud
|
||||
from app.models.syndarix.enums import AgentStatus, IssuePriority, IssueStatus, SyncStatus
|
||||
from app.models.syndarix.enums import (
|
||||
AgentStatus,
|
||||
IssuePriority,
|
||||
IssueStatus,
|
||||
SprintStatus,
|
||||
SyncStatus,
|
||||
)
|
||||
from app.models.user import User
|
||||
from app.schemas.common import (
|
||||
MessageResponse,
|
||||
@@ -550,7 +556,7 @@ async def update_issue(
|
||||
field="assigned_agent_id",
|
||||
)
|
||||
|
||||
# Validate sprint if being updated (IDOR prevention)
|
||||
# Validate sprint if being updated (IDOR prevention and status validation)
|
||||
if issue_in.sprint_id is not None:
|
||||
sprint = await sprint_crud.get(db, id=issue_in.sprint_id)
|
||||
if not sprint:
|
||||
@@ -564,6 +570,13 @@ async def update_issue(
|
||||
error_code=ErrorCode.VALIDATION_ERROR,
|
||||
field="sprint_id",
|
||||
)
|
||||
# Cannot add issues to completed or cancelled sprints
|
||||
if sprint.status in [SprintStatus.COMPLETED, SprintStatus.CANCELLED]:
|
||||
raise ValidationException(
|
||||
message=f"Cannot add issues to sprint with status '{sprint.status.value}'",
|
||||
error_code=ErrorCode.VALIDATION_ERROR,
|
||||
field="sprint_id",
|
||||
)
|
||||
|
||||
try:
|
||||
updated_issue = await issue_crud.update(db, db_obj=issue, obj_in=issue_in)
|
||||
|
||||
Reference in New Issue
Block a user