-
Notifications
You must be signed in to change notification settings - Fork 0
♻️ refactor/ZIP-30-kapt : 아파트 관련 기능 수정 #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
10eadaa
4e9b51d
483d6f1
65f4939
9cdb604
c3aca42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,10 +5,13 @@ | |||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.core.response.pageable.PageResponse; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.adapter.in.web.dto.response.EstateDetailResponse; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.adapter.in.web.dto.response.EstateListResponse; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.adapter.in.web.dto.response.EstatePriceListResponse; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.adapter.in.web.swagger.EstateApiSpec; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.application.in.estate.EstatePriceUseCase; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.application.in.estate.GetEstateUseCase; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.application.in.external.OpenAiUseCase; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.domain.estate.Estate; | ||||||||||||||||||||||||||||||||||||||||||||
| import com.zipte.platform.server.domain.estate.EstatePrice; | ||||||||||||||||||||||||||||||||||||||||||||
| import jakarta.persistence.EntityNotFoundException; | ||||||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.data.domain.Page; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -25,6 +28,9 @@ public class EstateApi implements EstateApiSpec { | |||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| private final GetEstateUseCase getService; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /// 가격 의존성 | ||||||||||||||||||||||||||||||||||||||||||||
| private final EstatePriceUseCase priceService; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /// AI 의존성 | ||||||||||||||||||||||||||||||||||||||||||||
| private final OpenAiUseCase openAiService; | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -74,9 +80,8 @@ public ApiResponse<List<EstateListResponse>> getEstateByLocation( | |||||||||||||||||||||||||||||||||||||||||||
| @RequestParam(value = "longitude") double longitude, | ||||||||||||||||||||||||||||||||||||||||||||
| @RequestParam(value = "latitude") double latitude, | ||||||||||||||||||||||||||||||||||||||||||||
| @RequestParam(value = "radius") double radius) { | ||||||||||||||||||||||||||||||||||||||||||||
| List<Estate> list = getService.loadEstatesNearBy(longitude, latitude, radius); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return ApiResponse.ok(EstateListResponse.from(list)); | ||||||||||||||||||||||||||||||||||||||||||||
| return ApiResponse.ok(getService.loadEstatesNearBy(longitude, latitude, radius)); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -101,4 +106,25 @@ public ApiResponse<String> getEstateDetail(@PathVariable String kaptCode) { | |||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return ApiResponse.ok(result); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| /// 가격 조회 | ||||||||||||||||||||||||||||||||||||||||||||
| @GetMapping("/price") | ||||||||||||||||||||||||||||||||||||||||||||
| public ApiResponse<List<EstatePriceListResponse>> getPriceByCodeAndArea( | ||||||||||||||||||||||||||||||||||||||||||||
| @RequestParam String kaptCode, | ||||||||||||||||||||||||||||||||||||||||||||
| @RequestParam double area) { | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| List<EstatePrice> list = priceService.getEstatePriceByCode(kaptCode, area); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return ApiResponse.ok(EstatePriceListResponse.from(list)); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| @GetMapping("/price/{kaptCode}") | ||||||||||||||||||||||||||||||||||||||||||||
| public ApiResponse<List<EstatePriceListResponse>> getPrice(@PathVariable String kaptCode) { | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| List<EstatePrice> list = priceService.getEstatePriceByCode(kaptCode); | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| return ApiResponse.ok(EstatePriceListResponse.from(list)); | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+130
to
+136
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 코드 중복을 제거하고 예외 처리를 개선하세요. 두 번째 가격 조회 엔드포인트에서도 파라미터 검증과 예외 처리가 필요합니다. 또한 두 메서드 간에 유사한 로직이 반복됩니다. 다음과 같이 개선할 수 있습니다: @GetMapping("/price/{kaptCode}")
public ApiResponse<List<EstatePriceListResponse>> getPrice(@PathVariable String kaptCode) {
+ if (kaptCode == null || kaptCode.trim().isEmpty()) {
+ throw new IllegalArgumentException("kaptCode는 필수 파라미터입니다.");
+ }
- List<EstatePrice> list = priceService.getEstatePriceByCode(kaptCode);
-
- return ApiResponse.ok(EstatePriceListResponse.from(list));
+ try {
+ List<EstatePrice> list = priceService.getEstatePriceByCode(kaptCode);
+ return ApiResponse.ok(EstatePriceListResponse.from(list));
+ } catch (Exception e) {
+ throw new EntityNotFoundException("해당 아파트의 가격 정보를 찾을 수 없습니다.");
+ }
}또한 두 메서드를 하나로 통합하여 코드 중복을 줄일 수 있습니다: @GetMapping("/price")
public ApiResponse<List<EstatePriceListResponse>> getPriceByCodeAndArea(
@RequestParam String kaptCode,
@RequestParam(required = false) Double area) {
if (kaptCode == null || kaptCode.trim().isEmpty()) {
throw new IllegalArgumentException("kaptCode는 필수 파라미터입니다.");
}
List<EstatePrice> list;
if (area != null) {
if (area <= 0) {
throw new IllegalArgumentException("area는 0보다 큰 값이어야 합니다.");
}
list = priceService.getEstatePriceByCode(kaptCode, area);
} else {
list = priceService.getEstatePriceByCode(kaptCode);
}
return ApiResponse.ok(EstatePriceListResponse.from(list));
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package com.zipte.platform.server.adapter.in.web.dto.response; | ||
|
|
||
| import com.zipte.platform.server.domain.estate.EstatePrice; | ||
| import lombok.Builder; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| @Builder | ||
| public record EstatePriceDetailResponse( | ||
| double exclusiveArea, String price, String transactionDate) { | ||
|
|
||
| public static EstatePriceDetailResponse from(Optional<EstatePrice> estatePrice) { | ||
| if (estatePrice.isEmpty()) { | ||
| return EstatePriceDetailResponse.builder() | ||
| .exclusiveArea(0.0) | ||
| .price("없음") | ||
| .transactionDate("없음") | ||
| .build(); | ||
| } | ||
|
|
||
| EstatePrice price = estatePrice.get(); | ||
| return EstatePriceDetailResponse.builder() | ||
| .exclusiveArea(price.getExclusiveArea() != 0.0 ? price.getExclusiveArea() : 0.0) | ||
| .price(price.getPrice() != null ? price.getPrice() : "없음") | ||
| .transactionDate(price.getTransactionDate() != null ? price.getTransactionDate() : "없음") | ||
| .build(); | ||
| } | ||
|
Comment on lines
+21
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 중복된 null 체크 로직 line 23-25에서 각 필드마다 null 체크를 하고 있는데, 이미 Optional이 존재하는지 확인했으므로 일부 중복된 체크가 있을 수 있습니다. 또한 다음과 같이 간소화할 수 있습니다: EstatePrice price = estatePrice.get();
return EstatePriceDetailResponse.builder()
- .exclusiveArea(price.getExclusiveArea() != 0.0 ? price.getExclusiveArea() : 0.0)
+ .exclusiveArea(price.getExclusiveArea())
.price(price.getPrice() != null ? price.getPrice() : "없음")
.transactionDate(price.getTransactionDate() != null ? price.getTransactionDate() : "없음")
.build();🤖 Prompt for AI Agents |
||
|
|
||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,11 +3,14 @@ | |||||
| import org.springframework.data.mongodb.repository.MongoRepository; | ||||||
|
|
||||||
| import java.util.List; | ||||||
| import java.util.Optional; | ||||||
|
|
||||||
| public interface EstatePriceMongoRepository extends MongoRepository<EstatePriceDocument, String> { | ||||||
|
|
||||||
| List<EstatePriceDocument> findAllByKaptCode(String kaptCode); | ||||||
|
|
||||||
| List<EstatePriceDocument> findALlByKaptCodeAndExclusiveArea(String kaptCode, double exclusiveArea); | ||||||
|
||||||
| List<EstatePriceDocument> findALlByKaptCodeAndExclusiveArea(String kaptCode, double exclusiveArea); | |
| List<EstatePriceDocument> findAllByKaptCodeAndExclusiveArea(String kaptCode, double exclusiveArea); |
🤖 Prompt for AI Agents
In
src/main/java/com/zipte/platform/server/adapter/out/mongo/estate/EstatePriceMongoRepository.java
at line 12, correct the method name from findALlByKaptCodeAndExclusiveArea to
findAllByKaptCodeAndExclusiveArea to fix the typo. Also, update all references
to this method, including in
src/main/java/com/zipte/platform/server/adapter/out/EstatePricePersistenceAdapter.java
and any other usage across the codebase. After renaming, verify no remaining
occurrences of the typo exist by searching the entire project.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,10 +2,13 @@ | |
|
|
||
| import com.zipte.platform.server.adapter.in.web.dto.response.EstateListResponse; | ||
| import com.zipte.platform.server.application.in.estate.GetEstateUseCase; | ||
| import com.zipte.platform.server.application.out.estate.EstatePricePort; | ||
| import com.zipte.platform.server.application.out.estate.LoadEstatePort; | ||
| import com.zipte.platform.server.application.out.property.LoadPropertyPort; | ||
| import com.zipte.platform.server.domain.estate.Estate; | ||
| import com.zipte.platform.server.domain.estate.EstatePrice; | ||
| import lombok.RequiredArgsConstructor; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.stereotype.Service; | ||
|
|
@@ -14,6 +17,7 @@ | |
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| @Slf4j | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class EstateService implements GetEstateUseCase { | ||
|
|
@@ -22,10 +26,28 @@ public class EstateService implements GetEstateUseCase { | |
|
|
||
| private final LoadPropertyPort loadPropertyPort; | ||
|
|
||
| /// 아파트 가격 조회 | ||
| private final EstatePricePort pricePort; | ||
|
|
||
|
|
||
| @Override | ||
| public List<Estate> loadEstatesNearBy(double latitude, double longitude, double radiusInKm) { | ||
| public List<EstateListResponse> loadEstatesNearBy(double latitude, double longitude, double radiusInKm) { | ||
| double radiusInRadians = radiusInKm / 6378.1; // 반경 km -> radians 변환 | ||
| return loadPort.loadEstatesNearBy(latitude, longitude, radiusInRadians); | ||
|
|
||
| /// 좌표 근처의 아파트 가져오기 | ||
| List<Estate> estates = loadPort.loadEstatesNearBy(latitude, longitude, radiusInRadians); | ||
|
|
||
| List<EstateListResponse> responses = new ArrayList<>(); | ||
|
|
||
| /// 최신의 거래 목록 가져오기 | ||
| estates.forEach(estate -> { | ||
| Optional<EstatePrice> price = pricePort.loadRecentPriceByKaptCode(estate.getKaptCode()); | ||
| EstateListResponse response = EstateListResponse.from(estate, price); | ||
| responses.add(response); | ||
| }); | ||
|
|
||
| return responses; | ||
|
|
||
|
Comment on lines
+36
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain메서드 시그니처 변경 및 로직 통합 메서드 반환 타입이
다음 스크립트를 실행하여 메서드 사용처를 확인해주세요: 🏁 Script executed: #!/bin/bash
# 설명: loadEstatesNearBy 메서드의 사용처를 찾아 시그니처 변경 영향도 확인
# 메서드 호출처 검색
rg -A 3 -B 3 "loadEstatesNearBy"
# GetEstateUseCase 인터페이스 구현체들 확인
ast-grep --pattern 'class $_ implements GetEstateUseCase'Length of output: 8809 시그니처 변경 영향도 확인 완료 및 예외 처리 권고
가격 정보 조회 예외 처리 검토
점검 위치:
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| @Override | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
파라미터 검증 로직을 추가하는 것을 고려하세요.
새로운 가격 조회 엔드포인트가 추가되었습니다. 그러나 입력 파라미터에 대한 검증이 부족합니다.
다음과 같은 개선사항을 적용하는 것을 권장합니다:
@GetMapping("/price") public ApiResponse<List<EstatePriceListResponse>> getPriceByCodeAndArea( @RequestParam String kaptCode, @RequestParam double area) { + if (kaptCode == null || kaptCode.trim().isEmpty()) { + throw new IllegalArgumentException("kaptCode는 필수 파라미터입니다."); + } + if (area <= 0) { + throw new IllegalArgumentException("area는 0보다 큰 값이어야 합니다."); + } List<EstatePrice> list = priceService.getEstatePriceByCode(kaptCode, area); return ApiResponse.ok(EstatePriceListResponse.from(list)); }📝 Committable suggestion
🤖 Prompt for AI Agents