Skip to content

Commit

Permalink
Merge pull request #83 from TeamACON/fix/#82
Browse files Browse the repository at this point in the history
[FIX/#82] 중복 동네 인증 에러 수정
  • Loading branch information
gahyuun authored Feb 16, 2025
2 parents f788f8d + 796cdfa commit 8e224c0
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public enum ErrorType {
INVALID_FAVORITE_SPOT_ERROR(HttpStatus.BAD_REQUEST, 40017, "유효하지 않은 favoriteSpot입니다."),
INVALID_FAVORITE_SPOT_RANK_SIZE_ERROR(HttpStatus.BAD_REQUEST, 40030, "favoriteSpotRank의 사이즈가 잘못되었습니다."),
INVALID_FAVORITE_CUISINE_RANK_SIZE_ERROR(HttpStatus.BAD_REQUEST, 40031, "favoriteCuisineRank의 사이즈가 잘못되었습니다."),
ALREADY_VERIFIED_AREA_ERROR(HttpStatus.BAD_REQUEST, 40032, "이미 인증된 동네가 존재합니다."),
INVALID_IMAGE_TYPE_ERROR(HttpStatus.BAD_REQUEST, 40045, "유효하지 않은 imageType입니다."),

/* 500 Internal Server Error */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.acon.server.member.api.request.ReissueTokenRequest;
import com.acon.server.member.api.request.WithdrawalReasonRequest;
import com.acon.server.member.api.response.AcornCountResponse;
import com.acon.server.member.api.response.AreaResponse;
import com.acon.server.member.api.response.LoginResponse;
import com.acon.server.member.api.response.MemberAreaResponse;
import com.acon.server.member.api.response.PreSignedUrlResponse;
Expand Down Expand Up @@ -65,13 +66,14 @@ public ResponseEntity<LoginResponse> login(
public ResponseEntity<MemberAreaResponse> postArea(
@Valid @RequestBody final MemberAreaRequest request
) {
String area = memberService.createMemberArea(request.latitude(), request.longitude());

return ResponseEntity.ok(new MemberAreaResponse(area));
return ResponseEntity.ok(
memberService.createMemberArea(request.latitude(), request.longitude())
);
}

@GetMapping(path = "/area", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<MemberAreaResponse> getArea(
public ResponseEntity<AreaResponse> getArea(
@DecimalMin(value = "33.1", message = "위도는 최소 33.1°N 이상이어야 합니다.(대한민국 기준)")
@DecimalMax(value = "38.6", message = "위도는 최대 38.6°N 이하이어야 합니다.(대한민국 기준)")
@Validated @RequestParam(name = "latitude") final Double latitude,
Expand All @@ -81,7 +83,7 @@ public ResponseEntity<MemberAreaResponse> getArea(
) {
String area = memberService.fetchMemberArea(latitude, longitude);

return ResponseEntity.ok(new MemberAreaResponse(area));
return ResponseEntity.ok(new AreaResponse(area));
}

@PostMapping(path = "/member/preference", consumes = MediaType.APPLICATION_JSON_VALUE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.acon.server.member.api.response;

public record AreaResponse(
String area
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

public record LoginResponse(
String accessToken,
String refreshToken
String refreshToken,
boolean hasVerifiedArea
) {

public static LoginResponse of(
final String accessToken,
final String refreshToken
final String refreshToken,
final boolean hasVerifiedArea
) {
return new LoginResponse(accessToken, refreshToken);
return new LoginResponse(accessToken, refreshToken, hasVerifiedArea);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package com.acon.server.member.api.response;

public record MemberAreaResponse(
String area
Long id,
String name
) {

public static MemberAreaResponse of(
final Long id,
final String name
) {
return new MemberAreaResponse(id, name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.acon.server.global.external.s3.S3Adapter;
import com.acon.server.member.api.response.AcornCountResponse;
import com.acon.server.member.api.response.LoginResponse;
import com.acon.server.member.api.response.MemberAreaResponse;
import com.acon.server.member.api.response.PreSignedUrlResponse;
import com.acon.server.member.api.response.ProfileResponse;
import com.acon.server.member.api.response.ReissueTokenResponse;
Expand Down Expand Up @@ -99,7 +100,9 @@ public LoginResponse login(
String accessToken = jwtTokenProvider.issueAccessToken(memberAuthentication);
String refreshToken = jwtTokenProvider.issueRefreshToken(memberId);

return LoginResponse.of(accessToken, refreshToken);
boolean hasVerifiedArea = verifiedAreaRepository.existsByMemberId(memberId);

return LoginResponse.of(accessToken, refreshToken, hasVerifiedArea);
}

protected Long fetchMemberId(
Expand All @@ -126,31 +129,43 @@ protected Long fetchMemberId(
}

@Transactional
public String createMemberArea(
public MemberAreaResponse createMemberArea(
final Double latitude,
final Double longitude
) {
MemberEntity memberEntity = memberRepository.findByIdOrElseThrow(principalHandler.getUserIdFromPrincipal());

// 추후 여러 동네 인증이 가능하게 되면 제거 예정
if (verifiedAreaRepository.existsByMemberId(memberEntity.getId())) {
throw new BusinessException(ErrorType.ALREADY_VERIFIED_AREA_ERROR);
}

String legalDong = naverMapsAdapter.getReverseGeoCodingResult(latitude, longitude);
Optional<VerifiedAreaEntity> optionalVerifiedAreaEntity = verifiedAreaRepository.findByMemberIdAndName(
memberEntity.getId(), legalDong);

optionalVerifiedAreaEntity.ifPresentOrElse(
verifiedAreaEntity -> {
VerifiedArea verifiedArea = verifiedAreaMapper.toDomain(verifiedAreaEntity);
verifiedArea.updateVerifiedDate(LocalDate.now());
verifiedAreaRepository.save(verifiedAreaMapper.toEntity(verifiedArea));
},
() -> verifiedAreaRepository.save(
VerifiedAreaEntity.builder()
.name(legalDong)
.memberId(memberEntity.getId())
.verifiedDate(Collections.singletonList(LocalDate.now()))
.build()
)
);
LocalDate currentDate = LocalDate.now();
VerifiedAreaEntity savedVerifiedAreaEntity = optionalVerifiedAreaEntity
.map(entity -> updateVerifiedAreaEntity(entity, currentDate))
.orElseGet(() -> createVerifiedAreaEntity(legalDong, memberEntity.getId(), currentDate));

return MemberAreaResponse.of(savedVerifiedAreaEntity.getId(), savedVerifiedAreaEntity.getName());
}

return legalDong;
private VerifiedAreaEntity updateVerifiedAreaEntity(VerifiedAreaEntity entity, LocalDate currentDate) {
VerifiedArea verifiedArea = verifiedAreaMapper.toDomain(entity);
verifiedArea.updateVerifiedDate(currentDate);
return verifiedAreaRepository.save(verifiedAreaMapper.toEntity(verifiedArea));
}

private VerifiedAreaEntity createVerifiedAreaEntity(String legalDong, Long memberId, LocalDate currentDate) {
return verifiedAreaRepository.save(
VerifiedAreaEntity.builder()
.name(legalDong)
.memberId(memberId)
.verifiedDate(Collections.singletonList(currentDate))
.build()
);
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -280,6 +295,7 @@ public ReissueTokenResponse reissueToken(String refreshToken) {
public void withdrawMember(String reason, String refreshToken) {
MemberEntity memberEntity = memberRepository.findByIdOrElseThrow(principalHandler.getUserIdFromPrincipal());

// TODO: memberId 존재하는 테이블에 member row 제거 ( 리뷰 테이블 제외 )
memberRepository.deleteById(memberEntity.getId());
jwtTokenProvider.deleteRefreshToken(refreshToken);
// TODO: 엑세스 토큰 블랙리스트
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface VerifiedAreaRepository extends JpaRepository<VerifiedAreaEntity
Optional<VerifiedAreaEntity> findByMemberIdAndName(Long memberId, String name);

List<VerifiedAreaEntity> findAllByMemberId(Long memberId);

boolean existsByMemberId(Long memberId);
}

0 comments on commit 8e224c0

Please sign in to comment.