Skip to content

Conversation

@unifolio0
Copy link
Contributor

@unifolio0 unifolio0 commented Oct 31, 2025

🚩 Issue

closed #57

🗣️ 리뷰 요구사항 (선택)

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 새로운 회원 서비스 마이크로서비스 추가 및 배포
    • 회원 관리 REST API 엔드포인트 추가 (생성, 조회, 삭제)
    • 즐겨찾기 레스토랑 관리 API 엔드포인트 추가
    • 서비스 디스커버리(Eureka) 통합
    • 헬스 체크 및 모니터링 기능
  • Documentation

    • 마이크로서비스 마이그레이션 계획 문서 업데이트 및 Phase 2 완료 상태 반영

@unifolio0 unifolio0 self-assigned this Oct 31, 2025
@unifolio0 unifolio0 added the feat label Oct 31, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 31, 2025

Walkthrough

이 PR은 member 서비스를 독립적인 마이크로서비스로 분리하고, REST API 컨트롤러, 애플리케이션 서비스, DTO, 예외 처리를 추가하며, Docker 구성 및 Eureka 클라이언트 설정을 포함합니다. 추가로 restaurant 모듈의 유효성 검사 메시지를 간소화합니다.

Changes

Cohort / File(s) Change Summary
문서 및 인프라 설정
claudedocs/microservices-migration-plan.md, docker-compose.yml, domain-member/build.gradle, domain-member/Dockerfile, domain-member/src/main/resources/application.yml
Phase 2 완료 상태 반영, member-service를 docker-compose에 추가 (port 8082, MySQL 의존), Gradle 의존성 추가 (Web, Actuator, Eureka Client), 멀티 스테이지 Dockerfile 추가 (Build/Runtime 단계), Spring Boot 설정 파일 추가 (Eureka, JPA, 로깅 구성)
Member 서비스 진입점
domain-member/src/main/java/com/wellmeet/domain/MemberServiceApplication.java
Spring Boot 애플리케이션 클래스 스켈레톤 추가 (코드는 주석 처리됨)
Member REST 컨트롤러
domain-member/src/main/java/com/wellmeet/domain/member/controller/MemberController.java, FavoriteRestaurantController.java
MemberController: 회원 CRUD 엔드포인트 추가 (POST, GET, DELETE), FavoriteRestaurantController: 즐겨찾기 관리 엔드포인트 추가 (GET, POST, DELETE)
Member DTO
domain-member/src/main/java/com/wellmeet/domain/member/dto/CreateMemberRequest.java, ErrorResponse.java, FavoriteRestaurantResponse.java, MemberIdsRequest.java, MemberResponse.java
요청/응답 DTO 레코드 5개 추가: CreateMemberRequest, ErrorResponse (statusCode, message, timestamp), FavoriteRestaurantResponse (엔티티 매핑), MemberIdsRequest, MemberResponse (엔티티 매핑)
Member 애플리케이션 서비스
domain-member/src/main/java/com/wellmeet/domain/member/service/MemberApplicationService.java, FavoriteRestaurantApplicationService.java
MemberApplicationService: createMember, getMemberById, getMembersByIds, deleteMember 메서드 추가, FavoriteRestaurantApplicationService: isFavorite, getFavoritesByMemberId, addFavorite, removeFavorite 메서드 추가 (트랜잭션 경계 적용)
Member 예외 처리
domain-member/src/main/java/com/wellmeet/domain/member/exception/MemberExceptionHandler.java
RestControllerAdvice로 중앙화된 예외 처리: MemberException, MethodArgumentNotValidException, IllegalArgumentException, 일반 Exception 핸들링
Member 도메인 서비스
domain-member/src/main/java/com/wellmeet/domain/member/MemberDomainService.java
java.util.Collection 미사용 임포트 제거
Restaurant 모듈 검증 정리
domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/AvailableDateIdsRequest.java, DecreaseCapacityRequest.java, IncreaseCapacityRequest.java, RestaurantIdsRequest.java
검증 애노테이션의 커스텀 메시지 제거 및 @min 제약조건 제거 (기본 메시지 사용)

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant MemberController
    participant MemberApplicationService
    participant MemberDomainService
    participant MemberRepository
    participant ErrorHandler

    Client->>MemberController: POST /api/members (CreateMemberRequest)
    MemberController->>MemberApplicationService: createMember(name, nickname, email, phone)
    MemberApplicationService->>MemberRepository: save(new Member(...))
    MemberRepository-->>MemberApplicationService: Member entity
    MemberApplicationService->>MemberApplicationService: MemberResponse.from(Member)
    MemberApplicationService-->>MemberController: MemberResponse
    MemberController-->>Client: 201 Created + MemberResponse

    Client->>MemberController: GET /api/members/{id}
    MemberController->>MemberApplicationService: getMemberById(id)
    MemberApplicationService->>MemberDomainService: getMemberById(id)
    MemberDomainService-->>MemberApplicationService: Member entity
    MemberApplicationService-->>MemberController: MemberResponse
    MemberController-->>Client: 200 OK + MemberResponse
    
    Client->>MemberController: POST /api/members (invalid request)
    rect rgb(255, 200, 200)
    MemberController->>ErrorHandler: MethodArgumentNotValidException
    ErrorHandler-->>Client: 400 Bad Request + ErrorResponse
    end
