diff --git a/src/organisation/router.py b/src/organisation/router.py index d3c27f3..4798022 100644 --- a/src/organisation/router.py +++ b/src/organisation/router.py @@ -38,8 +38,8 @@ from src.organisation.models import Organisation as Org from src.organisation.schemas import OrgPostOrgRequest, OrgPatchQuestionnaireRequest, OrgPatchStatusRequest, \ OrgPatchContactRequest, \ OrgPostUserRequest, OrgGetUserResponse, OrgGetContactResponse, OrgGetOrgResponse, OrgPatchRootRequest, \ - OrgGetGroupResponse, OrgDeleteUserRequest, OrgDeleteOrgRequest - + OrgGetGroupResponse, OrgDeleteUserRequest, OrgDeleteOrgRequest, OrgPostOrgResponse, OrgPatchQuestionnaireResponse, \ + OrgPatchStatusResponse, OrgPostUserResponse, OrgPatchRootResponse router = APIRouter( prefix="/org", @@ -73,6 +73,7 @@ async def get_org_by_id(org_model: org_model_root_claim_query_dependency): @router.post("/", summary="Create new organisation.", status_code=status.HTTP_201_CREATED, + response_model=OrgPostOrgResponse, responses={ status.HTTP_201_CREATED: {"description": "Successfully created organisation."}, status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, @@ -80,7 +81,6 @@ async def get_org_by_id(org_model: org_model_root_claim_query_dependency): status.HTTP_409_CONFLICT: {"description": "Organisation with this name already exists."}, }) async def create_org(db: db_dependency, user_model: user_model_claims_dependency, request_model: OrgPostOrgRequest): - # TODO: Response model if request_model.intake_questionnaire: intake_questionnaire = request_model.intake_questionnaire.model_dump() else: @@ -103,46 +103,53 @@ async def create_org(db: db_dependency, user_model: user_model_claims_dependency db.add(contact_model) db.flush() org_model.__setattr__(contact_type, contact_model.id) + response = OrgPostOrgResponse(**org_model.__dict__) db.commit() + return response @router.patch("/questionnaire", summary="Update questionnaire.", status_code=status.HTTP_200_OK, + response_model=OrgPatchQuestionnaireResponse, responses={ status.HTTP_200_OK: {"description": "Successfully updated questionnaire."}, status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, }) -async def update_questionnaire(db: db_dependency, org_model: org_model_root_claim_query_dependency, request_model: OrgPatchQuestionnaireRequest): +async def update_questionnaire(db: db_dependency, org_model: org_model_root_claim_body_dependency, request_model: OrgPatchQuestionnaireRequest): """ Route for updating questionnaire. The partial bool allows for submission of partially completed questionnaire and/or final "are you sure" check before setting the org to be in "submitted" status, awaiting admin approval. """ - # TODO: Response model org_model.intake_questionnaire = request_model.intake_questionnaire.model_dump() # Allows for partially completed questionnaires to be saved without being submitted for review if not request_model.partial: org_model.status = "submitted" + db.flush() + response = OrgPatchQuestionnaireResponse(**org_model.__dict__) db.commit() + return response @router.patch("/status", summary="Update status of organisation.", status_code=status.HTTP_200_OK, + response_model=OrgPatchStatusResponse, responses={ status.HTTP_200_OK: {"description": "Successfully updated organisation status."}, status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be super admin."}, }) async def update_status(db: db_dependency, org_model: org_model_body_dependency, su: super_admin_dependency, request_model: OrgPatchStatusRequest): - # TODO: Response model org_model.status = request_model.status - + db.flush() + response = OrgPatchStatusResponse(**org_model.__dict__) db.commit() + return response @router.get("/users", @@ -159,8 +166,9 @@ async def get_users(org_model: org_model_root_claim_query_dependency): @router.post("/users", - summary="All user to the organisation.", + summary="Add user to the organisation.", status_code=status.HTTP_200_OK, + response_model=OrgPostUserResponse, responses={ status.HTTP_200_OK: {"description": "Successfully added user to the organisation."}, status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be org root user."}, @@ -168,11 +176,13 @@ async def get_users(org_model: org_model_root_claim_query_dependency): status.HTTP_409_CONFLICT: {"description": "User is already a member of the organisation."}, }) async def add_user_to_org(db: db_dependency, org_model: org_model_root_claim_body_dependency, user_model: user_model_body_dependency, request_model: OrgPostUserRequest): - # TODO: response model if user_model in org_model.user_rel: raise Conflict(message="User already a part of this organisation") org_model.user_rel.append(user_model) + db.flush() + response = {"users": [user.email for user in org_model.user_rel]} db.commit() + return response @router.delete("/", @@ -191,15 +201,19 @@ async def delete_organisation_by_id(db: db_dependency, org_model: org_model_body @router.patch("/root_user", summary="Update the root user of the organisation.", status_code=status.HTTP_200_OK, + response_model=OrgPatchRootResponse, responses={ status.HTTP_200_OK: {"description": "Successfully updated root user."}, status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, status.HTTP_401_UNAUTHORIZED: {"description": "Not authorised. Must be super admin."}, }) async def update_root_user(db: db_dependency, org_model: org_model_body_dependency, user_model: user_model_body_dependency, su: super_admin_dependency, request_model: OrgPatchRootRequest): - # TODO: response model + # TODO: verify new user is already an org member org_model.root_user_rel = user_model + db.flush() + response = OrgPatchRootResponse(**org_model.__dict__) db.commit() + return response @router.get("/groups", @@ -224,7 +238,6 @@ async def get_org_groups(org_model: org_model_root_claim_query_dependency): status.HTTP_422_UNPROCESSABLE_CONTENT: {"description": "Invalid data in request."}, }) async def remove_user_from_org(db: db_dependency, org_model: org_model_root_claim_body_dependency, user_model: user_model_body_dependency, request_model: OrgDeleteUserRequest): - # TODO: response model if user_model not in org_model.user_rel: return diff --git a/src/organisation/schemas.py b/src/organisation/schemas.py index 0fb13c5..3620e38 100644 --- a/src/organisation/schemas.py +++ b/src/organisation/schemas.py @@ -18,9 +18,9 @@ from src.organisation.constants import Status, ContactType class Questionnaire(CustomBaseModel): - question_one: str - question_two: str - question_three: str + question_one: Optional[str] = None + question_two: Optional[str] = None + question_three: Optional[str] = None class OrgIDMixin(CustomBaseModel): organisation_id: int @@ -30,13 +30,26 @@ class OrgPostOrgRequest(CustomBaseModel): name: str intake_questionnaire: Optional[Questionnaire] = None +class OrgPostOrgResponse(CustomBaseModel): + name: str + status: Status + class OrgPatchQuestionnaireRequest(OrgIDMixin): intake_questionnaire: Questionnaire partial: bool +class OrgPatchQuestionnaireResponse(CustomBaseModel): + name: str + intake_questionnaire: Questionnaire + status: Status + class OrgPatchStatusRequest(OrgIDMixin): status: Status +class OrgPatchStatusResponse(CustomBaseModel): + name: str + status: Status + class OrgPatchContactRequest(OrgIDMixin): contact_type: ContactType @@ -56,12 +69,19 @@ class OrgPatchContactRequest(OrgIDMixin): class OrgPostUserRequest(OrgIDMixin, UserIDMixin): pass +class OrgPostUserResponse(CustomBaseModel): + users: list[str] + class OrgDeleteUserRequest(OrgIDMixin, UserIDMixin): pass class OrgPatchRootRequest(OrgIDMixin, UserIDMixin): pass +class OrgPatchRootResponse(CustomBaseModel): + name: str + root_user_email: str + class OrgGetUserResponse(CustomBaseModel): users: list[str]