From bec592e7631930dec376421d83cb78885faac556 Mon Sep 17 00:00:00 2001 From: Anuj Gupta <84966248+Anuj-Gupta4@users.noreply.github.com> Date: Thu, 26 Dec 2024 10:37:14 +0545 Subject: [PATCH] Send notification message to new project manager upon assignment and refactor assignment code (#2016) * feat(projects): send notification message to new project manager upon assignment and refactor add manager endpoint * fix(projects): update project URL scheme from http to https in notification message * fix(tests): update project summary test to assert short_description instead of description --- src/backend/app/projects/project_crud.py | 39 ++++++++++++++++++++-- src/backend/app/projects/project_routes.py | 24 ++++++++++--- src/backend/tests/test_projects_routes.py | 2 +- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/backend/app/projects/project_crud.py b/src/backend/app/projects/project_crud.py index 4288d478aa..7bb316303c 100644 --- a/src/backend/app/projects/project_crud.py +++ b/src/backend/app/projects/project_crud.py @@ -21,6 +21,7 @@ import uuid from io import BytesIO from pathlib import Path +from textwrap import dedent from traceback import format_exc from typing import Optional, Union @@ -28,17 +29,19 @@ import geojson_pydantic import requests from asgiref.sync import async_to_sync -from fastapi import HTTPException +from fastapi import HTTPException, Request from loguru import logger as log from osm_fieldwork.basemapper import create_basemap_file +from osm_login_python.core import Auth from osm_rawdata.postgres import PostgresClient from psycopg import Connection from psycopg.rows import class_row +from app.auth.providers.osm import get_osm_token, send_osm_message from app.central import central_crud, central_schemas from app.config import settings from app.db.enums import BackgroundTaskStatus, HTTPStatus, XLSFormType -from app.db.models import DbBackgroundTask, DbBasemap, DbProject, DbTask +from app.db.models import DbBackgroundTask, DbBasemap, DbProject, DbTask, DbUser from app.db.postgis_utils import ( check_crs, featcol_keep_single_geom_type, @@ -932,3 +935,35 @@ async def get_project_users_plus_contributions(db: Connection, project_id: int): ) as cur: await cur.execute(query, {"project_id": project_id}) return await cur.fetchall() + + +async def send_project_manager_message( + request: Request, + project: DbProject, + new_manager: DbUser, + osm_auth: Auth, +): + """Send message to the new project manager after assigned.""" + log.info(f"Sending message to new project manager ({new_manager.username}).") + + osm_token = get_osm_token(request, osm_auth) + project_url = f"{settings.FMTM_DOMAIN}/project/{project.id}" + if not project_url.startswith("http"): + project_url = f"https://{project_url}" + + message_content = dedent(f""" + You have been assigned to the project **{project.name}** as a + manager. You can now manage the project and its tasks. + + [Click here to view the project]({project_url}) + + Thank you for being a part of our platform! + """) + + send_osm_message( + osm_token=osm_token, + osm_id=new_manager.id, + title=f"You have been assigned to project {project.name} as a manager", + body=message_content, + ) + log.info(f"Message sent to new project manager ({new_manager.username}).") diff --git a/src/backend/app/projects/project_routes.py b/src/backend/app/projects/project_routes.py index 812344828c..4dcba39857 100644 --- a/src/backend/app/projects/project_routes.py +++ b/src/backend/app/projects/project_routes.py @@ -32,6 +32,7 @@ Form, HTTPException, Query, + Request, Response, UploadFile, ) @@ -47,6 +48,7 @@ from app.auth.auth_deps import login_required, mapper_login_required from app.auth.auth_schemas import AuthUser, OrgUserDict, ProjectUserDict +from app.auth.providers.osm import init_osm_auth from app.auth.roles import mapper, org_admin, project_manager from app.central import central_crud, central_deps, central_schemas from app.config import settings @@ -62,6 +64,7 @@ DbOdkEntities, DbProject, DbTask, + DbUser, DbUserRole, ) from app.db.postgis_utils import ( @@ -74,6 +77,7 @@ from app.organisations import organisation_deps from app.projects import project_crud, project_deps, project_schemas from app.s3 import delete_all_objs_under_prefix +from app.users.user_deps import get_user router = APIRouter( prefix="/projects", @@ -727,19 +731,31 @@ async def upload_custom_extract( @router.post("/add-manager") async def add_new_project_manager( + request: Request, db: Annotated[Connection, Depends(db_conn)], - project_user_dict: Annotated[ProjectUserDict, Depends(project_manager)], + background_tasks: BackgroundTasks, + new_manager: Annotated[DbUser, Depends(get_user)], + org_user_dict: Annotated[OrgUserDict, Depends(org_admin)], + osm_auth=Depends(init_osm_auth), ): """Add a new project manager. - The logged in user must be either the admin of the organisation or a super admin. + The logged in user must be the admin of the organisation. """ await DbUserRole.create( db, - project_user_dict["project"].id, - project_user_dict["user"].id, + org_user_dict["project"].id, + new_manager.id, ProjectRole.PROJECT_MANAGER, ) + + background_tasks.add_task( + project_crud.send_project_manager_message, + request=request, + project=org_user_dict["project"], + new_manager=new_manager, + osm_auth=osm_auth, + ) return Response(status_code=HTTPStatus.OK) diff --git a/src/backend/tests/test_projects_routes.py b/src/backend/tests/test_projects_routes.py index f53a8c26ea..2fc5e4ffa5 100644 --- a/src/backend/tests/test_projects_routes.py +++ b/src/backend/tests/test_projects_routes.py @@ -431,7 +431,7 @@ async def test_project_summaries(client, project): assert first_project["id"] == project.id assert first_project["name"] == project.name - assert first_project["description"] == project.description + assert first_project["short_description"] == project.short_description assert first_project["hashtags"] == project.hashtags assert first_project["organisation_id"] == project.organisation_id