diff --git a/backend/api/tasks/actions.py b/backend/api/tasks/actions.py index 82001e1453..dbf04148d1 100644 --- a/backend/api/tasks/actions.py +++ b/backend/api/tasks/actions.py @@ -1,5 +1,5 @@ from databases import Database -from fastapi import APIRouter, Depends, Request +from fastapi import APIRouter, Depends, Query, Request from fastapi.responses import JSONResponse from loguru import logger @@ -1141,6 +1141,14 @@ async def post( async def post( request: Request, project_id: int, + username: str | None = Query( + None, description="Username to revert tasks for", example="test" + ), + action: str | None = Query( + None, + description="Action to revert tasks for. Can be BADIMAGERY or VALIDATED", + example="BADIMAGERY", + ), db: Database = Depends(get_db), user: AuthUserDTO = Depends(login_required), ): @@ -1196,9 +1204,15 @@ async def post( description: Internal Server Error """ try: - request_data = await request.json() - action = request_data.get("action", None) - username = request_data.get("username", None) + if not (username or action): + return JSONResponse( + content={ + "Error": "Unable to revert tasks", + "SubCode": "InvalidData", + }, + status_code=400, + ) + if username: user = await UserService.get_user_by_username(username, db) revert_dto = RevertUserTasksDTO( diff --git a/backend/services/stats_service.py b/backend/services/stats_service.py index b0c40066fb..be4bdad7ac 100644 --- a/backend/services/stats_service.py +++ b/backend/services/stats_service.py @@ -294,7 +294,7 @@ async def get_last_activity( ) -> ProjectLastActivityDTO: """Gets the last activity for a project's tasks""" - # First subquery: Fetch the latest action date per task, excluding comments + # Subquery: Fetch latest actions for each task, excluding comments subquery_latest_action = """ SELECT DISTINCT ON (th.task_id) th.task_id, @@ -306,49 +306,33 @@ async def get_last_activity( ORDER BY th.task_id, th.action_date DESC """ - latest_actions = await db.fetch_all( - subquery_latest_action, - {"project_id": project_id, "comment_action": "COMMENT"}, - ) - - # Mapping the latest actions by task_id - latest_actions_map = {item["task_id"]: item for item in latest_actions} - - # Second subquery: Fetch the task statuses - query_task_statuses = """ + # Main query: Join task statuses with latest actions and user details + query_task_statuses = f""" SELECT - t.id as task_id, + t.id AS task_id, t.task_status, - u.username, - la.action_date + la.action_date, + u.username AS action_by FROM tasks t - LEFT JOIN ( - SELECT - th.task_id, - th.action_date, - th.user_id - FROM task_history th - WHERE th.project_id = :project_id - AND th.action != :comment_action - ORDER BY th.task_id, th.action_date DESC - ) la ON la.task_id = t.id + LEFT JOIN ({subquery_latest_action}) la ON la.task_id = t.id LEFT JOIN users u ON u.id = la.user_id WHERE t.project_id = :project_id ORDER BY t.id """ + # Execute the query results = await db.fetch_all( query_task_statuses, {"project_id": project_id, "comment_action": "COMMENT"} ) - # Creating DTO + # Create DTO dto = ProjectLastActivityDTO(activity=[]) for row in results: task_status_dto = TaskStatusDTO( task_id=row["task_id"], task_status=TaskStatus(row["task_status"]).name, action_date=row["action_date"], - action_by=row["username"], + action_by=row["action_by"], ) dto.activity.append(task_status_dto) diff --git a/backend/services/validator_service.py b/backend/services/validator_service.py index 6aef2bf0a7..d97c1b047e 100644 --- a/backend/services/validator_service.py +++ b/backend/services/validator_service.py @@ -2,8 +2,8 @@ import datetime from databases import Database -from sqlalchemy import text from loguru import logger +from sqlalchemy import text from backend.exceptions import NotFound from backend.models.dtos.mapping_dto import TaskDTOs @@ -512,37 +512,6 @@ async def get_task_mapping_issues(task_to_unlock: dict): ) ) - # @staticmethod - # async def revert_user_tasks(revert_dto: RevertUserTasksDTO, db: Database): - # """ - # Reverts tasks with supplied action to previous state by specific user - # :raises ValidatorServiceError - # """ - # if await ProjectAdminService.is_user_action_permitted_on_project( - # revert_dto.action_by, revert_dto.project_id, db - # ): - # query = Task.query.filter( - # Task.project_id == revert_dto.project_id, - # Task.task_status == TaskStatus[revert_dto.action].value, - # ) - # if TaskStatus[revert_dto.action].value == TaskStatus.BADIMAGERY.value: - # query = query.filter(Task.mapped_by == revert_dto.user_id) - # else: - # query = query.filter(Task.validated_by == revert_dto.user_id) - - # tasks_to_revert = query.all() - # for task in tasks_to_revert: - # task = MappingService.undo_mapping( - # revert_dto.project_id, - # task.id, - # revert_dto.user_id, - # revert_dto.preferred_locale, - # ) - # else: - # raise ValidatorServiceError( - # "UserActionNotPermitted- User not permitted to revert tasks" - # ) - @staticmethod async def revert_user_tasks(revert_dto: RevertUserTasksDTO, db: Database): """ @@ -568,7 +537,6 @@ async def revert_user_tasks(revert_dto: RevertUserTasksDTO, db: Database): else: query += " AND validated_by = :user_id" values["user_id"] = revert_dto.user_id - tasks_to_revert = await db.fetch_all(query=query, values=values) for task in tasks_to_revert: await MappingService.undo_mapping(