101 lines
4.0 KiB
Python

from loguru import logger
from sqlalchemy.orm import Session
from datetime import datetime, timezone
import json
from typing import Dict, Any, Optional
from database.models import JiraAnalysis
from llm.models import JiraWebhookPayload
def create_analysis_record(db: Session, payload: JiraWebhookPayload) -> JiraAnalysis:
"""Creates a new Jira analysis record in the database."""
db_analysis = JiraAnalysis(
issue_key=payload.issueKey,
status="pending",
issue_summary=payload.summary,
request_payload=payload.model_dump(),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
retry_count=0,
last_processed_at=None,
next_retry_at=None
)
db.add(db_analysis)
db.commit()
db.refresh(db_analysis)
return db_analysis
def get_analysis_record(db: Session, issue_key: str) -> Optional[JiraAnalysis]:
"""Retrieves the latest analysis record for a given Jira issue key."""
logger.debug(f"Attempting to retrieve analysis record for issue key: {issue_key}")
record = db.query(JiraAnalysis).filter(JiraAnalysis.issue_key == issue_key).order_by(JiraAnalysis.created_at.desc()).first()
if record:
logger.debug(f"Found analysis record for {issue_key}: {record.id}")
else:
logger.debug(f"No analysis record found for {issue_key}")
return record
def update_record_status(
db: Session,
record_id: int,
status: str,
analysis_result: Optional[Dict[str, Any]] = None,
error_message: Optional[str] = None,
raw_response: Optional[Dict[str, Any]] = None,
retry_count_increment: int = 0,
last_processed_at: Optional[datetime] = None,
next_retry_at: Optional[datetime] = None
) -> Optional[JiraAnalysis]:
"""Updates an existing Jira analysis record."""
db_analysis = db.query(JiraAnalysis).filter(JiraAnalysis.id == record_id).first()
if db_analysis:
db_analysis.status = status
db_analysis.updated_at = datetime.now(timezone.utc)
# Only update if not None, allowing explicit None to clear values
# Always update these fields if provided, allowing explicit None to clear them
db_analysis.analysis_result = analysis_result
db_analysis.error_message = error_message
db_analysis.raw_response = json.dumps(raw_response) if raw_response is not None else None
if retry_count_increment > 0:
db_analysis.retry_count += retry_count_increment
db_analysis.last_processed_at = last_processed_at
db_analysis.next_retry_at = next_retry_at
# When status is set to "pending", clear relevant fields for retry
if status == "pending":
db_analysis.analysis_result = None
db_analysis.error_message = None
db_analysis.raw_response = None
db_analysis.next_retry_at = None
db.commit()
db.refresh(db_analysis)
return db_analysis
def get_pending_analysis_records(db: Session) -> list[JiraAnalysis]:
"""Retrieves all pending or retrying analysis records that are ready for processing."""
now = datetime.now(timezone.utc)
return db.query(JiraAnalysis).filter(
(JiraAnalysis.status == "pending") |
((JiraAnalysis.status == "retrying") & (JiraAnalysis.next_retry_at <= now))
).order_by(JiraAnalysis.created_at.asc()).all()
def get_all_analysis_records(db: Session) -> list[JiraAnalysis]:
"""Retrieves all analysis records from the database."""
return db.query(JiraAnalysis).all()
def get_analysis_by_id(db: Session, record_id: int) -> Optional[JiraAnalysis]:
"""Retrieves an analysis record by its unique database ID."""
return db.query(JiraAnalysis).filter(JiraAnalysis.id == record_id).first()
def delete_all_analysis_records(db: Session) -> int:
"""Deletes all analysis records from the database and returns count of deleted records."""
count = db.query(JiraAnalysis).count()
db.query(JiraAnalysis).delete()
db.commit()
return count
db.query(JiraAnalysis).delete()
db.commit()
return count