diff --git a/app/api/routers/comments.py b/app/api/routers/comments.py index 39e7b05..d104691 100644 --- a/app/api/routers/comments.py +++ b/app/api/routers/comments.py @@ -50,9 +50,22 @@ def create_comment(comment: schemas.CommentCreate, db: Session = Depends(get_db) return db_comment -@router.get("/tasks/{task_id}/comments", response_model=List[schemas.CommentResponse]) +@router.get("/tasks/{task_id}/comments") def list_comments(task_id: int, db: Session = Depends(get_db)): - return db.query(models.Comment).filter(models.Comment.task_id == task_id).all() + comments = db.query(models.Comment).filter(models.Comment.task_id == task_id).all() + result = [] + for c in comments: + author = db.query(models.User).filter(models.User.id == c.author_id).first() + result.append({ + "id": c.id, + "content": c.content, + "task_id": c.task_id, + "author_id": c.author_id, + "author_username": author.username if author else None, + "created_at": c.created_at, + "updated_at": c.updated_at, + }) + return result @router.patch("/comments/{comment_id}", response_model=schemas.CommentResponse) diff --git a/app/api/routers/projects.py b/app/api/routers/projects.py index faf3b5f..fa33080 100644 --- a/app/api/routers/projects.py +++ b/app/api/routers/projects.py @@ -332,9 +332,12 @@ def list_project_members(project_id: str, db: Session = Depends(get_db)): role = db.query(Role).filter(Role.id == m.role_id).first() if role: role_name = role.name + user = db.query(models.User).filter(models.User.id == m.user_id).first() result.append({ "id": m.id, "user_id": m.user_id, + "username": user.username if user else None, + "full_name": user.full_name if user else None, "project_id": m.project_id, "role": role_name }) diff --git a/app/api/routers/proposes.py b/app/api/routers/proposes.py index f8877cf..2111b12 100644 --- a/app/api/routers/proposes.py +++ b/app/api/routers/proposes.py @@ -17,6 +17,24 @@ from app.services.activity import log_activity router = APIRouter(prefix="/projects/{project_id}/proposes", tags=["Proposes"]) +def _serialize_propose(db: Session, propose: Propose) -> dict: + """Serialize propose with created_by_username.""" + creator = db.query(models.User).filter(models.User.id == propose.created_by_id).first() if propose.created_by_id else None + return { + "id": propose.id, + "title": propose.title, + "description": propose.description, + "propose_code": propose.propose_code, + "status": propose.status.value if hasattr(propose.status, "value") else propose.status, + "project_id": propose.project_id, + "created_by_id": propose.created_by_id, + "created_by_username": creator.username if creator else None, + "feat_task_id": propose.feat_task_id, + "created_at": propose.created_at, + "updated_at": propose.updated_at, + } + + def _find_project(db, identifier): """Look up project by numeric id or project_code.""" try: @@ -92,7 +110,7 @@ def list_proposes( .order_by(Propose.id.desc()) .all() ) - return proposes + return [_serialize_propose(db, p) for p in proposes] @router.post("", response_model=schemas.ProposeResponse, status_code=status.HTTP_201_CREATED) @@ -123,7 +141,7 @@ def create_propose( log_activity(db, "create", "propose", propose.id, user_id=current_user.id, details={"title": propose.title}) - return propose + return _serialize_propose(db, propose) @router.get("/{propose_id}", response_model=schemas.ProposeResponse) @@ -140,7 +158,7 @@ def get_propose( propose = _find_propose(db, propose_id, project.id) if not propose: raise HTTPException(status_code=404, detail="Propose not found") - return propose + return _serialize_propose(db, propose) @router.patch("/{propose_id}", response_model=schemas.ProposeResponse) @@ -177,7 +195,7 @@ def update_propose( log_activity(db, "update", "propose", propose.id, user_id=current_user.id, details=data) - return propose + return _serialize_propose(db, propose) # ---- Actions ---- @@ -256,7 +274,7 @@ def accept_propose( "task_code": task_code, }) - return propose + return _serialize_propose(db, propose) class RejectRequest(schemas.BaseModel): @@ -293,7 +311,7 @@ def reject_propose( "reason": body.reason if body else None, }) - return propose + return _serialize_propose(db, propose) @router.post("/{propose_id}/reopen", response_model=schemas.ProposeResponse) @@ -323,4 +341,4 @@ def reopen_propose( log_activity(db, "reopen", "propose", propose.id, user_id=current_user.id) - return propose + return _serialize_propose(db, propose) diff --git a/app/schemas/schemas.py b/app/schemas/schemas.py index fa7c248..90b2d09 100644 --- a/app/schemas/schemas.py +++ b/app/schemas/schemas.py @@ -208,6 +208,8 @@ class ProjectMemberCreate(ProjectMemberBase): class ProjectMemberResponse(BaseModel): id: int user_id: int + username: Optional[str] = None + full_name: Optional[str] = None project_id: int role: str = "dev" @@ -290,6 +292,7 @@ class ProposeResponse(ProposeBase): status: ProposeStatusEnum project_id: int created_by_id: Optional[int] = None + created_by_username: Optional[str] = None feat_task_id: Optional[str] = None created_at: datetime updated_at: Optional[datetime] = None