Spaces:
Sleeping
Sleeping
| from fastapi import APIRouter, HTTPException, Query, Depends | |
| from typing import List, Optional | |
| from datetime import datetime, timedelta, date | |
| from integrations.jira_service import create_jira_service | |
| from services.auth_service import get_current_user | |
| from models.auth_models import UserCredentials | |
| from models.jira_models import ( | |
| JiraIssue, | |
| Sprint, | |
| TeamMember, | |
| WorklogEntry, | |
| ProjectInfo, | |
| KanbanBoard, | |
| KanbanIssuesByColumn, | |
| BoardConfiguration | |
| ) | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter(prefix="/jira", tags=["Jira"]) | |
| async def get_projects(current_user: UserCredentials = Depends(get_current_user)): | |
| """Get all Jira projects""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_projects() | |
| except Exception as e: | |
| logger.error(f"Error fetching projects: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_project_issues( | |
| project_key: str, | |
| current_user: UserCredentials = Depends(get_current_user), | |
| max_results: int = Query(100, ge=1, le=1000), | |
| start_date: Optional[str] = None, | |
| end_date: Optional[str] = None | |
| ): | |
| """Get issues for a specific project""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| start_dt = datetime.fromisoformat(start_date) if start_date else None | |
| end_dt = datetime.fromisoformat(end_date) if end_date else None | |
| return jira_service.get_issues_by_project( | |
| project_key=project_key, | |
| max_results=max_results, | |
| start_date=start_dt, | |
| end_date=end_dt | |
| ) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=f"Invalid date format: {str(e)}") | |
| except Exception as e: | |
| logger.error(f"Error fetching issues: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_boards(current_user: UserCredentials = Depends(get_current_user)): | |
| """Get all Jira boards""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_boards() | |
| except Exception as e: | |
| logger.error(f"Error fetching boards: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_board_sprints( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get sprints for a board""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_sprints(board_id) | |
| except Exception as e: | |
| logger.error(f"Error fetching sprints: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_active_sprint( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get the currently active sprint for a board""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_active_sprint(board_id) | |
| except Exception as e: | |
| logger.error(f"Error fetching active sprint: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_sprint_issues( | |
| sprint_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get issues for a specific sprint""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_sprint_issues(sprint_id) | |
| except Exception as e: | |
| logger.error(f"Error fetching sprint issues: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_team_members( | |
| project_key: str, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get team members for a project""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_team_members(project_key) | |
| except Exception as e: | |
| logger.error(f"Error fetching team members: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_worklogs( | |
| project_key: str, | |
| current_user: UserCredentials = Depends(get_current_user), | |
| start_date: Optional[str] = None, | |
| end_date: Optional[str] = None | |
| ): | |
| """Get worklogs for a project""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| start_dt = datetime.fromisoformat(start_date) if start_date else None | |
| end_dt = datetime.fromisoformat(end_date) if end_date else None | |
| return jira_service.get_worklogs( | |
| project_key=project_key, | |
| start_date=start_dt, | |
| end_date=end_dt | |
| ) | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=f"Invalid date format: {str(e)}") | |
| except Exception as e: | |
| logger.error(f"Error fetching worklogs: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_issue( | |
| issue_key: str, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get a specific issue by key""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| issue = jira_service.get_issue_by_key(issue_key) | |
| if not issue: | |
| raise HTTPException(status_code=404, detail=f"Issue {issue_key} not found") | |
| return issue | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"Error fetching issue: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| # ===== KANBAN BOARD ENDPOINTS ===== | |
| async def get_kanban_boards(current_user: UserCredentials = Depends(get_current_user)): | |
| """Get all Kanban boards with their column configurations""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_kanban_boards() | |
| except Exception as e: | |
| logger.error(f"Error fetching Kanban boards: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_kanban_board( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get a specific Kanban board by ID""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| board = jira_service.get_kanban_board_by_id(board_id) | |
| if not board: | |
| raise HTTPException( | |
| status_code=404, | |
| detail=f"Kanban board {board_id} not found or is not a Kanban board" | |
| ) | |
| return board | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"Error fetching Kanban board: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_board_configuration( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get detailed board configuration including columns, estimation, and ranking""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_board_configuration(board_id) | |
| except Exception as e: | |
| logger.error(f"Error fetching board configuration: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_kanban_board_issues( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get issues for a Kanban board grouped by columns""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_kanban_issues_by_column(board_id) | |
| except Exception as e: | |
| logger.error(f"Error fetching Kanban board issues: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_board_backlog( | |
| board_id: int, | |
| current_user: UserCredentials = Depends(get_current_user), | |
| max_results: int = Query(100, ge=1, le=500) | |
| ): | |
| """Get backlog issues for a board""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_board_backlog(board_id, max_results) | |
| except Exception as e: | |
| logger.error(f"Error fetching board backlog: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def transition_issue( | |
| issue_key: str, | |
| current_user: UserCredentials = Depends(get_current_user), | |
| transition_name: str = Query(..., description="Name of the transition to execute") | |
| ): | |
| """Move an issue to a different status/column via transition""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| success = jira_service.move_issue_to_status(issue_key, transition_name) | |
| if not success: | |
| raise HTTPException( | |
| status_code=400, | |
| detail=f"Transition '{transition_name}' not available for issue {issue_key}" | |
| ) | |
| return { | |
| "success": True, | |
| "message": f"Issue {issue_key} transitioned to {transition_name}" | |
| } | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"Error transitioning issue: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def get_issue_transitions( | |
| issue_key: str, | |
| current_user: UserCredentials = Depends(get_current_user) | |
| ): | |
| """Get available transitions for an issue""" | |
| try: | |
| jira_service = create_jira_service( | |
| current_user.jira_email, | |
| current_user.jira_api_token, | |
| current_user.jira_server_url | |
| ) | |
| return jira_service.get_issue_transitions(issue_key) | |
| except Exception as e: | |
| logger.error(f"Error fetching issue transitions: {str(e)}") | |
| raise HTTPException(status_code=500, detail=str(e)) | |