Skip to content

[FEAT] owner 서버 분리#68

Merged
unifolio0 merged 3 commits into
Team-soft-macaron:developfrom
unifolio0:feat/#60
Nov 2, 2025
Merged

[FEAT] owner 서버 분리#68
unifolio0 merged 3 commits into
Team-soft-macaron:developfrom
unifolio0:feat/#60

Conversation

@unifolio0

@unifolio0 unifolio0 commented Nov 2, 2025

Copy link
Copy Markdown
Contributor

🚩 Issue

closed #60

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

Summary by CodeRabbit

  • 신규 기능

    • 소유자 관리 서비스 추가 — 소유자 생성·조회·일괄조회·삭제 API 제공
  • 문서화

    • 마이크로서비스 마이그레이션 로드맵 및 단계별 진행상황(Phase 1–2) 상세화
    • 서비스 포트 할당 표 및 상태 배지 추가
  • Chores

    • 인프라/구성 업데이트(도커 컴포즈·서비스 구성·볼륨 등)
    • 일부 서비스의 DB 스키마 검증 모드 전환(자동갱신 → 검증)

@unifolio0 unifolio0 self-assigned this Nov 2, 2025
@unifolio0 unifolio0 added the feat label Nov 2, 2025
@coderabbitai

coderabbitai Bot commented Nov 2, 2025

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Owner 도메인 마이크로서비스 초기 분리 구현을 추가했습니다: domain-owner 모듈(컨트롤러, 애플리케이션/도메인 서비스, DTO, 예외 처리), Dockerfile 및 docker-compose 서비스, 빌드/설정 파일과 마이그레이션 계획 문서 업데이트가 포함됩니다.

Changes