Loading
sequenceDiagram
    actor Client
    participant FavoriteController
    participant FavoriteApplicationService
    participant FavoriteRestaurantDomainService
    participant Repository

    Client->>FavoriteController: POST /api/favorites?memberId=X&restaurantId=Y
    FavoriteController->>FavoriteApplicationService: addFavorite(memberId, restaurantId)
    rect rgb(200, 220, 255)
    Note over FavoriteApplicationService: @Transactional
    FavoriteApplicationService->>Repository: save(new FavoriteRestaurant(...))
    end
    Repository-->>FavoriteApplicationService: saved entity
    FavoriteApplicationService-->>FavoriteController: FavoriteRestaurantResponse
    FavoriteController-->>Client: 201 Created

    Client->>FavoriteController: DELETE /api/favorites?memberId=X&restaurantId=Y
    FavoriteController->>FavoriteApplicationService: removeFavorite(memberId, restaurantId)
    rect rgb(200, 220, 255)
    Note over FavoriteApplicationService: @Transactional
    FavoriteApplicationService->>FavoriteRestaurantDomainService: 조회 후 삭제
    end
    FavoriteApplicationService-->>FavoriteController: void
    FavoriteController-->>Client: 204 No Content
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • 특별히 검토가 필요한 영역:
    • MemberServiceApplication 클래스가 모두 주석 처리된 상태 - 빈 스캔 이슈 설명 및 활성화 계획 확인 필요
    • MemberApplicationService 및 FavoriteRestaurantApplicationService의 트랜잭션 경계 설정 (클래스 레벨 read-only, 메서드 레벨 오버라이드) 검증
    • MemberExceptionHandler의 모든 엔드포인트 시나리오에 대한 예외 처리 커버리지 확인
    • Docker Compose 네트워킹 및 Eureka 클라이언트 등록 설정 (mysql-member, discovery-server 의존성)
    • 기존 restaurant-service 변경사항과의 호환성 검증 (RestaurantServiceApplication 네이밍 변경)
    • 모든 DTO 검증 애노테이션 정합성 확인

Possibly related PRs

  • [REFACTOR] member 모듈 분리 #52: Member 모듈 리팩토링에서 ID 기반 Member API, FavoriteRestaurant 생성자 변경, MemberRepository 추가 등이 이 PR의 member-module 분리와 동일한 시그니처/클래스 변경과 직결됨
  • [FEAT] restaurant 서버 분리 #63: Domain-restaurant 모듈의 Spring Boot 진입점 이름 변경(RestaurantServiceApplication) 및 DTO/컨트롤러/서비스 변경이 이 PR과 겹침
  • [REFACTOR] restaurant 모듈 분리 #54: Domain-restaurant 모듈의 애플리케이션 진입점 및 도메인 클래스/설정 변경이 공통으로 영향받음

Suggested reviewers

  • ezcolin2

Poem

🐰 새로운 마이크로서비스의 탄생,
Member 서버 분리로 춤을 춘다네,
REST API 각설주처럼 소복하고,
Docker 컨테이너 안에 안전히 담겨,
Eureka의 발견 안에서 반짝반짝! 🌟

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning domain-restaurant 디렉토리의 변경사항들이 member 서버 분리 목표와 직접적으로 관련되지 않은 범위 외 변경으로 나타납니다. AvailableDateIdsRequest, DecreaseCapacityRequest, IncreaseCapacityRequest, RestaurantIdsRequest에서 커스텀 검증 메시지 제거 및 Min 제약조건 제거 등의 변경사항들은 검증 주석 정리/리팩토링으로 보이며, 명시된 이슈 #57의 "member 서버 분리" 목표와 무관한 변경으로 판단됩니다. domain-restaurant 도메인의 검증 제약조건 정리 변경사항들은 별도의 리팩토링 PR로 분리하거나, 이러한 변경사항이 member 서버 분리 작업의 일부인 경우 PR 설명에 명확하게 그 이유와 범위를 문서화하는 것을 권장합니다.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR 제목 "[FEAT] member 서버 분리"은 변경사항의 주요 목적과 명확하게 일치합니다. 원본 요약에서 보면 새로운 member 마이크로서비스가 생성되었으며, 컨트롤러, 서비스, DTO, 예외 처리, Docker 설정, Eureka 통합 등을 포함한 완전한 member 서버 구현이 추가되었습니다. 제목은 간결하고 구체적이며 팀원들이 변경 이력을 스캔할 때 명확하게 이해할 수 있는 내용입니다.
Description Check ✅ Passed PR 설명은 제공된 템플릿 구조를 따르고 있으며 필수 섹션들을 포함하고 있습니다. "🚩 Issue" 섹션에서 관련 이슈 #57을 참조하고, "🗣️ 리뷰 요구사항 (선택)" 섹션도 템플릿에 명시되어 있습니다. 설명 내용은 최소한이지만 템플릿의 구조를 충실히 따르고 있으며, 폐쇄하는 이슈 번호가 명확하게 지정되어 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @unifolio0, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 마이크로서비스 전환 로드맵의 중요한 이정표인 domain-member 모듈을 독립적인 서비스로 분리하는 작업을 완료합니다. 이를 통해 회원 및 즐겨찾기 관리 기능이 자체적인 배포 단위를 가지게 되어, 시스템의 확장성과 유지보수성이 향상됩니다. 새로운 서비스는 전용 API 엔드포인트와 데이터베이스를 사용하며, 기존 api-* 모듈과의 직접적인 의존성은 현재 단계에서는 유지됩니다.

