76 lines
2.9 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from loguru import logger
import json
from typing import Optional, List, Union
from sqlalchemy.orm import Session
from pydantic import BaseModel, ConfigDict, field_validator
from datetime import datetime, timezone # Import timezone
import uuid
from config import settings
from langfuse import Langfuse
from database.crud import create_analysis_record
from llm.models import JiraWebhookPayload
from database.database import get_db_session
webhook_router = APIRouter()
class BadRequestError(HTTPException):
def __init__(self, detail: str):
super().__init__(status_code=400, detail=detail)
class RateLimitError(HTTPException):
def __init__(self, detail: str):
super().__init__(status_code=429, detail=detail)
class ValidationError(HTTPException):
def __init__(self, detail: str):
super().__init__(status_code=422, detail=detail)
class ValidationError(HTTPException):
def __init__(self, detail: str):
super().__init__(status_code=422, detail=detail)
class JiraWebhookHandler:
async def process_jira_request(self, payload: JiraWebhookPayload, db: Session):
try:
if not payload.issueKey:
raise BadRequestError("Missing required field: issueKey")
if not payload.summary:
raise BadRequestError("Missing required field: summary")
# Create new analysis record with initial state
new_record = create_analysis_record(db=db, payload=payload)
logger.bind(
issue_key=payload.issueKey,
record_id=new_record.id,
timestamp=datetime.now(timezone.utc).isoformat()
).info(f"[{payload.issueKey}] Received webhook and queued for processing.")
return {"status": "queued", "record_id": new_record.id}
except Exception as e:
issue_key = payload.issueKey if payload.issueKey else "N/A"
logger.error(f"[{issue_key}] Error receiving webhook: {str(e)}")
import traceback
logger.error(f"[{issue_key}] Stack trace: {traceback.format_exc()}")
raise HTTPException(status_code=500, detail=f"Internal Server Error: {str(e)}")
# Initialize handler
webhook_handler = JiraWebhookHandler()
@webhook_router.post("/api/jira-webhook", status_code=202)
async def receive_jira_request(payload: JiraWebhookPayload, db: Session = Depends(get_db_session)):
"""Jira webhook endpoint - receives and queues requests for processing"""
try:
result = await webhook_handler.process_jira_request(payload, db)
return result
except ValidationError as e:
raise
except BadRequestError as e:
raise ValidationError(detail=e.detail)
except Exception as e:
logger.error(f"Unexpected error in webhook endpoint: {str(e)}")
raise HTTPException(status_code=500, detail=f"Internal Server Error: {str(e)}")