Cohort / File(s) 변경 요약
문서 및 마이그레이션 계획
CLAUDE.md, claudedocs/microservices-migration-plan.md
Phase 1-2 상태 세부화, 도메인 서비스 포트 할당 테이블 추가/업데이트(restaurant → 8083, owner → 8084 등), 실행/검증 상태·이슈·다음 단계 명시
도커 구성
docker-compose.yml
owner-service 서비스 추가(포트 8084, mysql-owner 의존성, Eureka 설정, 헬스체크), mysql-owner-data 볼륨 추가
도메인 Dockerfile
domain-owner/Dockerfile
multi-stage Dockerfile 추가(빌드: gradle:8.5-jdk21, 런타임: openjdk:21-slim), 포트 8084 노출, HEALTHCHECK 및 메모리 설정
빌드 설정
domain-owner/build.gradle
spring-boot-starter-web, actuator, eureka-client 등 의존성 추가
애플리케이션 설정
domain-owner/src/main/resources/application.yml, domain-member/..., domain-restaurant/...
domain-owner: 서버 포트 8084, MySQL 데이터소스, JPA/Eureka/관리 설정 추가; member/restaurant: JPA ddl-auto를 update→validate로 변경
애플리케이션 스타터
domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java
Spring Boot main 클래스 추가(주석 처리된 상태)
도메인/서비스 계층
domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java, .../service/OwnerApplicationService.java
Owner 조회(getById, findAllByIds), 생성/삭제 및 트랜잭션 처리 로직 추가
REST 컨트롤러
domain-owner/src/main/java/com/wellmeet/domain/owner/controller/OwnerController.java
POST /api/owners, GET /api/owners/{id}, POST /api/owners/batch, DELETE /api/owners/{id} 엔드포인트 추가
DTO 및 응답/에러 모델
domain-owner/src/main/java/com/wellmeet/domain/owner/dto/*
CreateOwnerRequest, OwnerIdsRequest, OwnerResponse, ErrorResponse 레코드 추가
예외 처리
domain-owner/src/main/java/com/wellmeet/domain/owner/exception/*
OWNER_NOT_FOUND 오류 코드 추가 및 OwnerExceptionHandler 전역 예외 핸들러 추가

Sequence Diagram

sequenceDiagram
    participant Client
    participant OwnerController
    participant OwnerApplicationService
    participant OwnerDomainService
    participant OwnerRepository
    participant DB

    rect rgb(220,245,220)
        Note right of OwnerController: CreateOwner (POST /api/owners)
        Client->>OwnerController: POST CreateOwnerRequest
        OwnerController->>OwnerApplicationService: createOwner(name,email)
        OwnerApplicationService->>OwnerRepository: save(new Owner)
        OwnerRepository->>DB: INSERT
        DB-->>OwnerRepository: Owner(with id)
        OwnerRepository-->>OwnerApplicationService: Owner
        OwnerApplicationService-->>OwnerController: OwnerResponse (201)
        OwnerController-->>Client: 201 Created
    end

    rect rgb(245,245,220)
        Note right of OwnerController: GetOwner (GET /api/owners/{id})
        Client->>OwnerController: GET /api/owners/{id}
        OwnerController->>OwnerApplicationService: getOwnerById(id)
        OwnerApplicationService->>OwnerDomainService: getById(id)
        OwnerDomainService->>OwnerRepository: findById(id)
        OwnerRepository->>DB: SELECT
        DB-->>OwnerRepository: Owner | empty
        OwnerRepository-->>OwnerDomainService: Owner
        OwnerDomainService-->>OwnerApplicationService: Owner
        OwnerApplicationService-->>OwnerController: OwnerResponse (200)
        OwnerController-->>Client: 200 OK
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 분

  • 집중 검토 권장 파일:
    • domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java, OwnerDomainService.java (트랜잭션 경계·예외 흐름)
    • OwnerExceptionHandler.java (핸들링 범위 및 메시지 일관성)
    • docker-compose.ymldomain-owner/src/main/resources/application.yml (데이터베이스 포트/네트워크·Eureka 설정)
    • domain-owner/build.gradle (의존성 호환성)

Possibly related PRs

Suggested reviewers

  • ezcolin2

Poem

🐰
새 둥지에 포트 8084를 심었네,
DTO로 당근 준비, 컨트롤러로 방명록 쓰네.
Eureka 별빛 아래 서비스 하나 자라고,
헬스체크는 깡충깡충, 배포는 살랑살랑.
작은 발자국으로 큰 도메인 분리 완성 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning PR 설명은 "closed #60"과 빈 선택 사항 섹션만 포함하고 있습니다. 템플릿의 필수 구조는 기술적으로 충족되지만, 설명이 극히 불완전합니다. 구현된 내용, 변경 사항의 세부 사항, 구현 접근 방식 또는 검토 요구사항에 대한 설명이 전혀 없습니다. 이는 템플릿에 따른 최소 요건을 넘어 실질적인 정보를 제공하지 못합니다. PR 설명을 개선하기 위해 다음을 추가하십시오: 구현된 기능의 요약 (REST 엔드포인트, 서비스 레이어, 도커 설정 등), 주요 변경 사항에 대한 간단한 설명, 리뷰어가 알아야 할 중요한 사항이나 검토 포인트. 선택적 "리뷰 요구사항" 섹션을 활용하여 특정 검토 항목을 명시할 수 있습니다.
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] owner 서버 분리"는 변경 사항의 핵심을 명확하게 설명합니다. 변경 사항을 검토하면 domain-owner 마이크로서비스의 완전한 구현이 포함되어 있으며, 이는 제목의 "owner 서버 분리"라는 개념과 정확하게 일치합니다. 제목은 간결하고 구체적이며 개발자의 관점에서 주요 변경 사항을 명확하게 전달합니다.
Out of Scope Changes Check ✅ Passed 모든 변경사항은 owner 서버 분리라는 목표와 직접 관련이 있습니다. 문서 업데이트(CLAUDE.md, microservices-migration-plan.md)는 구현 상태와 포트 할당을 명확히 합니다. Docker 및 Gradle 구성은 owner 서비스 배포에 필요합니다. 모든 Java 파일은 domain-owner 패키지 내에서 owner 마이크로서비스 구현에 직접 기여합니다.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0961e9b and 020593d.

📒 Files selected for processing (3)
  • domain-member/src/main/resources/application.yml (1 hunks)
  • domain-owner/src/main/resources/application.yml (1 hunks)
  • domain-restaurant/src/main/resources/application.yml (1 hunks)

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
Copy Markdown

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은 마이크로서비스 전환 전략에 따라 owner 도메인 서버를 독립적인 서비스로 분리하는 초기 작업을 수행합니다. domain-owner 서비스의 기본적인 구조와 API 엔드포인트를 구축하고, Docker 환경 설정을 추가하며, 마이그레이션 진행 상황을 문서화하여 전체 시스템의 모듈화 및 확장성을 향상시키는 데 기여합니다.

Highlights

  • Owner 서비스 분리 초기 구현: 마이크로서비스 전환 전략의 일환으로 domain-owner 서비스의 초기 분리 작업이 진행되었습니다. 이는 owner 관련 기능을 독립적인 서비스로 운영하기 위한 첫 단계입니다.
  • 마이그레이션 문서 업데이트: 마이크로서비스 마이그레이션 계획 문서(CLAUDE.md, claudedocs/microservices-migration-plan.md)가 업데이트되어, Phase 1 및 Phase 2의 진행 상황과 domain-owner 서비스의 다음 단계(Phase 3) 구현 계획이 명시되었습니다. 또한, 도메인 서비스별 포트 할당 테이블이 추가되었습니다.
  • Docker Compose 설정 추가: docker-compose.yml 파일에 owner-service 정의가 추가되어, domain-owner 서비스가 Docker 환경에서 빌드 및 실행될 수 있도록 설정되었습니다. 여기에는 빌드 컨텍스트, 의존성, 포트 매핑, 환경 변수 및 헬스 체크 설정이 포함됩니다.
  • Owner 서비스 핵심 기능 구현: domain-owner 모듈 내에 Owner 관련 REST API 컨트롤러, 도메인 서비스, 애플리케이션 서비스, DTO 및 예외 처리 로직이 추가되었습니다. 이를 통해 Owner 생성, 조회(단건/다건), 삭제 등의 기본 CRUD 기능이 구현되었습니다.
  • Spring Boot 및 Eureka 연동 설정: domain-owner 서비스의 build.gradlespring-boot-starter-web, spring-boot-starter-actuator, spring-cloud-starter-netflix-eureka-client 의존성이 추가되었으며, application.yml을 통해 서비스 포트(8084), 데이터소스, JPA, Eureka 클라이언트 설정이 완료되었습니다.
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.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

이 PR은 owner 도메인을 마이크로서비스로 분리하는 작업을 담고 있으며, Docker 설정, REST 컨트롤러 및 관련 서비스를 추가했습니다. 전반적으로 구조는 잘 잡혀있지만, 몇 가지 중요한 이슈가 있습니다. 가장 시급한 문제는 서비스의 메인 애플리케이션 클래스가 주석 처리되어 있어 애플리케이션을 실행할 수 없다는 점입니다. 또한, 예외 처리 시 로깅을 추가하여 디버깅 용이성을 높여야 하며, 프로덕션 환경을 위한 데이터베이스 스키마 관리 전략에 대한 고려가 필요합니다. 이 외에도 계층형 아키텍처를 강화하고 코드 일관성을 높이기 위한 몇 가지 리팩토링을 제안했습니다.

Comment on lines +1 to +12
//package com.wellmeet.domain;
//
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//
//@SpringBootApplication
//public class OwnerServiceApplication {
//
// public static void main(String[] args) {
// SpringApplication.run(OwnerServiceApplication.class, args);
// }
//}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

애플리케이션의 메인 클래스가 주석 처리되어 있어 서비스가 빌드 및 실행될 수 없습니다. 이는 마이크로서비스 분리라는 PR의 핵심 목표를 달성하지 못하게 하는 심각한 문제입니다.

문서에 언급된 '빈 스캔 문제'는 @SpringBootApplication의 위치와 관련이 있을 가능성이 높습니다. 현재 com.wellmeet.domain 패키지에 위치해 있는데, 이는 다른 도메인 모듈을 의도치 않게 스캔하여 문제를 일으킬 수 있습니다.

이 클래스를 com.wellmeet.domain.owner 패키지로 이동하고 주석을 해제하여 문제를 해결하는 것을 제안합니다. 이렇게 하면 컴포넌트 스캔 범위가 owner 도메인으로 적절히 제한됩니다. 파일 위치도 domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerServiceApplication.java로 변경해야 합니다.

Suggested change
//package com.wellmeet.domain;
//
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//
//@SpringBootApplication
//public class OwnerServiceApplication {
//
// public static void main(String[] args) {
// SpringApplication.run(OwnerServiceApplication.class, args);
// }
//}
package com.wellmeet.domain.owner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OwnerServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OwnerServiceApplication.class, args);
}
}

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);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

일반적인 Exception을 처리할 때, 예외의 상세 정보를 로깅하는 것이 매우 중요합니다. 현재 구현은 클라이언트에게 일반적인 오류 메시지만 반환하고 예외 스택 트레이스나 원인에 대한 정보를 기록하지 않아, 프로덕션 환경에서 문제가 발생했을 때 원인 파악이 거의 불가능합니다. @Slf4j 어노테이션을 클래스에 추가하고 log.error()를 사용하여 예외 정보를 로깅하는 코드를 추가하는 것을 제안합니다.

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleException(Exception e) {
        log.error("Internal server 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);
    }


jpa:
hibernate:
ddl-auto: update

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

spring.jpa.hibernate.ddl-auto: update 설정은 개발 환경에서는 편리하지만, 프로덕션 환경에서는 데이터 손실이나 의도치 않은 스키마 변경을 유발할 수 있어 위험합니다. 프로덕션 프로필에서는 validatenone으로 설정하고, 데이터베이스 스키마 변경은 Flyway나 Liquibase 같은 마이그레이션 도구를 사용하여 관리하는 것을 강력히 권장합니다. 이 PR의 다른 모듈(domain-reservation)에서는 이미 Flyway를 사용하고 있으므로, 일관성을 위해 domain-owner 모듈에도 Flyway를 도입하는 것을 고려해볼 수 있습니다.

public List<Owner> findAllByIds(List<String> ownerIds) {
return ownerRepository.findAllById(ownerIds);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

도메인 서비스의 역할을 강화하고 애플리케이션 서비스의 책임을 명확히 하기 위해, Owner를 생성하고 삭제하는 로직을 OwnerDomainService로 옮기는 것을 제안합니다. 이렇게 하면 OwnerApplicationServiceOwnerRepository에 직접 의존하지 않고 도메인 서비스에만 의존하게 되어 더 계층화된 아키텍처를 유지할 수 있습니다.

Suggested change
}
public List<Owner> findAllByIds(List<String> ownerIds) {
return ownerRepository.findAllById(ownerIds);
}
@Transactional
public Owner create(String name, String email) {
Owner owner = new Owner(name, email);
return ownerRepository.save(owner);
}
@Transactional
public void delete(String ownerId) {
Owner owner = getById(ownerId);
ownerRepository.delete(owner);
}
}

Comment on lines +20 to +27
@RequestMapping("/api/owners")
public class OwnerController {

private final OwnerApplicationService ownerApplicationService;

public OwnerController(OwnerApplicationService ownerApplicationService) {
this.ownerApplicationService = ownerApplicationService;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

프로젝트의 다른 서비스 및 컨트롤러 클래스에서는 lombok.RequiredArgsConstructor를 사용하여 생성자 주입을 간결하게 처리하고 있습니다. 일관성을 유지하고 보일러플레이트 코드를 줄이기 위해 이 클래스에도 @RequiredArgsConstructor를 사용하는 것을 권장합니다. import lombok.RequiredArgsConstructor; 구문도 추가해야 합니다.

Suggested change
@RequestMapping("/api/owners")
public class OwnerController {
private final OwnerApplicationService ownerApplicationService;
public OwnerController(OwnerApplicationService ownerApplicationService) {
this.ownerApplicationService = ownerApplicationService;
}
@RequestMapping("/api/owners")
@lombok.RequiredArgsConstructor
public class OwnerController {
private final OwnerApplicationService ownerApplicationService;

Comment on lines +17 to +42
private final OwnerDomainService ownerDomainService;
private final OwnerRepository ownerRepository;

@Transactional
public OwnerResponse createOwner(String name, String email) {
Owner owner = new Owner(name, email);
Owner saved = ownerRepository.save(owner);
return OwnerResponse.from(saved);
}

public OwnerResponse getOwnerById(String ownerId) {
Owner owner = ownerDomainService.getById(ownerId);
return OwnerResponse.from(owner);
}

public List<OwnerResponse> getOwnersByIds(List<String> ownerIds) {
return ownerDomainService.findAllByIds(ownerIds).stream()
.map(OwnerResponse::from)
.toList();
}

@Transactional
public void deleteOwner(String ownerId) {
Owner owner = ownerDomainService.getById(ownerId);
ownerRepository.delete(owner);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

애플리케이션 서비스는 도메인 로직을 직접 다루기보다 도메인 서비스를 통해 작업을 위임하는 것이 좋습니다. OwnerRepository에 직접 의존하는 대신, OwnerDomainService로 생성 및 삭제 로직을 옮기고 OwnerApplicationService에서는 OwnerDomainService만 호출하도록 리팩토링하는 것을 제안합니다. 이 변경은 OwnerDomainServicecreatedelete 메소드를 추가하는 다른 제안과 함께 적용되어야 합니다.

    private final OwnerDomainService ownerDomainService;

    @Transactional
    public OwnerResponse createOwner(String name, String email) {
        Owner saved = ownerDomainService.create(name, email);
        return OwnerResponse.from(saved);
    }

    public OwnerResponse getOwnerById(String ownerId) {
        Owner owner = ownerDomainService.getById(ownerId);
        return OwnerResponse.from(owner);
    }

    public List<OwnerResponse> getOwnersByIds(List<String> ownerIds) {
        return ownerDomainService.findAllByIds(ownerIds).stream()
                .map(OwnerResponse::from)
                .toList();
    }

    @Transactional
    public void deleteOwner(String ownerId) {
        ownerDomainService.delete(ownerId);
    }

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (6)
domain-owner/src/main/resources/application.yml (2)

8-12: 데이터베이스 자격 증명 하드코딩

password: password가 하드코딩되어 있습니다. 로컬 개발용이지만, 프로덕션 배포 시 환경 변수를 사용하도록 준비하세요:

spring:
  datasource:
    url: ${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3308/wellmeet_owner}
    username: ${SPRING_DATASOURCE_USERNAME:root}
    password: ${SPRING_DATASOURCE_PASSWORD:password}

docker-compose.yml에서 이미 환경 변수를 전달하고 있으므로, 이 설정으로 변경하면 로컬/프로덕션 모두 대응 가능합니다.


44-47: Debug 로깅 레벨 확인

com.wellmeetorg.hibernate.SQL 모두 DEBUG 레벨로 설정되어 있어 로그가 매우 많이 생성될 수 있습니다. 로컬 개발에는 유용하지만, 프로덕션 환경에서는 INFO 이상으로 설정하는 것을 권장합니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java (2)

17-18: 계층 분리를 고려해보세요.

Application Service가 OwnerDomainServiceOwnerRepository를 모두 주입받고 있습니다. 일반적으로 Application Service는 Domain Service를 통해서만 데이터 접근을 하는 것이 계층 분리 원칙에 더 부합합니다. Repository 직접 접근이 필요한 경우 Domain Service에 해당 메서드를 추가하는 것을 고려해보세요.


21-25: 생성 로직에 검증을 추가하는 것을 고려해보세요.

Owner 엔티티를 직접 생성하고 있는데, name과 email에 대한 비즈니스 검증이 필요한 경우 Domain Service에서 처리하는 것이 좋습니다. 예를 들어, OwnerErrorCode.OWNER_NAME_INVALID가 정의되어 있는 것으로 보아 이름 검증 로직이 필요할 수 있습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/exception/OwnerExceptionHandler.java (2)

20-27: 모든 검증 에러를 포함하는 것을 고려해보세요.

현재는 첫 번째 필드 에러만 반환하고 있습니다. 여러 필드에서 검증이 실패한 경우 클라이언트가 모든 오류를 한 번에 확인할 수 있도록 모든 필드 에러를 포함하는 것이 사용자 경험에 더 좋습니다.

다음과 같이 모든 검증 에러를 수집할 수 있습니다:

 @ExceptionHandler(MethodArgumentNotValidException.class)
 public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException e) {
-    FieldError fieldError = e.getBindingResult().getFieldError();
-    String message = fieldError != null ? fieldError.getDefaultMessage() : "Validation failed";
+    String message = e.getBindingResult().getFieldErrors().stream()
+            .map(FieldError::getDefaultMessage)
+            .collect(Collectors.joining(", "));
+    if (message.isEmpty()) {
+        message = "Validation failed";
+    }

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

35-42: 예외 로깅을 추가해주세요.

일반 예외 처리 시 실제 오류 정보가 숨겨지고 있습니다. 디버깅과 모니터링을 위해 예외를 로그로 남기는 것이 중요합니다. 다른 핸들러들에도 적절한 로그 레벨로 예외를 기록하는 것을 권장합니다.

다음과 같이 로깅을 추가할 수 있습니다:

+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 @RestControllerAdvice
 public class OwnerExceptionHandler {
 
     @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);
     }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d47658 and 0961e9b.

📒 Files selected for processing (16)
  • CLAUDE.md (2 hunks)
  • claudedocs/microservices-migration-plan.md (3 hunks)
  • docker-compose.yml (1 hunks)
  • domain-owner/Dockerfile (1 hunks)
  • domain-owner/build.gradle (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/controller/OwnerController.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/dto/CreateOwnerRequest.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/dto/ErrorResponse.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/dto/OwnerIdsRequest.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/dto/OwnerResponse.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/exception/OwnerErrorCode.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/exception/OwnerExceptionHandler.java (1 hunks)
  • domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java (1 hunks)
  • domain-owner/src/main/resources/application.yml (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java (1)
domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java (1)
  • Service (12-27)
domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java (1)
domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java (1)
  • Service (12-43)
🪛 markdownlint-cli2 (0.18.1)
claudedocs/microservices-migration-plan.md

399-399: Bare URL used

(MD034, no-bare-urls)

⏰ 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 (15)
domain-owner/Dockerfile (1)

17-17: JVM 메모리 설정 검토 필요

-Xms256m -Xmx512m 설정은 Spring Boot 애플리케이션에 다소 제한적일 수 있습니다. 서비스 시작 시 메모리 부족으로 인한 OOM 또는 성능 저하가 발생할 수 있습니다.

초기 부하 테스트를 통해 적절한 메모리 설정을 확인하고, 필요시 최소 -Xmx768m 이상으로 조정을 고려하세요.

CLAUDE.md (1)

128-183: 문서 업데이트가 현재 구현 상태를 정확히 반영합니다

마이그레이션 계획 문서가 Phase 1-2의 완료 상태와 Phase 3의 진행 상황을 명확히 표시하고 있으며, 도메인 서비스 포트 할당 테이블이 유용합니다. 알려진 이슈도 잘 문서화되어 있습니다.

domain-owner/build.gradle (1)

10-12: 의존성 추가가 적절합니다

spring-boot-starter-web, spring-boot-starter-actuator, spring-cloud-starter-netflix-eureka-client 추가가 domain-restaurant 및 domain-member 모듈과 일관되며, 독립 마이크로서비스 구성에 필요한 의존성을 올바르게 포함하고 있습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/dto/CreateOwnerRequest.java (2)

7-15: DTO 검증 패턴이 일관성 있게 구현되었습니다

Jakarta Bean Validation 어노테이션을 사용한 입력 검증이 적절하게 구현되어 있으며, 사용자 친화적인 한글 에러 메시지도 포함되어 있습니다.


8-10: 비즈니스 요구사항과의 일치성 확인 필요

코드베이스 검증 결과:

  • Owner.java 엔티티에서 MAX_NAME_LENGTH = 10이 상수로 명시적으로 정의됨
  • 검증이 DTO 계층(@SiZe)과 엔티티 계층(validateName())에서 이중으로 적용됨
  • OwnerTest.java에서 이 제한이 의도적으로 테스트됨

그러나 이 제한의 근거가 문서화되어 있지 않습니다. 10자 제한이 실제 비즈니스 요구사항에 기반한 것인지 기술적 결정일 뿐인지 확인이 필요합니다.

실무에서 사업자 이름은:

  • 개인명: 3-5자 (예: "김철수")
  • 상호명: 9자 이상 자주 사용 (예: "맛있는 한식당" = 9자, "Seoul BBQ Restaurant" = 20자 이상)

확인 필요 사항: 요구사항 문서를 검토하여 10자 제한이 실제 비즈니스 요구사항을 반영하는지 재검토하세요. 필요시 제한값을 조정하세요.

claudedocs/microservices-migration-plan.md (3)

288-304: Phase 1-2 완료 상태가 명확히 문서화되었습니다

코드 구현 완료 상태와 실행 검증 보류 상태를 명확히 구분하여 문서화했으며, 80% 완료도 표시가 현 상황을 정확히 반영합니다.


773-784: 포트 할당 테이블이 유용합니다

각 도메인 서비스의 포트와 현재 상태를 한눈에 파악할 수 있어 인프라 관리에 도움이 됩니다. domain-restaurant-service가 당초 계획의 8081이 아닌 8083 포트를 사용한다는 주의사항도 명확합니다.


394-403: 알려진 이슈가 명확히 문서화되었습니다

Phase 1-2 공통 이슈(Application 클래스 주석 처리, 빈 스캔 문제, Docker 실행 검증 보류)가 체크리스트 형태로 잘 정리되어 있어, 다음 작업 우선순위를 쉽게 파악할 수 있습니다.

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

1-13: 잘 구현되었습니다.

에러 응답 DTO가 명확하고 간결하게 구현되어 있습니다. 정적 팩토리 메서드를 통해 timestamp를 자동으로 설정하는 방식이 적절합니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/dto/OwnerIdsRequest.java (1)

1-10: 배치 조회 요청 DTO가 적절합니다.

@NotEmpty 검증을 통해 빈 리스트 요청을 방지하고 있어 좋습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/exception/OwnerErrorCode.java (1)

8-8: 에러 코드가 명확하게 정의되었습니다.

404 상태 코드와 함께 적절한 한글 메시지가 설정되어 있습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java (1)

19-22: 단건 조회 로직이 적절합니다.

존재하지 않는 Owner에 대해 명확하게 예외를 발생시키고 있어 좋습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/dto/OwnerResponse.java (1)

5-21: 응답 DTO와 매핑 로직이 잘 구현되었습니다.

Entity를 DTO로 변환하는 정적 팩토리 메서드가 명확하고 모든 필드가 적절히 매핑되어 있습니다.

domain-owner/src/main/java/com/wellmeet/domain/owner/service/OwnerApplicationService.java (1)

27-30: 조회 및 삭제 로직이 적절합니다.

Domain Service를 통해 Owner를 조회하고 응답으로 변환하는 패턴이 잘 구현되어 있습니다. 특히 삭제 시 존재 여부를 먼저 확인하는 것이 좋습니다.

Also applies to: 32-36, 39-42

domain-owner/src/main/java/com/wellmeet/domain/owner/controller/OwnerController.java (1)

19-57: REST 컨트롤러가 잘 구현되었습니다.

  • 적절한 HTTP 메서드와 상태 코드 사용 (POST→201, GET→200, DELETE→204)
  • @Valid 어노테이션을 통한 요청 검증
  • 명시적 생성자 주입으로 테스트 용이성 확보
  • RESTful 엔드포인트 설계가 명확함

Comment thread docker-compose.yml
Comment on lines +157 to +181
# Owner Service
owner-service:
build:
context: .
dockerfile: domain-owner/Dockerfile
container_name: owner-service
depends_on:
- mysql-owner
- discovery-server
ports:
- "8084:8084"
environment:
SPRING_PROFILES_ACTIVE: local
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-owner:3306/wellmeet_owner
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: password
EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: http://discovery-server:8761/eureka/
networks:
- wellmeet-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8084/actuator/health"]
interval: 30s
timeout: 3s
start_period: 40s
retries: 3

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

owner-service 구성이 기존 서비스 패턴과 일관성 있습니다

owner-service가 restaurant-service 및 member-service와 동일한 패턴으로 설정되어 있습니다. 다만, 다음 사항을 확인해야 합니다:

  1. Healthcheck 실행 실패: curl이 컨테이너에 없어 healthcheck가 실패합니다 (Dockerfile 리뷰 참고)
  2. 서비스 시작 불가: OwnerServiceApplication.java가 주석 처리되어 있어 컨테이너가 시작되지 않습니다

Application 클래스와 Dockerfile의 healthcheck를 수정한 후 다음 명령으로 검증하세요:


🏁 Script executed:

#!/bin/bash
# owner-service 독립 실행 검증
docker-compose up -d owner-service

# 컨테이너 로그 확인
docker-compose logs -f owner-service

# Eureka 등록 확인
curl http://localhost:8761/eureka/apps/DOMAIN-OWNER-SERVICE

# Health check 확인
curl http://localhost:8084/actuator/health

Length of output: 920


🏁 Script executed:

#!/bin/bash
# Verify concerns about owner-service configuration

# 1. Check domain-owner/Dockerfile for curl availability
echo "=== Checking domain-owner/Dockerfile for curl ==="
fd -t f "Dockerfile" domain-owner/ && cat domain-owner/Dockerfile

# 2. Check OwnerServiceApplication.java
echo -e "\n=== Checking OwnerServiceApplication.java ==="
fd -t f "OwnerServiceApplication.java" && cat domain-owner/src/main/java/com/wellmeet/owner/OwnerServiceApplication.java

# 3. Check other service Dockerfiles for comparison (restaurant and member)
echo -e "\n=== Checking restaurant-service Dockerfile for curl ==="
fd -t f "Dockerfile" domain-restaurant/ | head -1 | xargs cat

echo -e "\n=== Checking member-service Dockerfile for curl ==="
fd -t f "Dockerfile" domain-member/ | head -1 | xargs cat

Length of output: 1778


🏁 Script executed:

#!/bin/bash
# Find and check OwnerServiceApplication.java content
echo "=== Finding OwnerServiceApplication.java ==="
fd -t f "OwnerServiceApplication.java" domain-owner/

echo -e "\n=== Checking content of OwnerServiceApplication.java ==="
cat domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java

echo -e "\n=== Checking if curl is available in openjdk:21-jdk-slim ==="
# Check common base images for curl availability
echo "openjdk:21-jdk-slim base image does not include curl or wget by default"
echo "This affects all services using this base image"

# List all service Dockerfiles to see the pattern
echo -e "\n=== All service Dockerfiles using healthcheck with curl ==="
fd -t f "Dockerfile" domain-*/

