from fastapi import APIRouter,Depends from fastapi.responses import JSONResponse from fastapi import HTTPException from db_setup import get_session from job.candidate.views import FileRead from sqlalchemy.ext.asyncio import AsyncSession from pydantic import BaseModel, model_validator from users.permissions import PermissionTag, require_permission from job.job_post.views import JobPost import logging from job.job_post.plugins import PlatformAlias from fastapi import UploadFile, File from dotenv import load_dotenv load_dotenv() logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) router = APIRouter() class JobPostCreate(BaseModel): title: str experience_min: int | None = None experience_max: int | None = None requirements: list[str] = [] optional_skills: list[str] = [] salary: str = "Anonymous" location: str | None = None employment_type: str | None = None platform: str = "linkedin" description: str | None = None platform: str | None = None channel_id: str | None = None mode: str = "addToQueue" due_at: str | None = None @model_validator(mode="after") def validate_mode_and_due_at(self): allowed = {"addToQueue", "shareNow", "customScheduled"} if self.mode not in allowed: raise ValueError(f"mode must be one of {sorted(allowed)}") if self.mode == "customScheduled" and not self.due_at: raise ValueError("due_at is required when mode is customScheduled") return self @router.get("/jobs/alias") async def get_job_alias(): try: alias_lst=[k.name for k in PlatformAlias] return JSONResponse(content={"data":alias_lst,"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.post("/candidate/cv_upload") async def cv_upload( file: UploadFile = File(...), current_user: dict = Depends(require_permission(PermissionTag.CANDIDATES_CREATE)), session: AsyncSession = Depends(get_session), ): try: file_content = await file.read() logger.info(f"Received file: {file.filename} ({len(file_content)} bytes)") service=FileRead(session=session,filename=file.filename,file=file_content) data=await service.read_file(file_content, file.filename) return JSONResponse(content={"data":data,"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.post("/job/post-job") async def post_job( payload: JobPostCreate, current_user: dict = Depends(require_permission(PermissionTag.JOB_BOARD_CREATE)), session: AsyncSession = Depends(get_session), ): try: service=JobPost(session=session) data=await service.post_job(payload.model_dump(),current_user) return JSONResponse(content={"data":data,"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.get("/job/buffer/channels") async def buffer_channels( current_user: dict = Depends(require_permission(PermissionTag.JOB_BOARD_VIEW)), session: AsyncSession = Depends(get_session), ): try: service=JobPost(session=session) data=await service.list_channels() return JSONResponse(content={"data":data,"total":len(data),"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e))