Highlights

  • 회원 서비스 분리 완료: 마이크로서비스 전환 계획의 2단계인 domain-member 모듈의 독립 서버 구현이 완료되었습니다.
  • 새로운 API 및 서비스 계층: 회원 및 즐겨찾기 레스토랑 관리를 위한 REST API 컨트롤러, 애플리케이션 서비스 계층, DTO, 예외 처리 로직이 추가되었습니다.
  • 인프라 구성 업데이트: domain-member 서비스를 위한 Dockerfile 및 docker-compose.yml 설정이 추가되어 독립적인 배포 환경을 지원합니다.
  • 문서 업데이트: 마이크로서비스 전환 계획 문서(microservices-migration-plan.md)가 2단계 완료 사항 및 기술 스택 변경 내용을 반영하여 업데이트되었습니다.
  • 유효성 검사 개선: domain-restaurant 모듈의 DTO에서 유효성 검사 어노테이션의 message 속성이 제거되어 간결성이 향상되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 member 도메인을 별도의 마이크로서비스로 분리하는 작업을 담고 있습니다. 전반적으로 마이그레이션 계획에 따라 컨트롤러, 서비스, DTO, Docker 설정 등 필요한 구성 요소들이 잘 추가되었습니다. 코드 구조와 내용이 명확하며, MSA로의 전환을 위한 중요한 단계로 보입니다. 몇 가지 개선점을 제안드립니다. Docker 이미지 빌드 캐시 최적화, 컨트롤러에서의 일관된 의존성 주입 방식 사용, 예외 처리 시 로깅 추가, 서비스 레이어의 책임 분리 강화 등을 통해 코드의 유지보수성과 안정성을 높일 수 있을 것입니다. 자세한 내용은 각 파일에 대한 리뷰 코멘트를 참고해주세요.

Comment on lines +35 to +42
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
ErrorResponse errorResponse = ErrorResponse.of(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"Internal server error occurred"
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

예상치 못한 예외를 처리하는 handleException 메소드에서 예외를 로깅하지 않고 있습니다. 프로덕션 환경에서 원인을 알 수 없는 500 에러가 발생했을 때, 로그가 없으면 원인 파악이 매우 어렵습니다. log.error() 등을 사용하여 예외 스택 트레이스를 기록하는 것이 중요합니다. 클래스에 @Slf4j 어노테이션을 추가하거나 Logger 필드를 직접 선언한 후, 다음과 같이 로그를 추가해주세요.

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleException(Exception e) {
        log.error("Unhandled exception occurred", e);
        ErrorResponse errorResponse = ErrorResponse.of(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                "Internal server error occurred"
        );
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }

SPRING_PROFILES_ACTIVE: local
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-member:3306/wellmeet_member
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: password

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

데이터베이스 비밀번호와 같은 민감한 정보를 docker-compose.yml에 직접 작성하는 것은 보안상 위험할 수 있습니다. 로컬 환경이라도 .env 파일을 활용하여 환경 변수로 주입하고, .env 파일은 .gitignore에 추가하여 관리하는 것이 좋습니다. 이렇게 하면 실수로 인증 정보가 Git에 커밋되는 것을 방지할 수 있습니다.

      SPRING_DATASOURCE_PASSWORD: ${MEMBER_DB_PASSWORD}

Comment on lines +4 to +5
COPY . .
RUN gradle :domain-member:bootJar --no-daemon

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Docker 이미지 빌드 효율을 높이기 위해 Docker 레이어 캐시를 활용하는 것이 좋습니다. 현재 COPY . . 명령어는 소스 코드의 작은 변경만으로도 전체 캐시를 무효화하여 매번 모든 의존성을 새로 다운로드하게 만듭니다.

이를 개선하기 위해, 빌드 파일을 먼저 복사하여 의존성을 다운로드하고, 그 다음에 소스 코드를 복사하는 단계로 나누는 것을 권장합니다. 이렇게 하면 소스 코드만 변경되었을 때 의존성 다운로드 단계를 건너뛰어 빌드 시간을 크게 단축할 수 있습니다.

예시적인 구조는 다음과 같습니다:

# 1. 빌드 관련 파일만 복사
COPY build.gradle settings.gradle ./ 
# (필요에 따라 각 모듈의 build.gradle도 복사)

# 2. 의존성 다운로드 (이 레이어가 캐시됨)
RUN gradle dependencies

# 3. 전체 소스 코드 복사
COPY . .

# 4. 애플리케이션 빌드
RUN gradle :domain-member:bootJar --no-daemon

Comment on lines +22 to +24
public FavoriteRestaurantController(FavoriteRestaurantApplicationService favoriteRestaurantApplicationService) {
this.favoriteRestaurantApplicationService = favoriteRestaurantApplicationService;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

서비스 레이어에서는 @RequiredArgsConstructor를 사용하여 생성자 주입을 간결하게 처리하고 있습니다. 컨트롤러에서도 일관성을 위해 클래스 레벨에 @RequiredArgsConstructor를 추가하고 이 생성자를 제거하는 것을 추천합니다. 이렇게 하면 코드가 더 간결해지고 일관성이 유지됩니다.

Comment on lines +25 to +27
public MemberController(MemberApplicationService memberApplicationService) {
this.memberApplicationService = memberApplicationService;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

FavoriteRestaurantController와 마찬가지로, 서비스 레이어와의 일관성을 위해 Lombok의 @RequiredArgsConstructor를 사용하여 생성자 코드를 제거하고 코드를 간결하게 유지하는 것을 추천합니다.

member.getUpdatedAt()
);
}
} No newline at end of file

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

