101 lines
4.0 KiB
Python
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 |