from pydantic import BaseModel, Field from typing import List, Optional, Literal from datetime import date # --------------------------------------------------------- # 0. Itemized Claim Item Schema # (Individual item evaluation) # --------------------------------------------------------- class ItemizedClaimData(BaseModel): description: str = Field(description="Item description (medicine/procedure/test/consultation)") amount: float = Field(description="Amount billed for this item in INR") category: str = Field(description="Category: medicine, procedure, diagnostic_test, consultation") is_covered: bool = Field(description="True if covered by policy") exclusion_reason: str = Field(description="If not covered, why. Otherwise 'None'") is_medically_necessary: bool = Field(description="True if clinically justified") medical_necessity_reason: str = Field(description="Why it is/isn't necessary") # --------------------------------------------------------- # 1. Gemini Extraction Output Schema # (We force Gemini to output this exact structure) # --------------------------------------------------------- class ExtractedClaimData(BaseModel): patient_name: str = Field(description="Name of the patient on the document") treatment_date: str = Field(description="Date of treatment in YYYY-MM-DD format") doctor_name: str = Field(description="Name of the treating doctor") doctor_reg_no: str = Field(description="Doctor's medical registration number") diagnosis: str = Field(description="Primary diagnosis or reason for visit") is_treatment_excluded: bool = Field(default=False, description="True if the treatment matches an exclusion") exclusion_reason: str = Field(default="None") # Itemized breakdown instead of simple lists itemized_claims: List[ItemizedClaimData] = Field(description="Line-by-line breakdown of all billed items with individual coverage assessment") requires_pre_auth: bool = Field(default=False, description="True if procedure needs pre-auth") missing_pre_auth: bool = Field(default=False, description="True if pre-auth is missing") total_billed_amount: float = Field(description="Total amount billed in INR") overall_medically_necessary: bool = Field(description="Is the overall treatment medically justified") medical_necessity_reasoning: str = Field(description="Overall clinical assessment") # --------------------------------------------------------- # 2. API Input Schema # (What the frontend/Postman sends to our FastAPI route) # --------------------------------------------------------- class ClaimSubmission(BaseModel): member_id: str claim_amount: float cashless_request: bool = False hospital_name: Optional[str] = None # Note: Files (images/pdfs) will be handled via FastAPI UploadFile, not Pydantic # --------------------------------------------------------- # 3. Final Adjudication Output Schema # (Matches the exact assignment requirement format) # --------------------------------------------------------- class AdjudicationResponse(BaseModel): claim_id: str decision: Literal["APPROVED", "REJECTED", "PARTIAL", "MANUAL_REVIEW"] approved_amount: float rejection_reasons: List[str] confidence_score: float notes: str next_steps: str cashless_approved: bool = False network_discount: float = 0.0