158 lines
5.8 KiB
Python
158 lines
5.8 KiB
Python
from datetime import datetime
|
|
from fastapi import APIRouter,Depends,Query
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi import HTTPException
|
|
from openai import APIError
|
|
from pydantic import BaseModel
|
|
from db_setup import get_session
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from analytics.ask import ask_analytics
|
|
from analytics.views import Analytics
|
|
from users.permissions import PermissionTag,require_permission
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class AskRequest(BaseModel):
|
|
question: str
|
|
|
|
|
|
@router.get("/analytics/kpis/fetch")
|
|
async def fetch_kpis(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_kpis(from_date,to_date,department,recruiter_id)
|
|
return JSONResponse(content={"data":data,"total":1,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.get("/analytics/funnel/fetch")
|
|
async def fetch_funnel(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_funnel(from_date,to_date,department,recruiter_id)
|
|
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))
|
|
|
|
|
|
@router.get("/analytics/hiring-trend/fetch")
|
|
async def fetch_hiring_trend(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
months: int = Query(7,ge=1),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_hiring_trend(months,from_date,to_date,department,recruiter_id)
|
|
return JSONResponse(content={"data":data,"total":1,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.get("/analytics/source-performance/fetch")
|
|
async def fetch_source_performance(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_source_performance(from_date,to_date,department,recruiter_id)
|
|
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))
|
|
|
|
|
|
@router.get("/analytics/applications-per-job/fetch")
|
|
async def fetch_applications_per_job(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
top: int = Query(10,ge=1),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_applications_per_job(top,from_date,to_date,department,recruiter_id)
|
|
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))
|
|
|
|
|
|
@router.post("/analytics/ask")
|
|
async def ask(
|
|
payload: AskRequest,
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
data=await ask_analytics(session,payload.question)
|
|
return JSONResponse(content={"data":data,"total":1,"status_code":200})
|
|
except HTTPException:
|
|
raise
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=422,detail=str(e))
|
|
except (APIError,RuntimeError) as e:
|
|
# The governed queries are fine — it is the language model that is
|
|
# unreachable or misconfigured, so say that instead of a bare 500.
|
|
raise HTTPException(status_code=503,detail=f"AI assistant unavailable: {e}")
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500,detail=str(e))
|
|
|
|
|
|
@router.get("/analytics/recruiter-performance/fetch")
|
|
async def fetch_recruiter_performance(
|
|
current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)),
|
|
top: int = Query(5,ge=1),
|
|
from_date: datetime | None = Query(None),
|
|
to_date: datetime | None = Query(None),
|
|
department: str | None = Query(None),
|
|
recruiter_id: str | None = Query(None),
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
try:
|
|
service=Analytics(session=session)
|
|
data=await service.get_recruiter_performance(top,from_date,to_date,department,recruiter_id)
|
|
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))
|