파일의 끝에 개행 문자가 없습니다. POSIX 표준에 따르면 텍스트 파일은 개행 문자로 끝나야 하며, 일부 도구(Git, diff 등)에서 예기치 않은 동작을 유발할 수 있습니다. 파일 끝에 빈 줄을 추가하는 것이 좋습니다.

Suggested change
}
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (7)
claudedocs/microservices-migration-plan.md (1)

175-197: 단계 1.2 제목이 실제 상태를 정확히 반영하지 않음

제목 "Spring Boot Application 활성화"는 오도적입니다. 실제로는 Application 클래스가 완전히 주석 처리되어 있어 비활성 상태입니다. "빈 스캔 문제"의 근본 원인과 해결 방안을 명시하지 않아, 다른 팀원이 이를 정확히 이해하고 진행하기 어려울 수 있습니다.

제안: 제목을 "Spring Boot Application 클래스 생성 (주석 처리 상태)"로 변경하고, 빈 스캔 문제의 구체적 원인과 해결 예상 시점을 추가하세요.

domain-member/src/main/java/com/wellmeet/domain/member/dto/CreateMemberRequest.java (2)

15-16: 전화번호 형식 검증을 고려해보세요.

전화번호 필드에 패턴 검증을 추가하면 데이터 무결성이 향상됩니다.