Length of output: 858


owner-service 설정에서 두 가지 중요한 문제 확인됨

검증 결과, 원본 리뷰의 우려사항이 모두 확인되었습니다:

  1. OwnerServiceApplication.java 완전 주석 처리: 파일의 모든 코드가 주석 처리되어 있어 서비스가 시작되지 않습니다 (domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java)

  2. Healthcheck curl 실패: openjdk:21-jdk-slim 기본 이미지에는 curl이 포함되지 않습니다. 이는 owner-service뿐 아니라 restaurant-service와 member-service도 동일한 문제를 갖고 있습니다.

필수 수정 사항:

  • OwnerServiceApplication.java 주석 해제
  • 모든 서비스의 Dockerfile에서 healthcheck 실패 문제 해결 (curl 설치 또는 대체 방법 적용)
🤖 Prompt for AI Agents
In docker-compose.yml around lines 157 to 181: the review found two bugs
affecting owner-service startup and healthchecks—(1)
domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java is
completely commented out so the Spring Boot app won't start; uncomment or
restore the original class content so the application has a valid main class and
can boot, and (2) the base image used by owner, restaurant, and member services
(openjdk:21-jdk-slim) lacks curl so the healthcheck fails; update each service
Dockerfile to install a lightweight HTTP client (e.g., apt-get update && apt-get
install -y curl or use wget or busybox-extras) or switch the healthcheck to use
a JVM-aware check (e.g., java -jar readiness probe) so the docker healthcheck
command succeeds.

