76 lines
2.9 KiB
Python
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)}") |