import os import uuid from datetime import datetime from fastapi import FastAPI, UploadFile, File, Header, HTTPException, status, Form from fastapi.middleware.cors import CORSMiddleware from typing import Optional, List from backend.services.openai_service import extract_receipt_data from backend.schemas import ExtractionResponse, ClaimRecord, UserAccount, ClaimSubmission from dotenv import load_dotenv load_dotenv() app = FastAPI(title="AI-Assisted Data Entry API") # Configure CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # Adjust as needed for Angular frontend allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # In-memory database CLAIMS_DB: List[ClaimRecord] = [] USERS_DB: List[UserAccount] = [] @app.get("/health") async def health_check(): return {"status": "healthy"} @app.get("/api/v1/users", response_model=List[UserAccount]) async def get_users(): return USERS_DB @app.post("/api/v1/users", response_model=UserAccount) async def create_user(user: UserAccount): USERS_DB.append(user) return user @app.post("/api/v1/extract", response_model=ExtractionResponse) async def extract_receipt( file: UploadFile = File(...), user_name: str = Form("Unknown Employee"), department: str = Form("Unknown Department") ): if not file.content_type.startswith("image/"): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="File provided is not an image." ) try: content = await file.read() extraction_result = await extract_receipt_data(content, user_name, department) if extraction_result is None: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Could not extract data from the provided image." ) return extraction_result except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"An error occurred during extraction: {str(e)}" ) @app.post("/api/v1/claims", response_model=ClaimRecord) async def submit_claim( submission_data: ClaimSubmission, user_id: str = Header(...) ): # 1. Find User user = next((u for u in USERS_DB if u.id == user_id), None) if not user: raise HTTPException(status_code=404, detail="User not found") # 2. Financial Guard Logic spent_amount = submission_data.amount_spent remaining = user.medical_allowance amount_claimed = min(spent_amount, remaining) # 3. Update User Balance user.medical_allowance -= amount_claimed # 4. Save Claim claim = ClaimRecord( id=str(uuid.uuid4()), timestamp=datetime.now().isoformat(), submitted_by=user.name, department=user.department, amount_spent=spent_amount, amount_claimed=amount_claimed, provider_name=submission_data.provider_name, visit_date=submission_data.visit_date, extraction_data=submission_data.extraction_data ) CLAIMS_DB.append(claim) return claim @app.get("/api/v1/claims", response_model=List[ClaimRecord]) async def get_claims(): return CLAIMS_DB if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)