Comment thread domain-owner/Dockerfile
FROM gradle:8.5-jdk21 AS build
WORKDIR /app
COPY . .
RUN gradle :domain-owner:bootJar --no-daemon

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

bootJar 빌드가 실패할 수 있습니다

OwnerServiceApplication.java가 전체 주석 처리되어 있어 bootJar 빌드가 실패합니다. Application 클래스의 주석을 해제한 후 Dockerfile을 테스트하세요.


🏁 Script executed:

#!/bin/bash
# Find OwnerServiceApplication.java file
fd -i "OwnerServiceApplication.java" -type f

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Search for the application class file with broader patterns
fd "Application\.java" -type f | grep -i owner

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Check the structure of domain-owner module
find . -path "*/domain-owner/*" -name "*.java" -type f | head -20

Length of output: 1661


🏁 Script executed:

#!/bin/bash
# View contents of OwnerServiceApplication.java
cat ./domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java

Length of output: 358


OwnerServiceApplication.java 주석 해제 필요

검증 결과, OwnerServiceApplication.java 파일이 완전히 주석 처리되어 있습니다. @SpringBootApplication 애노테이션과 main 메서드가 모두 주석 처리된 상태에서는 gradle :domain-owner:bootJar 빌드가 실패합니다. Dockerfile 빌드를 진행하기 전에 이 파일의 주석을 해제해야 합니다.

