From df9ceb07140280a4be94db8524333a2a107ad0a2 Mon Sep 17 00:00:00 2001 From: Pradip-p Date: Mon, 29 Jul 2024 15:40:08 +0545 Subject: [PATCH] feat: add endpoint to list all tasks for drone user with role validation --- src/backend/app/tasks/task_crud.py | 41 ++++++++++++++++++++++++++- src/backend/app/tasks/task_routes.py | 23 ++++++++++++++- src/backend/app/tasks/task_schemas.py | 9 ++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/backend/app/tasks/task_crud.py b/src/backend/app/tasks/task_crud.py index dab10274..2ae11ff2 100644 --- a/src/backend/app/tasks/task_crud.py +++ b/src/backend/app/tasks/task_crud.py @@ -1,6 +1,45 @@ import uuid from databases import Database -from app.models.enums import State +from app.models.enums import HTTPStatus, State +from fastapi import HTTPException +from loguru import logger as log + + +async def get_tasks_by_user(user_id: str, db: Database): + try: + query = """WITH task_details AS ( + SELECT + tasks.id AS task_id, + ST_Area(ST_Transform(tasks.outline, 4326)) / 1000000 AS task_area, + task_events.created_at, + task_events.state + FROM + task_events + JOIN + tasks ON task_events.task_id = tasks.id + WHERE + task_events.user_id = :user_id + ) + SELECT + task_details.task_id, + task_details.task_area, + task_details.created_at, + CASE + WHEN task_details.state = 'REQUEST_FOR_MAPPING' THEN 'ongoing' + WHEN task_details.state = 'UNLOCKED_DONE' THEN 'completed' + WHEN task_details.state IN ('UNLOCKED_TO_VALIDATE', 'LOCKED_FOR_VALIDATION') THEN 'mapped' + ELSE 'unknown' + END AS state + FROM task_details + """ + records = await db.fetch_all(query, values={"user_id": user_id}) + return records + + except Exception as e: + log.exception(e) + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Retrieval failed" + ) from e async def get_all_tasks(db: Database, project_id: uuid.UUID): diff --git a/src/backend/app/tasks/task_routes.py b/src/backend/app/tasks/task_routes.py index bc673b04..88ea49a5 100644 --- a/src/backend/app/tasks/task_routes.py +++ b/src/backend/app/tasks/task_routes.py @@ -1,7 +1,7 @@ import uuid from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException from app.config import settings -from app.models.enums import EventType, State +from app.models.enums import EventType, State, UserRole from app.tasks import task_schemas, task_crud from app.users.user_deps import login_required from app.users.user_schemas import AuthUser @@ -19,6 +19,27 @@ ) +@router.get("/", response_model=list[task_schemas.UserTasksStatsOut]) +async def list_tasks( + db: Database = Depends(database.get_db), + user_data: AuthUser = Depends(login_required), +): + """Get all tasks for a drone user.""" + + user_id = user_data.id + query = """SELECT role FROM user_profile WHERE user_id = :user_id""" + record = await db.fetch_one(query, {"user_id": user_id}) + if not record: + raise HTTPException(status_code=404, detail="User profile not found") + + if record.role != UserRole.DRONE_PILOT.name: + raise HTTPException( + status_code=403, detail="Access forbidden for non-DRONE_PILOT users" + ) + + return await task_crud.get_tasks_by_user(user_id, db) + + @router.get("/states/{project_id}") async def task_states(project_id: uuid.UUID, db: Database = Depends(database.get_db)): """Get all tasks states for a project.""" diff --git a/src/backend/app/tasks/task_schemas.py b/src/backend/app/tasks/task_schemas.py index ef38f50e..3f60671a 100644 --- a/src/backend/app/tasks/task_schemas.py +++ b/src/backend/app/tasks/task_schemas.py @@ -1,6 +1,15 @@ from pydantic import BaseModel from app.models.enums import EventType +import uuid +from datetime import datetime class NewEvent(BaseModel): event: EventType + + +class UserTasksStatsOut(BaseModel): + task_id: uuid.UUID + task_area: float + created_at: datetime + state: str