Files
MOHPortalTest-AllAgents-All…/qwen/python/merchants_of_hope/api/v1/jobs.py
2025-10-24 14:54:44 -05:00

153 lines
5.3 KiB
Python

"""
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
@router.get("/", response_model=List[JobResponse])
async def get_jobs(skip: int = 0, limit: int = 100, is_active: bool = True, db: Session = Depends(SessionLocal), request: Request = None):
"""Get all jobs for the current tenant"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
query = db.query(JobPosting).filter(JobPosting.tenant_id == tenant_id)
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), request: Request = None):
"""Get a specific job"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
job = db.query(JobPosting).filter(
JobPosting.id == job_id,
JobPosting.tenant_id == tenant_id # Ensure job belongs to current tenant
).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), request: Request = None, user_id: int = 1): # In real app, get from auth context
"""Create a new job posting"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
# Verify user exists and has permission to create job postings
user = db.query(User).filter(
User.id == user_id,
User.tenant_id == tenant_id # Ensure user belongs to current tenant
).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 current 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), request: Request = None):
"""Update a job posting"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
db_job = db.query(JobPosting).filter(
JobPosting.id == job_id,
JobPosting.tenant_id == tenant_id # Ensure job belongs to current tenant
).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), request: Request = None):
"""Delete a job posting (soft delete by setting is_active to False)"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
db_job = db.query(JobPosting).filter(
JobPosting.id == job_id,
JobPosting.tenant_id == tenant_id # Ensure job belongs to current tenant
).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"}