from typing import Optional, List, Union from enum import Enum from loguru import logger from pydantic import BaseModel, ConfigDict, field_validator, Field from datetime import datetime from config import settings class LLMResponse(BaseModel): status: str message: str class CustomerSentiment(str, Enum): NEUTRAL = "neutral" FRUSTRATED = "frustrated" CALM = "calm" class IssueCategory(str, Enum): TECHNICAL_ISSUE = "technical_issue" DATA_REQUEST = "data_request" ACCESS_PROBLEM = "access_problem" GENERAL_QUESTION = "general_question" OTHER = "other" # New: Add an Enum for technical areas based on Confluence doc class Area(str, Enum): DIRECT_CHANNEL = "Direct Channel" STREAMING_CHANNEL = "Streaming Channel" JAVA_BATCH_CHANNEL = "Java Batch Channel" ETL_BATCH_CHANNEL = "ETL Batch Channel" DCR_SERVICE = "DCR Service" API_GATEWAY = "API Gateway" CALLBACK_SERVICE = "Callback Service" PUBLISHER = "Publisher" RECONCILIATION = "Reconciliation" SNOWFLAKE = "Snowflake" AUTHENTICATION = "Authentication" OTHER = "Other" class JiraWebhookPayload(BaseModel): model_config = ConfigDict(alias_generator=lambda x: ''.join(word.capitalize() if i > 0 else word for i, word in enumerate(x.split('_'))), populate_by_name=True) issueKey: str summary: str description: Optional[str] = None comment: Optional[str] = None labels: Optional[Union[List[str], str]] = [] @field_validator('labels', mode='before') @classmethod def convert_labels_to_list(cls, v): if isinstance(v, str): return [v] return v or [] status: Optional[str] = None assignee: Optional[str] = None updated: Optional[str] = None class AnalysisFlags(BaseModel): model_config = ConfigDict(alias_generator=lambda x: ''.join(word.capitalize() if i > 0 else word for i, word in enumerate(x.split('_'))), populate_by_name=True) issueCategory: IssueCategory = Field(..., description="The primary category of the Jira ticket.") area: Area = Field(..., description="The technical area of the MDM HUB related to the issue.") customerSentiment: Optional[CustomerSentiment] = Field(..., description="Overall customer sentiment (e.g., 'neutral', 'frustrated', 'calm').") isEscalated: bool = Field(..., description="Is there evidence of multiple escalation attempts?") oneSentenceSummary: str = Field(..., description="A single paragraph in concise English that summarizes the discussion.") class JiraAnalysisResponse(BaseModel): model_config = ConfigDict(from_attributes=True) id: int issue_key: str status: str issue_summary: str request_payload: dict analysis_result: Optional[dict] = None created_at: datetime updated_at: datetime error_message: Optional[str] = None raw_response: Optional[dict] = None