Skip to content

Commit

Permalink
Merge pull request #6643 from hotosm/fastapi-refactor
Browse files Browse the repository at this point in the history
Revert user task fixed and get latest task activity now returns disti…
  • Loading branch information
prabinoid authored Nov 20, 2024
2 parents a88a903 + f14a671 commit bb67366
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 63 deletions.
22 changes: 18 additions & 4 deletions backend/api/tasks/actions.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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),
):
Expand Down Expand Up @@ -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(
Expand Down
36 changes: 10 additions & 26 deletions backend/services/stats_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)

Expand Down
34 changes: 1 addition & 33 deletions backend/services/validator_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand All @@ -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(
Expand Down

0 comments on commit bb67366

Please sign in to comment.