예시:

 public record CreateMemberRequest(
         // ...
         
         @NotBlank
+        @Pattern(regexp = "^01[0-9]-?[0-9]{3,4}-?[0-9]{4}$", message = "올바른 전화번호 형식이 아닙니다")
         String phone
 ) {

5-17: 검증 오류 메시지 커스터마이징을 고려해보세요.

더 나은 사용자 경험을 위해 각 검증 어노테이션에 커스텀 메시지를 추가하는 것을 고려해보세요.

예시:

 public record CreateMemberRequest(
-        @NotBlank
+        @NotBlank(message = "이름은 필수입니다")
         String name,
 
-        @NotBlank
+        @NotBlank(message = "닉네임은 필수입니다")
         String nickname,
domain-member/src/main/resources/application.yml (1)

14-21: 프로덕션 환경에서 ddl-auto 설정을 확인하세요.

ddl-auto: update는 개발 환경에서는 편리하지만, 프로덕션에서는 의도하지 않은 스키마 변경을 일으킬 수 있습니다. 프로덕션 프로파일에서는 validate 또는 none으로 설정하는 것을 권장합니다.

domain-member/src/main/java/com/wellmeet/domain/member/controller/FavoriteRestaurantController.java (2)

44-61: REST API 설계 개선을 고려하세요.

POST와 DELETE 엔드포인트가 @RequestParam을 사용하고 있습니다. 더 RESTful한 설계를 위해 다음을 고려해보세요:

  • POST: Request body 사용 (e.g., {"memberId": "...", "restaurantId": "..."})
  • DELETE: Path variable 사용 (e.g., DELETE /api/favorites/{memberId}/{restaurantId})

현재 구현도 동작하지만, REST 관례를 따르면 API 일관성이 향상됩니다.


26-33: 요청 파라미터에 유효성 검증 추가를 고려하세요.

memberIdrestaurantId 파라미터에 대한 유효성 검증이 없습니다. 빈 문자열이나 null 값 방지를 위해 @NotBlank 애노테이션 추가를 고려해보세요.

예시:

@RequestParam @NotBlank String memberId,
@RequestParam @NotBlank String restaurantId

Also applies to: 44-52, 54-61

domain-member/src/main/java/com/wellmeet/domain/member/controller/MemberController.java (1)

46-52: 배치 조회 엔드포인트의 HTTP 메서드를 재검토하세요.

POST /api/members/batch 엔드포인트는 조회 작업에 POST를 사용하고 있어 HTTP 메서드의 의미론과 맞지 않습니다. 다음 방안을 고려하세요:

  1. GET with query parameter: ID 목록이 적은 경우 GET /api/members?ids=id1,id2,id3
  2. POST to search endpoint: 의도를 명확히 하기 위해 POST /api/members/search 또는 /api/members/query로 변경

현재 구조가 대량의 ID를 처리하기 위한 의도적인 선택이라면, 엔드포인트 이름을 더 명확하게 변경하는 것을 권장합니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 58075f4 and 11cb6d0.

📒 Files selected for processing (21)
  • claudedocs/microservices-migration-plan.md (3 hunks)
  • docker-compose.yml (1 hunks)
  • domain-member/Dockerfile (1 hunks)
  • domain-member/build.gradle (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/MemberServiceApplication.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/MemberDomainService.java (0 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/controller/FavoriteRestaurantController.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/controller/MemberController.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/CreateMemberRequest.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/ErrorResponse.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/FavoriteRestaurantResponse.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/MemberIdsRequest.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/MemberResponse.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/exception/MemberExceptionHandler.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/service/FavoriteRestaurantApplicationService.java (1 hunks)
  • domain-member/src/main/java/com/wellmeet/domain/member/service/MemberApplicationService.java (1 hunks)
  • domain-member/src/main/resources/application.yml (1 hunks)
  • domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/AvailableDateIdsRequest.java (1 hunks)
  • domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/DecreaseCapacityRequest.java (1 hunks)
  • domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/IncreaseCapacityRequest.java (1 hunks)
  • domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/RestaurantIdsRequest.java (1 hunks)
💤 Files with no reviewable changes (1)
  • domain-member/src/main/java/com/wellmeet/domain/member/MemberDomainService.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-10T02:52:48.337Z
Learnt from: unifolio0
Repo: Team-soft-macaron/WellMeet-Backend PR: 14
File: src/main/java/com/wellmeet/recommend/dto/RecommendRestaurantResponse.java:3-3
Timestamp: 2025-07-10T02:52:48.337Z
Learning: The Restaurant class is located at `com.wellmeet.restaurant.domain.Restaurant` after the package refactoring in the WellMeet-Backend project, not in a nested model package structure.

Applied to files:

  • domain-member/src/main/java/com/wellmeet/domain/member/controller/FavoriteRestaurantController.java
  • domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/RestaurantIdsRequest.java
  • domain-member/src/main/java/com/wellmeet/domain/member/dto/FavoriteRestaurantResponse.java
  • claudedocs/microservices-migration-plan.md
  • domain-member/src/main/java/com/wellmeet/domain/member/service/FavoriteRestaurantApplicationService.java
🧬 Code graph analysis (4)
domain-member/src/main/java/com/wellmeet/domain/member/controller/FavoriteRestaurantController.java (1)
domain-member/src/main/java/com/wellmeet/domain/member/controller/MemberController.java (1)
  • RestController (19-59)
domain-member/src/main/java/com/wellmeet/domain/member/service/MemberApplicationService.java (1)
domain-member/src/main/java/com/wellmeet/domain/member/MemberDomainService.java (1)
  • Service (11-25)
domain-member/src/main/java/com/wellmeet/domain/member/service/FavoriteRestaurantApplicationService.java (3)
domain-member/src/main/java/com/wellmeet/domain/member/service/MemberApplicationService.java (1)
  • Service (12-44)
domain-member/src/main/java/com/wellmeet/domain/member/MemberDomainService.java (1)
  • Service (11-25)
domain-member/src/main/java/com/wellmeet/domain/member/FavoriteRestaurantDomainService.java (1)
  • Service (11-37)
domain-member/src/main/java/com/wellmeet/domain/member/controller/MemberController.java (1)
domain-member/src/main/java/com/wellmeet/domain/member/controller/FavoriteRestaurantController.java (1)
  • RestController (16-62)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-push
🔇 Additional comments (16)
claudedocs/microservices-migration-plan.md (1)

296-374: Phase 2 상태 표기와 실제 상태의 불일치 - 명확성 필요

Phase 2를 "✅ (완료)"로 표시하고 모든 완료 기준을 [x]로 체크했지만, 동시에 "bootJar 빌드 불가", "Docker 컨테이너 실행 검증 보류"라는 중대한 이슈를 명시하고 있습니다. 이는 다음과 같은 혼동을 야기합니다:

  • 아키텍처 및 코드 구조는 완료: ✅ (명확함)
  • 실제 배포 가능성: ❓ (불명확함)

다른 개발자들이 이 문서를 참고할 때, Phase 2가 프로덕션 배포 가능한 상태인지 확실하게 판단할 수 없습니다.

제안:

  • 상태를 "Phase 2: domain-member 구현 ✅ (코드 구조 완료, 배포 검증 보류)" 형태로 명확히 하거나
  • "완료"의 의미를 명시하는 섹션을 추가하여, 팀의 공동 이해를 확보하세요
domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/AvailableDateIdsRequest.java (1)

7-8: 검증 메시지 단순화가 적절합니다.

커스텀 검증 메시지를 제거하고 기본 메시지를 사용하는 것은 합리적인 선택입니다. 검증 동작은 동일하게 유지됩니다.

domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/RestaurantIdsRequest.java (1)

7-8: 검증 메시지 단순화가 적절합니다.

커스텀 검증 메시지를 기본 메시지로 변경하는 것은 일관된 접근 방식이며, 검증 로직에는 영향을 미치지 않습니다.

domain-member/src/main/java/com/wellmeet/domain/member/dto/FavoriteRestaurantResponse.java (1)

6-22: DTO 구현이 깔끔합니다.

레코드 기반 DTO와 정적 팩토리 메서드 패턴이 적절하게 구현되었습니다.

domain-member/build.gradle (1)

10-12: 마이크로서비스에 적합한 의존성이 추가되었습니다.

REST API 컨트롤러, 헬스 체크, 서비스 디스커버리를 위한 의존성이 올바르게 추가되었습니다.

domain-member/src/main/java/com/wellmeet/domain/member/dto/ErrorResponse.java (1)

5-13: 표준적인 에러 응답 구조입니다.

statusCode, message, timestamp를 포함한 에러 응답 DTO가 적절하게 구현되었습니다.

domain-member/src/main/java/com/wellmeet/domain/member/dto/MemberIdsRequest.java (1)

6-9: 배치 요청 DTO가 적절하게 구현되었습니다.

@notempty 검증으로 빈 리스트를 방지하고 있으며, 배치 조회 기능에 적합한 구조입니다.

docker-compose.yml (1)

131-155: 멤버 서비스 Docker 구성이 추가되었습니다.

서비스 구성이 전반적으로 적절하나, Line 151의 healthcheck가 curl을 사용합니다. 이는 Dockerfile의 slim 이미지에 curl이 포함되지 않아 실패할 수 있습니다. Dockerfile 리뷰 코멘트를 참조하세요.

domain-member/Dockerfile (1)

1-17: 멀티 스테이지 빌드 구조가 적절합니다.

Gradle 빌드와 런타임을 분리하여 최종 이미지 크기를 최적화하고 있으며, JVM 메모리 설정과 G1GC 사용도 적절합니다.

domain-member/src/main/java/com/wellmeet/domain/MemberServiceApplication.java (1)

1-12: 이 리뷰 의견은 부정확합니다. 수정이 불필요합니다.

domain-member는 독립 실행 가능한 서비스가 아니라 공유 도메인 라이브러리 모듈입니다. 검증 결과:

  • build.gradle에서 java-test-fixtures 플러그인 사용 (라이브러리 모듈 표시)
  • api-user, api-owner, batch-reminder 등 여러 서비스에서 의존성으로 사용
  • 독립 실행 가능한 메인 애플리케이션: api-user, api-owner, discovery-server, batch-reminder (모두 활성화된 @SpringBootApplication 포함)
  • 도메인 모듈(domain-member, domain-restaurant)의 주석 처리된 진입점은 의도된 설계

이는 멀티모듈 마이크로서비스 아키텍처의 정상적인 패턴입니다.

Likely an incorrect or invalid review comment.

domain-member/src/main/java/com/wellmeet/domain/member/dto/MemberResponse.java (1)

6-33: LGTM!

DTO 레코드 구조가 깔끔하고, 정적 팩토리 메서드가 Member 엔티티로부터 적절하게 매핑하고 있습니다. 불변성을 보장하는 record 타입 사용이 적절합니다.

domain-member/src/main/resources/application.yml (1)

23-33: LGTM!

Eureka 클라이언트 설정이 적절합니다. 랜덤 인스턴스 ID 사용으로 다중 인스턴스 배포를 지원하고 있습니다.

domain-member/src/main/java/com/wellmeet/domain/member/service/MemberApplicationService.java (3)

20-25: 회원 생성 시 중복 검증을 확인하세요.

이메일이나 전화번호의 중복 검증이 없습니다. 이러한 필드들이 고유해야 한다면, 생성 전 중복 검증을 추가하거나 데이터베이스 제약조건(unique constraint)이 설정되어 있는지 확인하세요. 제약조건 없이 중복 데이터가 입력되면 데이터 무결성 문제가 발생할 수 있습니다.

중복 검증이 필요한 경우 다음과 같이 추가할 수 있습니다:

@Transactional
public MemberResponse createMember(String name, String nickname, String email, String phone) {
    // 중복 검증 로직 추가
    if (memberRepository.existsByEmail(email)) {
        throw new MemberException(MemberErrorCode.DUPLICATE_EMAIL);
    }
    Member member = new Member(name, nickname, email, phone);
    Member savedMember = memberRepository.save(member);
    return MemberResponse.from(savedMember);
}

39-43: LGTM!

삭제 전 엔티티를 조회하여 존재 여부를 검증하는 방식이 안전합니다. 존재하지 않는 회원 삭제 시 명확한 예외가 발생합니다.


32-37: LGTM!

배치 조회 메서드가 스트림 API를 효과적으로 사용하고 있습니다. 메서드 참조로 깔끔하게 DTO 변환을 수행합니다.

domain-member/src/main/java/com/wellmeet/domain/member/service/FavoriteRestaurantApplicationService.java (1)

18-27: LGTM!

조회 및 삭제 메서드들이 깔끔하게 구현되어 있습니다. 도메인 서비스와 적절히 분리되어 있고, DTO 변환도 명확합니다.

Also applies to: 37-41

Comment on lines +14 to +15
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
CMD curl -f http://localhost:8082/actuator/health || exit 1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

HEALTHCHECK가 실패할 수 있습니다.

openjdk:21-jdk-slim 이미지에는 curl이 기본적으로 포함되어 있지 않습니다. 헬스체크가 실패하여 컨테이너가 unhealthy 상태가 됩니다.

해결 방법 1 (권장): 런타임 이미지에 curl 설치

 # Stage 2: Runtime
 FROM openjdk:21-jdk-slim
 WORKDIR /app
+RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
 COPY --from=build /app/domain-member/build/libs/*.jar app.jar

해결 방법 2: wget 사용 (slim 이미지에 포함됨)

 HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
-  CMD curl -f http://localhost:8082/actuator/health || exit 1
+  CMD wget --no-verbose --tries=1 --spider http://localhost:8082/actuator/health || exit 1
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
CMD curl -f http://localhost:8082/actuator/health || exit 1
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
CMD wget --no-verbose --tries=1 --spider http://localhost:8082/actuator/health || exit 1
🤖 Prompt for AI Agents
In domain-member/Dockerfile around lines 14 to 15, the HEALTHCHECK uses curl but
the openjdk:21-jdk-slim base image doesn't include curl, causing health checks
to fail; fix by either installing curl in the image (add package install in the
image build stage before HEALTHCHECK, e.g., apt-get update && apt-get install -y
curl && cleanup) or change the HEALTHCHECK to use wget (which is present in
slim) or a shell-built-in check (e.g., using /bin/sh to test the port) so the
command succeeds without relying on missing binaries.

Comment on lines +12 to +13
@NotBlank
String email,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

email 필드에 형식 검증이 필요합니다.

email 필드가 @notblank만으로 검증되고 있습니다. 이메일 형식의 유효성을 보장하기 위해 @Email 어노테이션을 추가해야 합니다.

다음 diff를 적용하세요:

+import jakarta.validation.constraints.Email;
+
 public record CreateMemberRequest(
         @NotBlank
         String name,
 
         @NotBlank
         String nickname,
 
         @NotBlank
+        @Email
         String email,
🤖 Prompt for AI Agents
In
domain-member/src/main/java/com/wellmeet/domain/member/dto/CreateMemberRequest.java
around lines 12 to 13, the email field currently has only @NotBlank; add the
@Email validation annotation to ensure proper email format and add the
corresponding import (javax.validation.constraints.Email) if it is not already
present; keep @NotBlank alongside @Email so both non-empty and format checks are
enforced.

Comment on lines +14 to +42
@ExceptionHandler(MemberException.class)
public ResponseEntity<ErrorResponse> handleMemberException(MemberException e) {
ErrorResponse errorResponse = ErrorResponse.of(e.getStatusCode(), e.getMessage());
return ResponseEntity.status(e.getStatusCode()).body(errorResponse);
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException e) {
FieldError fieldError = e.getBindingResult().getFieldError();
String message = fieldError != null ? fieldError.getDefaultMessage() : "Validation failed";

ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), message);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
}

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException e) {
ErrorResponse errorResponse = ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
ErrorResponse errorResponse = ErrorResponse.of(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"Internal server error occurred"
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

예외 핸들러에 로깅을 추가하세요.

예외 핸들러에 로깅이 없어 디버깅과 모니터링이 어렵습니다. 특히 일반 Exception 핸들러(lines 35-42)는 중요한 에러 정보를 숨길 수 있으므로, 최소한 에러 레벨 로그를 추가해야 합니다.

다음과 같이 로깅을 추가하는 것을 권장합니다:

+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 @RestControllerAdvice
 public class MemberExceptionHandler {
 
     @ExceptionHandler(MemberException.class)
     public ResponseEntity<ErrorResponse> handleMemberException(MemberException e) {
+        log.warn("MemberException occurred: {}", e.getMessage());
         ErrorResponse errorResponse = ErrorResponse.of(e.getStatusCode(), e.getMessage());
         return ResponseEntity.status(e.getStatusCode()).body(errorResponse);
     }
 
     @ExceptionHandler(Exception.class)
     public ResponseEntity<ErrorResponse> handleException(Exception e) {
+        log.error("Unexpected error occurred", e);
         ErrorResponse errorResponse = ErrorResponse.of(
                 HttpStatus.INTERNAL_SERVER_ERROR.value(),
                 "Internal server error occurred"
         );
         return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
     }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
domain-member/src/main/java/com/wellmeet/domain/member/exception/MemberExceptionHandler.java
around lines 14 to 42, the exception handlers currently do not log errors which
hinders debugging and monitoring; add logging to each handler (preferably using
a class-level SLF4J logger or Lombok @Slf4j) and log at error level including
contextual information and the Throwable itself: for MemberException log the
status and message with the exception, for MethodArgumentNotValidException log
the field name and validation message (or binding result) and the exception, for
IllegalArgumentException log the provided message and exception, and for the
generic Exception handler log a clear contextual message and pass the exception
to capture the stack trace; ensure necessary imports or Lombok annotation are
added and keep response behavior unchanged.

Comment on lines +29 to +34
@Transactional
public FavoriteRestaurantResponse addFavorite(String memberId, String restaurantId) {
FavoriteRestaurant favoriteRestaurant = new FavoriteRestaurant(memberId, restaurantId);
favoriteRestaurantDomainService.save(favoriteRestaurant);
return FavoriteRestaurantResponse.from(favoriteRestaurant);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

즐겨찾기 추가 시 중복 방지 로직을 추가하세요.

동일한 회원-레스토랑 조합에 대한 중복 즐겨찾기 생성을 방지하는 로직이 없습니다. 중복 생성을 허용하지 않으려면 추가 전 존재 여부를 확인해야 합니다.

다음과 같이 중복 검증을 추가하세요:

 @Transactional
 public FavoriteRestaurantResponse addFavorite(String memberId, String restaurantId) {
+    if (favoriteRestaurantDomainService.isFavorite(memberId, restaurantId)) {
+        throw new MemberException(MemberErrorCode.FAVORITE_ALREADY_EXISTS);
+    }
     FavoriteRestaurant favoriteRestaurant = new FavoriteRestaurant(memberId, restaurantId);
     favoriteRestaurantDomainService.save(favoriteRestaurant);
     return FavoriteRestaurantResponse.from(favoriteRestaurant);
 }
🤖 Prompt for AI Agents
In
domain-member/src/main/java/com/wellmeet/domain/member/service/FavoriteRestaurantApplicationService.java
around lines 29 to 34, add a pre-save duplicate check for the same memberId and
restaurantId and prevent creating a duplicate favorite: call the
domainService/repository method (e.g., existsByMemberIdAndRestaurantId or
findByMemberIdAndRestaurantId) before creating the FavoriteRestaurant, and if it
exists either return the existing FavoriteRestaurantResponse or throw a
DomainDuplicateException; additionally ensure a unique constraint at the DB
level for (member_id, restaurant_id) to guard against race conditions and handle
DataIntegrityViolationException (map it to the same
duplicate-response/exception) so duplicates are never persisted.

Comment on lines +8 to +12
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/wellmeet_member
username: root
password: password
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

데이터베이스 자격증명을 환경변수로 외부화하세요.

데이터베이스 URL, 사용자명, 비밀번호가 하드코딩되어 있습니다. 환경변수를 사용하여 외부화해야 합니다.

다음 diff를 적용하세요:

   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://localhost:3307/wellmeet_member
-    username: root
-    password: password
+    url: ${DB_URL:jdbc:mysql://localhost:3307/wellmeet_member}
+    username: ${DB_USERNAME:root}
+    password: ${DB_PASSWORD}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/wellmeet_member
username: root
password: password
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL:jdbc:mysql://localhost:3307/wellmeet_member}
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD}
🤖 Prompt for AI Agents
In domain-member/src/main/resources/application.yml around lines 8 to 12, the DB
URL/username/password are hardcoded; change them to reference environment
variables (e.g. use property placeholders like ${DB_URL} / ${DB_USERNAME} /
${DB_PASSWORD} with sensible defaults or none) so credentials are externalized,
update any docs/deployment manifests to set those env vars, and remove hardcoded
secrets from the file before committing.

Comment on lines +6 to 10
@NotNull
Long availableDateId,

@NotNull(message = "Party size는 필수입니다")
@Min(value = 1, message = "Party size는 최소 1명 이상이어야 합니다")
@NotNull
Integer partySize
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

partySize에 대한 최솟값 검증이 제거되었습니다.

@Min(value = 1) 제약 조건을 제거하면 partySize가 0 또는 음수 값을 허용하게 되어 비즈니스 로직 오류가 발생할 수 있습니다. 파티 크기는 최소 1명 이상이어야 합니다.

다음 diff를 적용하여 최솟값 검증을 복원하세요:

 package com.wellmeet.domain.restaurant.dto;
 
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Min;
 
 public record DecreaseCapacityRequest(
         @NotNull
         Long availableDateId,
 
         @NotNull
+        @Min(1)
         Integer partySize
 ) {
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@NotNull
Long availableDateId,
@NotNull(message = "Party size는 필수입니다")
@Min(value = 1, message = "Party size는 최소 1명 이상이어야 합니다")
@NotNull
Integer partySize
package com.wellmeet.domain.restaurant.dto;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Min;
public record DecreaseCapacityRequest(
@NotNull
Long availableDateId,
@NotNull
@Min(1)
Integer partySize
) {
}
🤖 Prompt for AI Agents
In
domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/DecreaseCapacityRequest.java
around lines 6 to 10, the @Min(1) validation on the partySize field was removed
which allows 0 or negative party sizes; restore the minimum-value constraint by
adding @Min(1) above the partySize field (and add the import for
javax.validation.constraints.Min if it's not present) so that partySize must be
at least 1.

Comment on lines +6 to 10
@NotNull
Long availableDateId,

@NotNull(message = "Party size는 필수입니다")
@Min(value = 1, message = "Party size는 최소 1명 이상이어야 합니다")
@NotNull
Integer partySize
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

partySize에 대한 최솟값 검증이 제거되었습니다.

@Min(value = 1) 제약 조건을 제거하면 partySize가 0 또는 음수 값을 허용하게 됩니다. 이는 비즈니스 로직상 유효하지 않은 값입니다.

다음 diff를 적용하여 최솟값 검증을 복원하세요:

 package com.wellmeet.domain.restaurant.dto;
 
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Min;
 
 public record IncreaseCapacityRequest(
         @NotNull
         Long availableDateId,
 
         @NotNull
+        @Min(1)
         Integer partySize
 ) {
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@NotNull
Long availableDateId,
@NotNull(message = "Party size는 필수입니다")
@Min(value = 1, message = "Party size는 최소 1명 이상이어야 합니다")
@NotNull
Integer partySize
package com.wellmeet.domain.restaurant.dto;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Min;
public record IncreaseCapacityRequest(
@NotNull
Long availableDateId,
@NotNull
@Min(1)
Integer partySize
) {
}
🤖 Prompt for AI Agents
In
domain-restaurant/src/main/java/com/wellmeet/domain/restaurant/dto/IncreaseCapacityRequest.java
around lines 6 to 10, the @Min(value = 1) constraint for partySize was removed
causing zero/negative party sizes to be allowed; re-add @Min(1) on the partySize
field (preserving @NotNull), and ensure the javax.validation.constraints.Min
import is present at the top of the file so validation enforces a minimum value
of 1.

@unifolio0 unifolio0 merged commit 6d47658 into Team-soft-macaron:develop Oct 31, 2025
2 checks passed
@unifolio0 unifolio0 deleted the feat/#57 branch October 31, 2025 13:54
This was referenced Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] member 서버 분리

1 participant