import logging import httpx import json from datetime import datetime, timezone from typing import List, Optional, Dict logger = logging.getLogger('ats_resume_scorer') from backend.core.config import SUPABASE_URL, SUPABASE_KEY def _get_headers(): if not SUPABASE_URL or not SUPABASE_KEY: return None return { "apikey": SUPABASE_KEY, "Authorization": f"Bearer {SUPABASE_KEY}", "Content-Type": "application/json", "Prefer": "return=representation" } async def save_analysis(user_id: str, filename: str, analysis_result: Dict) -> Optional[str]: headers = _get_headers() if not headers: return None def _json_default(o): if hasattr(o, 'model_dump'): return o.model_dump() return str(o) serializable_result = json.loads(json.dumps(analysis_result, default=_json_default)) doc = { "user_id": user_id, "filename": filename, "ats_score": serializable_result.get("ats_score", 0), "keyword_match": serializable_result.get("keyword_match", 0), "missing_keywords": serializable_result.get("missing_keywords", []), "created_at": datetime.now(timezone.utc).isoformat(), "analysis_result": serializable_result, } url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses" try: async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, json=doc) response.raise_for_status() data = response.json() if data and len(data) > 0: inserted_id = str(data[0].get("id")) logger.info(f"Saved analysis for user {user_id}: {inserted_id}") return inserted_id return None except Exception as exc: logger.error(f"Failed to save analysis to Supabase: {exc}") return None async def get_user_history(user_id: str) -> List[Dict]: headers = _get_headers() if not headers: return [] url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses" try: async with httpx.AsyncClient() as client: response = await client.get( url, headers=headers, params={ "user_id": f"eq.{user_id}", "order": "created_at.desc" } ) response.raise_for_status() docs = response.json() results = [] for doc in docs: results.append({ "id": str(doc.get("id")), "filename": doc.get("filename", "resume"), "resume_name": doc.get("filename", "resume"), "job_title": "Software Engineer", "ats_score": doc.get("ats_score", 0), "keyword_match": doc.get("keyword_match", 0), "missing_keywords": doc.get("missing_keywords", []), "date": doc.get("created_at", ""), "created_at": doc.get("created_at", ""), "analysis_result": doc.get("analysis_result", {}), }) return results except Exception as exc: logger.error(f"Failed to fetch history from Supabase: {exc}") return [] async def delete_analysis(analysis_id: str, user_id: str) -> bool: headers = _get_headers() if not headers: return False url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses" try: async with httpx.AsyncClient() as client: response = await client.delete( url, headers=headers, params={ "id": f"eq.{analysis_id}", "user_id": f"eq.{user_id}" } ) response.raise_for_status() return True except Exception as exc: logger.error(f"Failed to delete analysis {analysis_id}: {exc}") return False