diff --git a/app/api/routers/misc.py b/app/api/routers/misc.py index 07a22b9..d321ed5 100644 --- a/app/api/routers/misc.py +++ b/app/api/routers/misc.py @@ -158,14 +158,60 @@ def list_milestone_issues(milestone_id: int, db: Session = Depends(get_db)): @router.get("/milestones/{milestone_id}/progress", tags=["Milestones"]) def milestone_progress(milestone_id: int, db: Session = Depends(get_db)): + from datetime import datetime ms = db.query(MilestoneModel).filter(MilestoneModel.id == milestone_id).first() if not ms: raise HTTPException(status_code=404, detail="Milestone not found") - issues = db.query(models.Issue).filter(models.Issue.milestone_id == milestone_id).all() + # Count tasks only + issues = db.query(models.Issue).filter( + models.Issue.milestone_id == milestone_id, + models.Issue.issue_type == "task" + ).all() total = len(issues) done = sum(1 for i in issues if i.status in ("resolved", "closed")) - return {"milestone_id": milestone_id, "title": ms.title, "total_issues": total, - "completed": done, "progress_pct": round(done / total * 100, 1) if total else 0} + + time_progress = None + if ms.planned_release_date and ms.created_at: + now = datetime.now() + total_duration = (ms.planned_release_date - ms.created_at).total_seconds() + elapsed = (now - ms.created_at).total_seconds() + time_progress = min(100, max(0, (elapsed / total_duration * 100))) + + return {"milestone_id": milestone_id, "title": ms.title, "total": total, + "completed": done, "progress_pct": round(done / total * 100, 1) if total else 0, + "time_progress_pct": round(time_progress, 1) if time_progress else None, + "planned_release_date": ms.planned_release_date} + + +@router.get("/milestones/{milestone_id}/items", tags=["Milestones"]) +def milestone_items(milestone_id: int, db: Session = Depends(get_db)): + ms = db.query(MilestoneModel).filter(MilestoneModel.id == milestone_id).first() + if not ms: + raise HTTPException(status_code=404, detail="Milestone not found") + + issues = db.query(models.Issue).filter(models.Issue.milestone_id == milestone_id).all() + + tasks = [] + supports = [] + meetings = [] + + for issue in issues: + issue_data = { + "id": issue.id, + "title": issue.title, + "description": issue.description, + "status": issue.status.value if hasattr(issue.status, 'value') else issue.status, + "priority": issue.priority.value if hasattr(issue.priority, 'value') else issue.priority, + "created_at": issue.created_at, + } + if issue.issue_type == "task": + tasks.append(issue_data) + elif issue.issue_type == "support": + supports.append(issue_data) + elif issue.issue_type == "meeting": + meetings.append(issue_data) + + return {"tasks": tasks, "supports": supports, "meetings": meetings} # ============ Notifications ============