🤖 Prompt for AI Agents
In domain-owner/Dockerfile around line 5, the docker build runs "gradle
:domain-owner:bootJar" but the build fails because OwnerServiceApplication.java
is fully commented out; open
domain-owner/src/main/java/.../OwnerServiceApplication.java and remove the
comment markers to restore the @SpringBootApplication annotation and the public
static void main(String[] args) method (and any required imports), save the
file, and then re-run the docker build so gradle can produce the bootJar.

Comment thread domain-owner/Dockerfile
Comment on lines +14 to +15
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
CMD curl -f http://localhost:8084/actuator/health || exit 1

Copy link
Copy Markdown

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이 기본 설치되어 있지 않아 healthcheck가 실패합니다.

다음 중 하나를 선택하세요:

방법 1 (권장): wget 사용

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

방법 2: curl 설치 추가

 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-owner/build/libs/*.jar app.jar

방법 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:8084/actuator/health || exit 1
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

Comment on lines +24 to +26
public List<Owner> findAllByIds(List<String> ownerIds) {
return ownerRepository.findAllById(ownerIds);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

배치 조회 시 누락된 ID에 대한 처리를 검토해주세요.

findAllById는 존재하지 않는 ID를 조용히 생략합니다. 호출자가 요청한 모든 ID에 대한 결과를 기대할 수 있으므로, 누락된 ID가 있을 때의 동작을 명확히 하거나 검증 로직을 추가하는 것을 고려해보세요.

다음 스크립트로 이 메서드의 사용처를 확인하여 누락된 Owner 처리가 필요한지 검토해주세요:


🏁 Script executed:

#!/bin/bash
# Description: Check how findAllByIds is used in the codebase

# Search for usages of findAllByIds
rg -n -A 5 "findAllByIds" --type java

Length of output: 8208


추가 검증을 위해 Map 조회 후 null 처리 여부를 확인하겠습니다.

[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Check null handling in ReservationService and FavoriteService after Map.get() calls

# Check ReservationService (api-owner)
echo "=== api-owner/ReservationService around line 45 ==="
rg -n -B 5 -A 10 "membersById\.get" api-owner/src/main/java/com/wellmeet/reservation/ReservationService.java

echo -e "\n=== api-user/ReservationService around line 41 ==="
rg -n -B 5 -A 10 "restaurantsById\.get\|availableDatesById\.get" api-user/src/main/java/com/wellmeet/reservation/ReservationService.java

echo -e "\n=== FavoriteService around line 41 ==="
rg -n -B 5 -A 10 "restaurantsById\.get" api-user/src/main/java/com/wellmeet/favorite/FavoriteService.java

Length of output: 1849


업스트림 검증이 있는지 확인하겠습니다.

[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Check if there's validation before calling findAllByIds

echo "=== Check ReservationService getReservations method for validation ==="
rg -n -B 15 "memberDomainService.findAllByIds" api-owner/src/main/java/com/wellmeet/reservation/ReservationService.java | head -40

echo -e "\n=== Check FavoriteService for validation ==="
rg -n -B 15 "restaurantDomainService.findAllByIds" api-user/src/main/java/com/wellmeet/favorite/FavoriteService.java | head -40

echo -e "\n=== Check if there are any error/exception handlers ==="
rg -n "Optional\|orElse\|orElseThrow\|ifPresent" api-owner/src/main/java/com/wellmeet/reservation/ReservationService.java

Length of output: 1798


배치 조회 시 누락된 ID 처리 - 검증 완료, 개선 필요

OwnerDomainService.findAllByIds의 호출 패턴을 검증한 결과, 실제로 문제가 있습니다:

  1. OwnerApplicationService (33-35줄): findAllByIds 결과를 직접 stream().map()하며 null 체크 없음
  2. api-owner/ReservationService (40-55줄): memberDomainService.findAllByIds 후 member.getName() 등을 null 체크 없이 호출
  3. api-user/FavoriteService (36-42줄): restaurantDomainService.findAllByIds 후 restaurant.getId()를 null 체크 없이 호출

findAllById는 존재하지 않는 ID를 조용히 생략하므로, 데이터 일관성 문제(외래키 참조 대상이 삭제된 경우)가 발생하면 NullPointerException이 발생합니다.

필요한 조치:

  • findAllByIds 호출 후 반환된 크기와 요청 ID 크기 검증 또는
  • 호출자에서 null 체크 추가 또는
  • 데이터 정합성 보장 로직 추가
🤖 Prompt for AI Agents
In domain-owner/src/main/java/com/wellmeet/domain/owner/OwnerDomainService.java
around lines 24 to 26, the method returns repository.findAllById(ownerIds) which
silently omits missing IDs; update the method to validate returned list against
the requested ownerIds (e.g., compare sizes or compute missing IDs) and either
throw a clear exception listing missing IDs or return a result object that
signals which IDs were not found (or at minimum log a warning), so callers are
not exposed to unexpected nulls when they dereference entities.

Comment on lines +1 to +12
//package com.wellmeet.domain;
//
//import org.springframework.boot.SpringApplication;
//import org.springframework.boot.autoconfigure.SpringBootApplication;
//
//@SpringBootApplication
//public class OwnerServiceApplication {
//
// public static void main(String[] args) {
// SpringApplication.run(OwnerServiceApplication.class, args);
// }
//}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Application 클래스가 주석 처리되어 독립 실행 불가

전체 Application 클래스가 주석 처리되어 있어 다음 문제가 발생합니다:

  • bootJar 빌드 실패 (main 메서드 없음)
  • Docker 컨테이너 시작 불가
  • Eureka 서버 등록 불가
  • 독립 서비스로 실행 검증 불가

Phase 1-2와 동일한 빈 스캔 문제로 보이며, 다음을 시도해보세요:

-//package com.wellmeet.domain;
-//
-//import org.springframework.boot.SpringApplication;
-//import org.springframework.boot.autoconfigure.SpringBootApplication;
-//
-//@SpringBootApplication
-//public class OwnerServiceApplication {
-//
-//    public static void main(String[] args) {
-//        SpringApplication.run(OwnerServiceApplication.class, args);
-//    }
-//}
+package com.wellmeet.domain;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication(scanBasePackages = "com.wellmeet")
+public class OwnerServiceApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(OwnerServiceApplication.class, args);
+    }
+}

scanBasePackages를 명시적으로 지정하면 빈 스캔 문제가 해결될 수 있습니다.

🤖 Prompt for AI Agents
In domain-owner/src/main/java/com/wellmeet/domain/OwnerServiceApplication.java
around lines 1 to 12, the entire Application class is commented out causing no
main method (bootJar, Docker start, Eureka registration failures); restore an
executable Spring Boot application by uncommenting or re-creating the class with
the package declaration, @SpringBootApplication annotation, and public static
void main(...) that calls SpringApplication.run(...); to fix the bean-scan
issues also set @SpringBootApplication(scanBasePackages =
{"com.wellmeet.domain","com.wellmeet.shared","<other-needed-packages>"}) so
Spring explicitly scans required packages, then rebuild and verify bootJar and
runtime startup succeed.

Comment on lines +14 to +21
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show-sql: false
open-in-view: false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

ddl-auto: update 설정 검토 필요

ddl-auto: update는 로컬 개발 환경에는 편리하지만, 프로덕션 환경에서는 예상치 못한 스키마 변경이나 데이터 손실을 유발할 수 있습니다.

환경별 프로파일 설정을 권장합니다:

spring:
  config:
    activate:
      on-profile: local
  jpa:
    hibernate:
      ddl-auto: update

---
spring:
  config:
    activate:
      on-profile: prod
  jpa:
    hibernate:
      ddl-auto: validate  # 프로덕션: validate만 사용

또는 domain-reservation처럼 Flyway를 도입하여 스키마 변경을 버전 관리하는 것도 고려하세요.

🤖 Prompt for AI Agents
In domain-owner/src/main/resources/application.yml around lines 14 to 21, the
current setting uses jpa.hibernate.ddl-auto: update which is unsafe for
production; refactor configuration to move ddl-auto: update into a local/dev
profile and set the production profile to use ddl-auto: validate (or omit
ddl-auto entirely) via profile-specific YAML sections, and add instructions to
introduce Flyway (or another migration tool) for schema versioning in production
so schema changes are managed explicitly rather than auto-applied.

@unifolio0 unifolio0 merged commit 906fd04 into Team-soft-macaron:develop Nov 2, 2025
1 of 2 checks passed
@unifolio0 unifolio0 deleted the feat/#60 branch November 2, 2025 03:53
@coderabbitai coderabbitai Bot mentioned this pull request Nov 6, 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] owner 서버 분리

1 participant