feat(P3.1): milestone action endpoints — freeze/start/close + auto-complete hook

- New milestone_actions router with POST freeze/start/close endpoints
- freeze: validates exactly 1 release maintenance task exists
- start: validates all milestone/task dependencies completed, records started_at
- close: allows from open/freeze/undergoing with reason
- try_auto_complete_milestone helper: auto-completes milestone when sole release task finishes
- Wired auto-complete into task transition and update endpoints
- Added freeze enforcement: no new feature story tasks after freeze
- Added started_at to milestone serializer
- All actions write activity logs
This commit is contained in:
zhi
2026-03-17 04:03:05 +00:00
parent 75ccbcb362
commit 7d8c448cb8
4 changed files with 336 additions and 2 deletions

View File

@@ -176,6 +176,12 @@ def update_task(task_id: int, task_update: schemas.TaskUpdate, db: Session = Dep
setattr(task, field, value)
db.commit()
db.refresh(task)
# P3.5: auto-complete milestone when release task reaches completed via update
if "status" in update_data and update_data["status"] == "completed":
from app.api.routers.milestone_actions import try_auto_complete_milestone
try_auto_complete_milestone(db, task, user_id=current_user.id)
return task
@@ -209,6 +215,12 @@ def transition_task(task_id: int, new_status: str, bg: BackgroundTasks, db: Sess
task.status = new_status
db.commit()
db.refresh(task)
# P3.5: auto-complete milestone when its sole release task is completed
if new_status == "completed":
from app.api.routers.milestone_actions import try_auto_complete_milestone
try_auto_complete_milestone(db, task, user_id=None)
event = "task.closed" if new_status == "closed" else "task.updated"
bg.add_task(fire_webhooks_sync, event,
{"task_id": task.id, "title": task.title, "old_status": old_status, "new_status": new_status},