From ef80222b154f8846b527a770a8fcb4fdc029e90e Mon Sep 17 00:00:00 2001 From: TaeyeonKim Date: Thu, 20 Feb 2025 20:36:32 +0900 Subject: [PATCH] =?UTF-8?q?Refactor:=20=EC=A7=80=EC=A0=95=EA=B2=AC?= =?UTF-8?q?=EC=A0=81=20=EC=9A=94=EC=B2=AD=20=ED=94=8C=EB=9E=9C=EC=9D=98=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=EC=BF=BC=EB=A6=AC=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A7=80=EC=A0=95=EA=B2=AC=EC=A0=81=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=EC=97=90=20=EC=84=9C=EB=B9=84=EC=8A=A4=EC=A7=80?= =?UTF-8?q?=EC=97=AD=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httpTest/plan.http | 15 ++++++++++++--- httpTest/user.http | 9 ++++++++- src/common/constants/errorMessage.enum.ts | 1 + src/common/domains/plan/plan.domain.ts | 4 ++++ src/common/domains/plan/plan.interface.ts | 2 ++ src/common/types/plan/plan.type.ts | 2 +- src/modules/plan/plan.repository.ts | 2 +- src/modules/plan/plan.service.ts | 7 +++++++ 8 files changed, 36 insertions(+), 6 deletions(-) diff --git a/httpTest/plan.http b/httpTest/plan.http index 60716f6..3b15b50 100644 --- a/httpTest/plan.http +++ b/httpTest/plan.http @@ -1,8 +1,11 @@ @HOST_NAME=http://localhost:4000/plans @SERVER_NAME=https://www.goforme.duckdns.org/plans @MAKER1_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwMzJkN2JkNC0xMTZjLTQ2N2ItOTM1Mi1hMTRiMGQ0OTRlZjkiLCJyb2xlIjoiTUFLRVIiLCJpYXQiOjE3MzgyODY3MDAsImV4cCI6MTc0MTc0MjcwMH0.7SDoUJEj6C3ucUbJhqqaPiB_obs-iuhXdKWcuInxmKM +@MAKER2_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJlZjg0NjUxOS0yYjczLTRiZTQtODA3ZS1mNmVmMWMwN2ViNjAiLCJyb2xlIjoiTUFLRVIiLCJpYXQiOjE3NDAwNTEwMTksImV4cCI6MTc0MzUwNzAxOX0.di5lEQVNKdhkyXaEoKSITPHy1Q-m3MA64faZo_s3RNk +@MAKER3_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhMDhkOTg1Ni1hZGZhLTRmODMtOWU5YS00ODQwMWYzZDBlZjMiLCJyb2xlIjoiTUFLRVIiLCJpYXQiOjE3Mzg2Nzc3NjAsImV4cCI6MTc0MjEzMzc2MH0.SFh1raM_FaliSjm3QlqJYR0OMgzasmc9_8Qj3Nyk5YI @DREAMER1_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2Njg4NWEzYy01MGY0LTQyN2ItOGE5Mi0zNzAyYzY5NzZmYjAiLCJyb2xlIjoiRFJFQU1FUiIsImlhdCI6MTczODMxNjA4OSwiZXhwIjoxNzQxNzcyMDg5fQ.eq2atkVBmm8RiGC1PYqBwCXP14hukjyElCkdx_PHOIo @DREAMER2_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTVkNDYzZS0zN2I2LTQxMGItOTA2MS0xMWE5ZDY4MjJiZGQiLCJyb2xlIjoiRFJFQU1FUiIsImlhdCI6MTczODg1MTMwNCwiZXhwIjoxNzQyMzA3MzA0fQ.HAP5l-hpW9GYpNEZJD1LZfYc0ydReNXN_CzMye8pIpw +@asdf2_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJkZjMyMTlmZC1mOTU5LTQ4NGYtODhlNi00YjBjYTA0MDc1YzEiLCJyb2xlIjoiRFJFQU1FUiIsImlhdCI6MTc0MDA0NTkxNCwiZXhwIjoxNzQzNTAxOTE0fQ.dQtT2FX7cdl7vQbwUuWgSCKrtH2olUl7fDOmcDstyL4 @PLAN1_ID=b198135d-9865-445b-a04b-742ca9939ee1 @CONFIRMED_PLAN1=9004bc52-a8b0-4587-af53-59914168582f @CONFIRMED_PLAN2=6d201a98-1d06-4497-806a-fa123599019a @@ -56,11 +59,12 @@ Authorization: Bearer {{DREAMER1_TOKEN}} Content-Type: application/json { - "assigneeId": "ef846519-2b73-4be4-807e-f6ef1c07eb60" + //"assigneeId": "ef846519-2b73-4be4-807e-f6ef1c07eb60" + "assigneeId": "a08d9856-adfa-4f83-9e9a-48401f3d0ef3" } ### DELETE {{HOST_NAME}}/16865772-f792-4bb6-8ac8-504fcb4064e3/assign -Authorization: Bearer {{MAKER1_TOKEN}} +Authorization: Bearer {{MAKER2_TOKEN}} ### PATCH {{HOST_NAME}}/{{CONFIRMED_PLAN1}}/complete Authorization: Bearer {{DREAMER1_TOKEN}} @@ -87,4 +91,9 @@ GET {{HOST_NAME}}/dreamer?readyToComplete=true&page=1&pageSize=6 Authorization: Bearer {{DREAMER1_TOKEN}} ### PATCH {{HOST_NAME}}/6d201a98-1d06-4497-806a-fa123599019a/complete -Authorization: Bearer {{DREAMER1_TOKEN}} \ No newline at end of file +Authorization: Bearer {{DREAMER1_TOKEN}} +### +GET {{HOST_NAME}}/groupCount +### +GET {{HOST_NAME}}/maker?pageSize=10 +Authorization: Bearer {{MAKER1_TOKEN}} \ No newline at end of file diff --git a/httpTest/user.http b/httpTest/user.http index 4b7f8d0..290feeb 100644 --- a/httpTest/user.http +++ b/httpTest/user.http @@ -57,7 +57,7 @@ POST http://localhost:4000/auth/login Content-Type: application/json { - "email": "maker1@test.com", + "email": "maker2@test.com", "password": "12345678" } ### @@ -69,3 +69,10 @@ Content-Type: application/json "password": "12345678" } ### +POST http://localhost:4000/auth/login +Content-Type: application/json + +{ + "email": "asdf2@naver.com", + "password": "123456" +} \ No newline at end of file diff --git a/src/common/constants/errorMessage.enum.ts b/src/common/constants/errorMessage.enum.ts index 0c7c891..945e801 100644 --- a/src/common/constants/errorMessage.enum.ts +++ b/src/common/constants/errorMessage.enum.ts @@ -39,6 +39,7 @@ export enum ErrorMessage { PLAN_DELETE_BAD_REQUEST = 'CONFIRMED 상태의 진행중인 플랜은 삭제할 수 없습니다.', PLAN_IS_ASSIGNED_BAD_REQUEST = 'IS_ASSIGNED 값은 true와 false 혹은 입력하지 않아야 합니다.', PLAN_CANNOT_CREATE_CHATROOM_BAD_REQUEST = '해당 플랜은 채팅방을 만들 수 없습니다. CONFIRMED상태의 플랜만 가능합니다.', + PLAN_MAKER_NOT_IN_SERVICE_AREA = '메이커의 서비스지역이 플랜의 서비스지역과 일치하지 않습니다.', QUOTE_NOT_FOUND = '해당 견적서를 찾을 수 없습니다.', QUOTE_FORBIDDEN_ID = '해당 견적서의 Maker와 Dreamer만 조회할 수 있습니다.', diff --git a/src/common/domains/plan/plan.domain.ts b/src/common/domains/plan/plan.domain.ts index 4c323c6..f859912 100644 --- a/src/common/domains/plan/plan.domain.ts +++ b/src/common/domains/plan/plan.domain.ts @@ -228,4 +228,8 @@ export default class Plan implements IPlan { getTripType(): TripType { return this.tripType; } + + getServiceArea(): ServiceArea { + return this.serviceArea; + } } diff --git a/src/common/domains/plan/plan.interface.ts b/src/common/domains/plan/plan.interface.ts index 34b749e..c3fc026 100644 --- a/src/common/domains/plan/plan.interface.ts +++ b/src/common/domains/plan/plan.interface.ts @@ -2,6 +2,7 @@ import { PlanProperties, PlanToClientProperties } from 'src/common/types/plan/pl import { Status } from 'src/common/constants/status.type'; import { AssignData } from 'src/common/types/plan/plan.type'; import { TripType } from 'src/common/constants/tripType.type'; +import { ServiceArea } from 'src/common/constants/serviceArea.type'; export default interface IPlan { toClient(): PlanToClientProperties; @@ -24,4 +25,5 @@ export default interface IPlan { getAssigneeNickName(makerId: string): string; getTitle(): string; getTripType(): TripType; + getServiceArea(): ServiceArea; } diff --git a/src/common/types/plan/plan.type.ts b/src/common/types/plan/plan.type.ts index e33a771..ad27bf1 100644 --- a/src/common/types/plan/plan.type.ts +++ b/src/common/types/plan/plan.type.ts @@ -13,7 +13,7 @@ export interface PlanWhereConditions { serviceArea?: { in: ServiceArea[] }; tripType?: { in: TripType[] }; tripDate?: Date | string | { gte?: Date; lte?: Date }; - quotes?: { some: { makerId: { not: string } } }; + quotes?: { none: { makerId: string } }; assignees?: { some: { id: string } }; status?: { in: Status[] }; dreamerId?: string; diff --git a/src/modules/plan/plan.repository.ts b/src/modules/plan/plan.repository.ts index 05645a3..96e87a3 100644 --- a/src/modules/plan/plan.repository.ts +++ b/src/modules/plan/plan.repository.ts @@ -192,7 +192,7 @@ export default class PlanRepository { if (role === RoleValues.MAKER) { whereConditions.status = { in: status }; //NOTE. Maker 전용 api 조건 - whereConditions.quotes = { some: { makerId: { not: userId } } }; + whereConditions.quotes = { none: { makerId: userId } }; if (isAssigned === true) whereConditions.assignees = { some: { id: userId } }; //NOTE. 지정견적 조회 API } else if (userId) { whereConditions.dreamerId = userId; //NOTE. Dreamer 전용 api 조건 diff --git a/src/modules/plan/plan.service.ts b/src/modules/plan/plan.service.ts index 6a35c3e..589ee7a 100644 --- a/src/modules/plan/plan.service.ts +++ b/src/modules/plan/plan.service.ts @@ -55,6 +55,7 @@ export default class PlanService { options: PlanQueryOptions ): Promise<{ totalCount: number; groupByCount: GroupByCount; list: PlanToClientProperties[] }> { const makerProfile = await this.userService.getProfile(RoleValues.MAKER, userId); + const serviceArea: ServiceArea[] = makerProfile.serviceArea; options.serviceArea = serviceArea; //NOTE. 메이커의 서비스지역 필터링 @@ -179,7 +180,13 @@ export default class PlanService { throw new BadRequestError(ErrorMessage.PLAN_ASSIGN_NOT_MAKER); } + const assigneeServiceArea = (await this.userService.getProfile(RoleValues.MAKER, assigneeId)).serviceArea; + if (!assigneeServiceArea.includes(plan.getServiceArea())) { + throw new BadRequestError(ErrorMessage.PLAN_MAKER_NOT_IN_SERVICE_AREA); + } + plan.requestAssign(data); + const updatedPlan = await this.repository.update(plan); const nickName = updatedPlan.getDreamerNickName();