From d4ebe0c55f8f5ea93bc91f52d74c99001b9df7e1 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Wed, 19 Feb 2025 02:13:15 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EB=8F=99?= =?UTF-8?q?=EB=84=A4=20=EC=82=AD=EC=A0=9C=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EC=9E=91=EC=84=B1=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/api/controller/MemberController.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/acon/server/member/api/controller/MemberController.java b/src/main/java/com/acon/server/member/api/controller/MemberController.java index 380c2a4..57366ae 100644 --- a/src/main/java/com/acon/server/member/api/controller/MemberController.java +++ b/src/main/java/com/acon/server/member/api/controller/MemberController.java @@ -27,13 +27,16 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Positive; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -70,7 +73,6 @@ public ResponseEntity login( public ResponseEntity postVerifiedArea( @Valid @RequestBody final VerifiedAreaRequest request ) { - return ResponseEntity.ok( memberService.createVerifiedArea(request.latitude(), request.longitude()) ); @@ -79,12 +81,21 @@ public ResponseEntity postVerifiedArea( @GetMapping(path = "/members/verified-areas", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity getVerifiedAreaList( ) { - return ResponseEntity.ok( memberService.fetchVerifiedAreaList() ); } + @DeleteMapping(path = "/members/verified-areas/{verifiedAreaId}") + public ResponseEntity deleteVerifiedArea( + @Positive(message = "verifiedAreaId는 양수여야 합니다.") + @PathVariable(name = "verifiedAreaId") final Long verifiedAreaId + ) { + memberService.deleteVerifiedArea(verifiedAreaId); + + return ResponseEntity.ok().build(); + } + @GetMapping(path = "/area", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity getArea( @DecimalMin(value = "33.1", message = "위도는 최소 33.1°N 이상이어야 합니다.(대한민국 기준)") From 8723ce4b135ba044df3ddf0f336f6bf82587ed81 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Wed, 19 Feb 2025 02:14:29 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EB=8F=99?= =?UTF-8?q?=EB=84=A4=20=EC=82=AD=EC=A0=9C=20JPA=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/global/exception/ErrorType.java | 4 ++++ .../infra/repository/MemberRepository.java | 5 +++-- .../repository/VerifiedAreaRepository.java | 18 +++++++++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/acon/server/global/exception/ErrorType.java b/src/main/java/com/acon/server/global/exception/ErrorType.java index 9311977..48c2412 100644 --- a/src/main/java/com/acon/server/global/exception/ErrorType.java +++ b/src/main/java/com/acon/server/global/exception/ErrorType.java @@ -52,6 +52,10 @@ public enum ErrorType { INVALID_IMAGE_TYPE_ERROR(HttpStatus.BAD_REQUEST, 40045, "유효하지 않은 imageType입니다."), INVALID_NICKNAME_ERROR(HttpStatus.BAD_REQUEST, 40051, "닉네임이 조건을 만족하지 않습니다."), INVALID_BIRTH_DATE_ERROR(HttpStatus.BAD_REQUEST, 40053, "유효하지 않은 생년월일입니다."), + INVALID_VERIFIED_AREA_ERROR(HttpStatus.BAD_REQUEST, 40054, "유효하지 않은 인증 동네입니다."), + + /* 404 Not Found */ + NOT_FOUND_VERIFIED_AREA_ERROR(HttpStatus.NOT_FOUND, 40404, "존재하지 않는 인증 동네입니다."), /* 409 Conflict */ DUPLICATED_NICKNAME_ERROR(HttpStatus.CONFLICT, 40901, "이미 사용 중인 닉네임입니다."), diff --git a/src/main/java/com/acon/server/member/infra/repository/MemberRepository.java b/src/main/java/com/acon/server/member/infra/repository/MemberRepository.java index bcb8006..b7f6fc7 100644 --- a/src/main/java/com/acon/server/member/infra/repository/MemberRepository.java +++ b/src/main/java/com/acon/server/member/infra/repository/MemberRepository.java @@ -14,7 +14,8 @@ public interface MemberRepository extends JpaRepository { boolean existsByNickname(String nickname); default MemberEntity findByIdOrElseThrow(Long id) { - return findById(id) - .orElseThrow(() -> new BusinessException(ErrorType.NOT_FOUND_MEMBER_ERROR)); + return findById(id).orElseThrow( + () -> new BusinessException(ErrorType.NOT_FOUND_MEMBER_ERROR) + ); } } diff --git a/src/main/java/com/acon/server/member/infra/repository/VerifiedAreaRepository.java b/src/main/java/com/acon/server/member/infra/repository/VerifiedAreaRepository.java index 259a7b6..a2e720d 100644 --- a/src/main/java/com/acon/server/member/infra/repository/VerifiedAreaRepository.java +++ b/src/main/java/com/acon/server/member/infra/repository/VerifiedAreaRepository.java @@ -1,5 +1,7 @@ package com.acon.server.member.infra.repository; +import com.acon.server.global.exception.BusinessException; +import com.acon.server.global.exception.ErrorType; import com.acon.server.member.infra.entity.VerifiedAreaEntity; import java.util.List; import java.util.Optional; @@ -7,11 +9,21 @@ public interface VerifiedAreaRepository extends JpaRepository { + long countByMemberId(Long memberId); + + boolean existsByMemberId(Long memberId); + boolean existsByMemberIdAndName(Long memberId, String name); + Optional findById(Long id); + Optional findByMemberIdAndName(Long memberId, String name); - List findAllByMemberId(Long memberId); + default VerifiedAreaEntity findByIdOrElseThrow(Long id) { + return findById(id).orElseThrow( + () -> new BusinessException(ErrorType.NOT_FOUND_VERIFIED_AREA_ERROR) + ); + } - boolean existsByMemberId(Long memberId); -} \ No newline at end of file + List findAllByMemberId(Long memberId); +} From afdd72ca5c1a6ce488058ef4bf001e9955433877 Mon Sep 17 00:00:00 2001 From: ckkim817 Date: Wed, 19 Feb 2025 02:14:45 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EB=8F=99?= =?UTF-8?q?=EB=84=A4=20=EC=82=AD=EC=A0=9C=20=EB=B9=84=EC=A6=88=EB=8B=88?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/service/MemberService.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/acon/server/member/application/service/MemberService.java b/src/main/java/com/acon/server/member/application/service/MemberService.java index 0590b38..ba21605 100644 --- a/src/main/java/com/acon/server/member/application/service/MemberService.java +++ b/src/main/java/com/acon/server/member/application/service/MemberService.java @@ -62,6 +62,7 @@ public class MemberService { private static final char[] CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.".toCharArray(); private static final int MAX_NICKNAME_LENGTH = 16; private static final String NICKNAME_PATTERN = "^[a-zA-Z0-9_.가-힣]+$"; + private static final int MIN_VERIFIED_AREA_SIZE = 1; private static final int MAX_VERIFIED_AREA_SIZE = 5; private final GuidedSpotRepository guidedSpotRepository; @@ -163,10 +164,7 @@ public VerifiedAreaResponse createVerifiedArea( ) { MemberEntity memberEntity = memberRepository.findByIdOrElseThrow(principalHandler.getUserIdFromPrincipal()); - List verifiedAreaEntityList = verifiedAreaRepository.findAllByMemberId( - memberEntity.getId()); - - if (verifiedAreaEntityList.size() >= MAX_VERIFIED_AREA_SIZE) { + if (verifiedAreaRepository.countByMemberId(memberEntity.getId()) >= MAX_VERIFIED_AREA_SIZE) { throw new BusinessException(ErrorType.INVALID_AREA_SIZE_ERROR); } @@ -193,7 +191,22 @@ public VerifiedAreaListResponse fetchVerifiedAreaList() { .toList(); return new VerifiedAreaListResponse(verifiedAreaList); + } + + @Transactional + public void deleteVerifiedArea(final Long verifiedAreaId) { + MemberEntity memberEntity = memberRepository.findByIdOrElseThrow(principalHandler.getUserIdFromPrincipal()); + VerifiedAreaEntity verifiedAreaEntity = verifiedAreaRepository.findByIdOrElseThrow(verifiedAreaId); + + if (!verifiedAreaEntity.getMemberId().equals(memberEntity.getId())) { + throw new BusinessException(ErrorType.INVALID_VERIFIED_AREA_ERROR); + } + + if (verifiedAreaRepository.countByMemberId(memberEntity.getId()) <= MIN_VERIFIED_AREA_SIZE) { + throw new BusinessException(ErrorType.INVALID_AREA_SIZE_ERROR); + } + verifiedAreaRepository.deleteById(verifiedAreaId); } private VerifiedAreaEntity updateVerifiedAreaEntity(