Conversation
…ctor/homeCreate
- HomeCreateRequestDto, HomeUpdateRequestDto 신규 생성 - HomeCreateDTO에서 imageUrls 필드 제거 (파일 업로드만 지원) - HomeImageVO 필드명 수정 (ImageUrl → imageUrl) - Swagger 어노테이션 추가 및 예제값 설정
- selectHomeFacilitiesByHomeDetailId 중복 제거 - selectHomeMaintenanceFeesByHomeId 중복 제거 - selectFacilityCategories 중복 제거 - selectFacilityItemsByCategoryId 중복 제거 - incrementViewCount 중복 제거
- HomeController 인터페이스 정의 - HomeControllerImpl 구현 클래스 생성 - API 정의와 비즈니스 로직 분리 - 테스트 가능성 및 유지보수성 향상
- 불필요한 디버깅 로그 제거
- 이미지 업로드 로직 단순화
- S3 경로 처리 개선 (home/{homeId}/{fileName} 형식)
- 에러 처리 및 로깅 메시지 최적화
- updateHome 메서드에 이미지 파라미터 추가 - 매물 수정 시 이미지 업로드 기능 지원
- 메서드 호출 공백 일관성 개선 - 코드 포맷팅 통일
- LocalDateTime.toLocalDate() 호출 제거 - buildDate가 이미 LocalDate 타입으로 처리되도록 수정
- HomeCreateRequestDto/HomeUpdateRequestDto import 경로 수정 - buildDate 타입을 LocalDateTime에서 LocalDate로 변경 - 필드명 매핑 수정 (bathroomCount -> bathroomCnt, isParkingAvailable -> isParking) - MaintenanceFeeDTO를 MaintenanceFeeItem으로 변환하는 로직 추가 - Integer를 Long으로 변환하는 로직 추가
- multipart/form-data에서 LocalDate 타입 변환 지원 - ISO_LOCAL_DATE 포맷 (yyyy-MM-dd) 처리 - 빈 문자열 처리 지원
… into refactor/homeCreate
Walkthrough홈 도메인 전반에 description 필드를 추가하고 생성/조회 흐름에 전파했다. Controller, Service, DTO, VO, Mapper(XML)에 해당 필드를 매핑했으며, 일부 응답 매핑에 chatCnt 포함 및 로깅을 강화했다. Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Controller as HomeController
participant Service as HomeService
participant Mapper as HomeMapper
participant DB
Client->>Controller: POST /homes (HomeCreateRequestDto with description)
Controller->>Service: createHome(HomeCreateDTO with description)
Service->>Mapper: insertHomeDetail(description, ...)
Mapper->>DB: INSERT home_detail (...)
DB-->>Mapper: OK
Service-->>Controller: Created HomeId
Controller-->>Client: 201 Created
sequenceDiagram
actor Client
participant Controller as HomeController
participant Service as HomeService
participant Mapper as HomeMapper
participant DB
Client->>Controller: GET /homes/{id}
Controller->>Service: getHome(id)
Service->>Mapper: selectHomeDetailByHomeId(id)
Mapper->>DB: SELECT ... , description
DB-->>Mapper: HomeDetail(record with description)
Mapper-->>Service: VO
Service-->>Controller: HomeResponseDTO(description, chatCnt?, ...)
Controller-->>Client: 200 OK
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (2)
src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml (1)
276-286: updateHomeDetail에 description 갱신 누락
- create/조회에는 description을 연결하셨지만, 수정 쿼리에는 반영되지 않아 수정이 DB에 저장되지 않습니다.
아래처럼 description 컬럼 업데이트를 추가해 주세요.
UPDATE home_detail SET build_date = #{buildDate}, home_floor = #{homeFloor}, building_total_floors = #{buildingTotalFloors}, home_direction = #{homeDirection}, bathroom_count = #{bathroomCnt}, is_pet = #{isPet}, - is_parking_available = #{isParking} + is_parking_available = #{isParking}, + description = #{description} WHERE home_detail_id = #{homeDetailId}src/main/java/org/scoula/domain/home/service/HomeServiceImpl.java (1)
193-201: readOnly 트랜잭션에서 view count 증가(쓰기) 수행 — 반영 실패/예외 가능
@Transactional(readOnly = true)범위 내에서homeMapper.incrementViewCount(homeId)(쓰기)를 호출합니다. 데이터소스/드라이버 설정에 따라 반영이 무시되거나 예외가 발생할 수 있습니다.권장 수정:
- 방법 A(간단): 메서드의 readOnly를 해제합니다.
- @Transactional(readOnly = true) + @Transactional public HomeResponseDTO getHome(Integer homeId) {
- 방법 B(보수): 존재 여부 확인 후 증가시키도록 순서도 조정하면 안전합니다. 예시:
public HomeResponseDTO getHome(Integer homeId) { HomeVO home = homeMapper.selectHomeById(homeId); if (home == null) { throw new BusinessException(CommonErrorCode.ENTITY_NOT_FOUND, "존재하지 않는 매물입니다."); } homeMapper.incrementViewCount(homeId); ... }
🧹 Nitpick comments (9)
src/main/java/org/scoula/domain/home/dto/HomeResponseDTO.java (1)
55-55: description 필드 추가는 적절합니다. 응답 스키마 문서화와 길이/콘텐츠 정책을 명확히 해두면 좋겠습니다.
- API 문서 가독성을 위해 Response DTO에도 Swagger 필드 설명을 붙이는 것을 권장합니다.
- DB 컬럼 타입/길이(TEXT vs VARCHAR(N))와 최대 길이 정책을 확인해주세요. 긴 텍스트를 허용한다면 FE 렌더링 시 XSS 방지를 위해 이스케이프 처리 또는 허용 태그 화이트리스트 정책이 필요합니다.
적용 예시(diff: 선택 라인 내 변경):
- private String description; + @io.swagger.annotations.ApiModelProperty(value = "상세 설명", example = "남향, 인근 공원, 채광 우수") + private String description;추가(선택 라인 외): HomeMapper/DDL에서 description 컬럼 정의 확인
- VARCHAR(1000) 등 명확한 길이 정책 정의 또는 TEXT 사용 시 검색/인덱싱 전략 고려.
src/main/java/org/scoula/domain/home/dto/HomeCreateDTO.java (1)
64-65: 생성 DTO에 description 연동 OK. 업데이트 플로우 동등 반영 여부 확인 필요create 플로우에선 전달되지만, update 플로우에서도 동일하게 전달/수정 가능해야 합니다. Controller의 updateHome 빌더에 description 세팅이 누락되지 않았는지 확인 부탁드립니다.
선택 라인 외 참고(Controller update 빌더 예시):
.description(updateDto.getDescription())원하시면 해당 부분 패치 PR 제안 드리겠습니다.
src/main/java/org/scoula/domain/home/dto/HomeCreateRequestDto.java (1)
101-103: 입력 검증 보강 제안: description 길이 제한 및 문서화유저 입력 필드인 만큼 길이 제한을 두는 것이 안전합니다. 필요 시 서비스 레이어에서 trim/sanitize도 고려해주세요.
적용 예시(diff):
- @ApiModelProperty(value = "상세 정보", example = "남향이라 햇살이 잘 들고, 근처에 공원이 있어 산책하기 좋습니다.") - private String description; + @Size(max = 1000, message = "상세 정보는 1000자 이내여야 합니다.") + @ApiModelProperty(value = "상세 정보", example = "남향이라 햇살이 잘 들고, 근처에 공원이 있어 산책하기 좋습니다.", notes = "최대 1000자") + private String description;src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java (1)
77-77: create 빌더에 description 전달 OK. update 경로/DTO에도 동일하게 반영 필요updateHome 빌더에는 description 설정이 보이지 않습니다. update 요청 DTO(HomeUpdateRequestDto)에 description 필드가 존재하고, 빌더에도 전달되도록 정합성 맞추길 권장합니다.
선택 라인 외 적용 예시:
// HomeUpdateRequestDto: private String description; (+ Swagger/검증 어노테이션) HomeCreateDTO updateDTO = HomeCreateDTO.builder() // ... .description(updateDto.getDescription()) .build();src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml (1)
21-26: home_detail INSERT에 description 추가는 적절함. 컬럼 스키마/널 허용 여부만 확인 부탁.
- 컬럼/값 순서 일치하고 바인딩도 올바릅니다.
- 운영 데이터에 따라 description이 null일 수 있으면 DB 컬럼이 NULL 허용인지 확인해 주세요.
- 사소하지만 VALUES 부분
,#{description}앞 공백 일관성도 챙기면 가독성 좋아집니다.src/main/java/org/scoula/domain/home/service/HomeServiceImpl.java (4)
27-27: 서비스 인터페이스 네이밍 컨벤션 불일치 가능성
- 가이드에 따르면 인터페이스는
*ServiceInterface, 구현체는*ServiceImpl권장입니다. 현재implements HomeService로 되어 있어 컨벤션과 다를 수 있습니다. 프로젝트 전반 컨벤션과 일치하는지 한번 확인 부탁드립니다.
40-43: INFO 레벨에서 DTO 전체/description 로그는 과다 로그·PII 노출 위험. DEBUG로 낮추는 것을 권장
- 운영 환경에서 요청 DTO 전체를 INFO로 남기면 주소 등 민감/개인 정보가 로그에 축적될 수 있습니다.
- log.info("서비스에서 받은 DTO: {}", createDTO); - log.info("서비스에서 확인한 description 값: {}", createDTO.getDescription()); + log.debug("서비스에서 받은 DTO: {}", createDTO); + log.debug("서비스에서 확인한 description 값: {}", createDTO.getDescription());
89-92: DB 저장 전 HomeDetailVO 전체 로그도 DEBUG 권장
- 객체 전체를 INFO로 남기면 개인 정보 노출 및 로그 부하가 큽니다.
- log.info("DB에 저장할 HomeDetailVO 객체: {}", homeDetail); - log.info("최종 DB 저장 직전의 description 값: {}", homeDetail.getDescription()); + log.debug("DB에 저장할 HomeDetailVO 객체: {}", homeDetail); + log.debug("최종 DB 저장 직전의 description 값: {}", homeDetail.getDescription());
204-209: 매퍼 반환 객체/description 로그는 DEBUG 권장
- 조회 응답을 INFO로 장기간 적재하면 로그 비용 및 개인정보 노출 리스크가 큽니다.
- log.info("매퍼에서 반환된 HomeDetailVO: {}", homeDetail); - log.info( - "매퍼에서 확인한 description 값: {}", - homeDetail != null ? homeDetail.getDescription() : null); + log.debug("매퍼에서 반환된 HomeDetailVO: {}", homeDetail); + log.debug("매퍼에서 확인한 description 값: {}", + homeDetail != null ? homeDetail.getDescription() : null);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java(2 hunks)src/main/java/org/scoula/domain/home/dto/HomeCreateDTO.java(1 hunks)src/main/java/org/scoula/domain/home/dto/HomeCreateRequestDto.java(1 hunks)src/main/java/org/scoula/domain/home/dto/HomeResponseDTO.java(1 hunks)src/main/java/org/scoula/domain/home/service/HomeServiceImpl.java(7 hunks)src/main/java/org/scoula/domain/home/vo/HomeDetailVO.java(1 hunks)src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml(2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
src/main/java/org/scoula/**/controller/*Controller{,Impl}.java
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use interface-implementation pattern for controllers:
*Controller.java(interface) and*ControllerImpl.java(implementation)
Files:
src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java
src/main/java/org/scoula/**/controller/**/*.java
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/main/java/org/scoula/**/controller/**/*.java: All controller endpoints should return a consistentApiResponse<T>wrapper
Add Swagger annotations to controller endpoints for API documentation
Files:
src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java
src/main/java/org/scoula/**/service/*Service{Interface,Impl}.java
📄 CodeRabbit Inference Engine (CLAUDE.md)
Use interface-implementation pattern for services:
*ServiceInterface.java(interface) and*ServiceImpl.java(implementation)
Files:
src/main/java/org/scoula/domain/home/service/HomeServiceImpl.java
src/main/resources/org/scoula/domain/*/mapper/*Mapper.xml
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/main/resources/org/scoula/domain/*/mapper/*Mapper.xml: Place MyBatis XML mappers atsrc/main/resources/org/scoula/domain/*/mapper/*Mapper.xml
Name MyBatis XML mappers*Mapper.xmlto match their corresponding*Mapper.javainterfaces
Files:
src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml
🔇 Additional comments (8)
src/main/java/org/scoula/domain/home/vo/HomeDetailVO.java (1)
27-27: 매퍼(description) 반영 확인됨, DDL 컬럼 정의 검증 필요
- src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml
• 21행·25행: INSERT에description포함
• 66행: SELECT에description as description포함- DDL(예: migration SQL)에서
home_detail.description컬럼의 길이와 타입이 정책과 일치하는지 꼭 확인 부탁드립니다.src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java (1)
77-77: chatCnt 조회 방식 검증 완료: N+1 쿼리 없음HomeMapper.xml에서
h.chat_cnt AS chatCnt로 단일 쿼리 내에 직접 조회하고 있어, 별도의 JOIN·서브쿼리를 통한 건별 카운트 조회가 아니므로 N+1 이슈가 발생하지 않습니다.
코드 수정은 불필요하며, DB 스키마 측면에서chat_room.home_id인덱스 존재 여부만 한 번 점검해 주시기 바랍니다.src/main/resources/org/scoula/domain/home/mapper/HomeMapper.xml (1)
66-69: SELECT 매핑에 description 포함한 부분 LGTM
- VO의
description과 정상 매핑됩니다.src/main/java/org/scoula/domain/home/service/HomeServiceImpl.java (5)
86-87: VO 빌더에 description 전달 LGTM
- 생성 흐름에서 description 누락 없이 DB로 전달됩니다.
170-174: 예외 로깅 강화 LGTM
- 메시지와 함께 예외 객체를 포함해 스택 트레이스 확인이 가능해졌습니다.
251-252: 응답 DTO에 description 포함 LGTM
- 프론트로 description 전달 경로가 완성되었습니다.
285-286: searchHomes 응답에 chatCnt 연동 LGTM
- PR 목적(메인페이지 채팅수 연동)에 부합합니다. Mapper의
selectHomeListByCondition가chat_cnt as chatCnt를 이미 반환하고 있어 일관적입니다.
321-321: getHomeList 응답에 chatCnt 연동 LGTM
- 메인 목록에서도 채팅 수가 노출되도록 일관성 있게 처리되었습니다.
| // ✨ 매물 등록 요청 데이터와 description 값을 로그로 확인 | ||
| log.info("매물 등록 요청 데이터: {}", requestDto); | ||
| log.info("컨트롤러에서 확인한 description 값: {}", requestDto.getDescription()); | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
PII 노출 위험: 요청 DTO 전체를 info 레벨로 로깅하지 마세요
주소 등 민감정보와 대용량 파일 메타가 로그에 남을 수 있습니다. debug로 내리고, 필요한 최소 필드만 구조화해 로그하세요.
적용 예시(diff):
- // ✨ 매물 등록 요청 데이터와 description 값을 로그로 확인
- log.info("매물 등록 요청 데이터: {}", requestDto);
- log.info("컨트롤러에서 확인한 description 값: {}", requestDto.getDescription());
+ // 요청 핵심 메타만 디버그 로깅 (민감정보/대용량 제외)
+ log.debug("매물 등록 요청 수신: residenceType={}, leaseType={}, roomCnt={}, hasImages={}, hasDescription={}",
+ requestDto.getResidenceType(),
+ requestDto.getLeaseType(),
+ requestDto.getRoomCnt(),
+ requestDto.getImages() != null && !requestDto.getImages().isEmpty(),
+ requestDto.getDescription() != null && !requestDto.getDescription().isBlank());추가 제안(선택 라인 외, 가이드 준수): Swagger 엔드포인트 문서화
// import io.swagger.annotations.ApiOperation;
// import io.swagger.annotations.ApiResponses;
// import io.swagger.annotations.ApiResponse;
@ApiOperation(value = "매물 등록", notes = "이미지와 함께 매물을 등록합니다.")
@ApiResponses({
@ApiResponse(code = 200, message = "성공"),
@ApiResponse(code = 400, message = "유효성 검증 실패"),
@ApiResponse(code = 401, message = "인증 실패")
})
@PostMapping(consumes = "multipart/form-data")
public ResponseEntity<ApiResponse<Integer>> createHome(...)추가 제안(선택 라인 외, 가이드 준수 — 선택): 목록/검색 응답도 ApiResponse로 일원화
return ResponseEntity.ok(ApiResponse.success(PageResponse.of(homes, pageRequest, totalCount)));원하시면 일괄 변경 패치도 도와드릴게요.
🤖 Prompt for AI Agents
In src/main/java/org/scoula/domain/home/controller/HomeControllerImpl.java
around lines 45-48, avoid logging the entire request DTO at INFO (PII risk);
change the first log to debug and stop printing the full DTO, and instead log
only a few non-sensitive structured fields (e.g., userId, title, description
length/preview) at DEBUG or INFO as appropriate; replace the second line that
logs description directly with a safer, minimal field log (e.g., description
length or first N chars) and ensure logs never include addresses, full file
metadata, or other sensitive fields.
🚀 관련 이슈
🔑 주요 변경사항
✔️ 체크 리스트
mainbranch에 실수로 PR 생성 금지)📢 To Reviewers
📸 스크린샷 or 실행영상
Summary by CodeRabbit
신기능
개선
작업