from typing import List, Dict, Optional, Any from pydantic import BaseModel, Field from datetime import datetime class JobPosting(BaseModel): id: str = Field(..., description="Unique job identifier, e.g. JOB-BLR-101") title: str = Field(..., description="Job title, e.g., Senior Backend Engineer (Go/Distributed Systems)") company: str = Field(..., description="Company name") tech_domain: str = Field(default="Backend Engineering", description="Domain: Backend, Frontend, Full Stack, DevOps/Cloud, Data Engineering, AI/ML & GenAI, Mobile, Cybersecurity") city: str = Field(default="Bengaluru", description="City location: Bengaluru, Pune, Hyderabad, Gurgaon, Mumbai, Chennai, Remote") area: str = Field(default="Indiranagar", description="Locality or Tech Park, e.g. Outer Ring Road, Hinjawadi, HITEC City, Cyber City") salary_min_lpa: float = Field(..., description="Minimum salary in Lakhs Per Annum (LPA)") salary_max_lpa: float = Field(..., description="Maximum salary in Lakhs Per Annum (LPA)") experience_min_years: int = Field(..., description="Minimum experience required in years") experience_max_years: int = Field(..., description="Maximum experience requested in years") tech_stack: List[str] = Field(default_factory=list, description="Extracted tech stack, e.g., ['Go', 'Kubernetes', 'gRPC', 'PostgreSQL', 'Redis']") requirements: str = Field(..., description="Full text job description and responsibilities") work_mode: str = Field(default="Hybrid", description="Hybrid, On-site, or Remote") company_tier: str = Field(default="Product Unicorn / Enterprise", description="Company tier") posted_date: str = Field(default_factory=lambda: datetime.now().strftime("%Y-%m-%d")) url: Optional[str] = Field(default="https://techradar.ai/jobs", description="Job posting URL") semantic_score: Optional[float] = Field(default=None, description="Relevance score from semantic vector search") class SkillGapReport(BaseModel): target_job_id: str job_title: str company: str city: str tech_domain: str match_percentage: float = Field(..., description="Overall candidate match percentage (0-100%)") matched_skills: List[str] = Field(default_factory=list, description="Skills present in candidate profile & JD") missing_skills: List[str] = Field(default_factory=list, description="Critical skills in JD missing from candidate profile") high_priority_gaps: List[str] = Field(default_factory=list, description="Top deal-breaker missing skills for this role") recommended_action_plan: List[Dict[str, str]] = Field(default_factory=list, description="Actionable micro-projects to bridge gaps") estimated_learning_hours: int = Field(default=20, description="Estimated effort to reach 90%+ match") class ResumePatch(BaseModel): target_job_id: str job_title: str company: str ats_compatibility_score: float = Field(..., description="Score out of 100 for ATS parsing") tailored_bullets: List[Dict[str, str]] = Field( ..., description="List of dicts with 'original', 'tailored', and 'rationale'" ) added_keywords: List[str] = Field(default_factory=list, description="Keywords injected for ATS optimization") class CityMarketInsights(BaseModel): city: str tech_domain: str total_active_jobs: int avg_salary_lpa: float salary_range: str top_demanded_frameworks: List[Dict[str, Any]] top_hiring_hubs: List[Dict[str, Any]] top_employers: List[str] growth_trend: str class InterviewQuestion(BaseModel): question: str category: str difficulty: str ideal_answer_points: List[str] company_context: Optional[str] = None class InterviewPrepKit(BaseModel): job_id: str job_title: str company: str city: str tech_domain: str technical_questions: List[InterviewQuestion] system_design_challenge: Dict[str, Any] prep_tips: List[str]