from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, Query from fastapi.responses import JSONResponse from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from db_setup import get_session from tasks.views import Task from users.permissions import PermissionTag, require_permission router = APIRouter() class TaskCreate(BaseModel): title: str priority: str | None = None due_date: datetime | None = None assignee_id: str | None = None # defaults to the caller server-side inbox_id: int | None = None job_post_id: str | None = None class TaskUpdate(BaseModel): title: str | None = None status: str | None = None # open | done — the complete/reopen flip priority: str | None = None due_date: datetime | None = None assignee_id: str | None = None inbox_id: int | None = None job_post_id: str | None = None @router.get("/tasks/fetch") async def fetch_tasks( current_user: dict = Depends(require_permission(PermissionTag.TASKS_VIEW)), status: str | None = Query(None), priority: str | None = Query(None), assignee_id: str | None = Query(None), top: int | None = Query(None), skip: int = Query(0, ge=0), session: AsyncSession = Depends(get_session), ): try: service = Task(session=session) data, total = await service.get_tasks(status, priority, assignee_id, top, skip) return JSONResponse(content={"data": data, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/tasks/assignees/fetch") async def fetch_task_assignees( current_user: dict = Depends(require_permission(PermissionTag.TASKS_VIEW)), session: AsyncSession = Depends(get_session), ): """Assignee picker: active recruiter-role users (role id resolved from the roles table). Separate from /users/fetch so assigning a task never requires rbac_users.view.""" try: service = Task(session=session) data, total = await service.get_assignees() return JSONResponse(content={"data": data, "total": total, "status_code": 200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/tasks/create") async def create_task( payload: TaskCreate, current_user: dict = Depends(require_permission(PermissionTag.TASKS_CREATE)), session: AsyncSession = Depends(get_session), ): try: service = Task(session=session) data = await service.create_task(payload.model_dump(exclude_unset=True), 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.patch("/tasks/update") async def update_task( payload: TaskUpdate, current_user: dict = Depends(require_permission(PermissionTag.TASKS_EDIT)), task_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Task(session=session) data = await service.update_task(task_id, payload.model_dump(exclude_unset=True), 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.delete("/tasks/delete") async def delete_task( current_user: dict = Depends(require_permission(PermissionTag.TASKS_DELETE)), task_id: str = Query(...), session: AsyncSession = Depends(get_session), ): try: service = Task(session=session) data = await service.delete_task(task_id, 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))