""" Jobs API routes """ from fastapi import APIRouter, Depends, HTTPException, status, Request from typing import List from pydantic import BaseModel from sqlalchemy.orm import Session from ...database import SessionLocal from ...models import JobPosting, User from ...config.settings import settings router = APIRouter() # Pydantic models for jobs class JobCreate(BaseModel): title: str description: str requirements: str location: str = None salary_min: int = None salary_max: int = None is_remote: bool = False class JobUpdate(BaseModel): title: str = None description: str = None requirements: str = None location: str = None salary_min: int = None salary_max: int = None is_active: bool = None is_remote: bool = None class JobResponse(BaseModel): id: int title: str description: str requirements: str location: str salary_min: int salary_max: int is_active: bool is_remote: bool tenant_id: int created_by_user_id: int class Config: from_attributes = True json_schema_extra = { "example": { "id": 1, "title": "Software Engineer", "description": "We are looking for a skilled software engineer...", "requirements": "Bachelor's degree in Computer Science...", "location": "New York, NY", "salary_min": 8000000, # in cents "salary_max": 12000000, # in cents "is_active": True, "is_remote": True, "tenant_id": 1, "created_by_user_id": 1 } } @router.get("/", response_model=List[JobResponse]) async def get_jobs(skip: int = 0, limit: int = 100, is_active: bool = True, db: Session = Depends(SessionLocal)): """Get all jobs""" query = db.query(JobPosting) if is_active is not None: query = query.filter(JobPosting.is_active == is_active) jobs = query.offset(skip).limit(limit).all() return jobs @router.get("/{job_id}", response_model=JobResponse) async def get_job(job_id: int, db: Session = Depends(SessionLocal)): """Get a specific job""" job = db.query(JobPosting).filter( JobPosting.id == job_id, ).first() if not job: raise HTTPException(status_code=404, detail="Job not found") if not job.is_active: raise HTTPException(status_code=404, detail="Job not found") return job @router.post("/", response_model=JobResponse) async def create_job(job: JobCreate, db: Session = Depends(SessionLocal), user_id: int = 1): # Default for testing """Create a new job posting""" # For testing, use default tenant tenant_id = 1 # Default tenant for testing # Verify user exists and has permission to create job postings user = db.query(User).filter( User.id == user_id ).first() if not user or user.role not in ["job_provider", "admin"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not authorized to create job postings" ) db_job = JobPosting( title=job.title, description=job.description, requirements=job.requirements, location=job.location, salary_min=job.salary_min, salary_max=job.salary_max, is_remote=job.is_remote, tenant_id=tenant_id, # Use default tenant created_by_user_id=user_id ) db.add(db_job) db.commit() db.refresh(db_job) return db_job @router.put("/{job_id}", response_model=JobResponse) async def update_job(job_id: int, job_update: JobUpdate, db: Session = Depends(SessionLocal)): """Update a job posting""" db_job = db.query(JobPosting).filter( JobPosting.id == job_id, ).first() if not db_job: raise HTTPException(status_code=404, detail="Job not found") # Update fields if provided for field, value in job_update.model_dump(exclude_unset=True).items(): setattr(db_job, field, value) db.commit() db.refresh(db_job) return db_job @router.delete("/{job_id}") async def delete_job(job_id: int, db: Session = Depends(SessionLocal)): """Delete a job posting (soft delete by setting is_active to False)""" db_job = db.query(JobPosting).filter( JobPosting.id == job_id, ).first() if not db_job: raise HTTPException(status_code=404, detail="Job not found") db_job.is_active = False db.commit() return {"message": "Job deactivated successfully"}