Skip to content

[Feature] 가게 도메인 API 구현#5

Merged
mingdodev merged 8 commits intomainfrom
feature/4-market
Jul 5, 2025
Merged

[Feature] 가게 도메인 API 구현#5
mingdodev merged 8 commits intomainfrom
feature/4-market

Conversation

@mingdodev
Copy link
Owner

@mingdodev mingdodev commented Jul 5, 2025

Summary by CodeRabbit

  • 신규 기능

    • 가게 목록 조회 및 키워드 검색 기능이 추가되었습니다.
    • 고객 회원가입과 사장님 회원가입이 각각 별도의 엔드포인트로 분리되었습니다.
    • 사장님 회원가입 시 가게 정보 입력 및 생성이 한 번에 처리됩니다.
  • 버그 수정

    • API 문서(Swagger)에서 JWT Bearer 인증 방식이 명확히 표시되도록 개선되었습니다.
    • 회원가입 시 이메일 중복 검증 로직이 추가되었습니다.
  • 리팩터링

    • 회원가입 요청 및 응답 DTO가 고객/판매자용으로 각각 분리 및 명확화되었습니다.
  • 문서화

    • Swagger/OpenAPI 문서에 보안 요구 사항 및 엔드포인트 설명이 추가·수정되었습니다.

@mingdodev mingdodev linked an issue Jul 5, 2025 that may be closed by this pull request
3 tasks
@coderabbitai
Copy link

coderabbitai bot commented Jul 5, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

이번 변경사항에서는 Market(마켓) 도메인 API가 새롭게 도입되고, 회원가입 플로우가 고객/판매자 분리 및 판매자 가입 시 마켓 생성이 동시에 이뤄지는 구조로 리팩터링되었습니다. 또한 API 문서의 인증 방식이 Bearer(JWT)로 변경되고, 관련 시큐리티 및 Swagger 설정이 이에 맞게 수정되었습니다.

Changes

파일/경로 그룹 변경 요약
.../domain/market/controller/MarketController.java
.../dto/request/MarketSearchCondition.java
.../dto/response/MarketSummary.java
.../entity/Market.java
.../repository/MarketRepository.java
.../service/MarketService.java
Market(마켓) 도메인 전체 신규 구현: 마켓 엔티티, DTO, 조회 API, 검색조건, 서비스, 레포지토리 추가
.../domain/product/entity/Product.java Product(상품) JPA 엔티티 신규 추가
.../domain/user/controller/UserController.java
.../service/UserService.java
.../dto/request/UserCreateCustomerRequest.java
.../dto/request/UserCreateMerchantRequest.java
.../dto/response/UserCreateCustomerResponse.java
.../dto/response/UserCreateMerchantResponse.java
회원가입(customer/merchant) 분리: 고객/판매자 각각의 요청/응답 DTO, 컨트롤러, 서비스 메서드 분리 및 리팩터링
.../global/config/SecurityConfig.java 회원가입 엔드포인트를 고객/판매자 별로 분리하여 시큐리티 화이트리스트 경로 수정
.../global/config/SwaggerConfig.java Swagger 인증 스키마를 Bearer(JWT) 방식으로 변경, 전역 시큐리티 요구사항 및 스키마 정의 수정
.../domain/auth/controller/AuthController.java 로그인 API의 Swagger 시큐리티 요구사항 명시(빈 이름) 추가

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant UserController
  participant UserService
  participant MarketRepository
  participant UserRepository

  Note over Client,UserController: 고객 회원가입
  Client->>UserController: POST /signup/customer (UserCreateCustomerRequest)
  UserController->>UserService: signupCustomer(request)
  UserService->>UserRepository: save(User)
  UserService-->>UserController: UserCreateCustomerResponse
  UserController-->>Client: ApiResponse<UserCreateCustomerResponse>

  Note over Client,UserController: 판매자 회원가입 + 마켓 생성
  Client->>UserController: POST /signup/merchant (UserCreateMerchantRequest)
  UserController->>UserService: signupMerchant(request)
  UserService->>UserRepository: save(User)
  UserService->>MarketRepository: save(Market)
  UserService-->>UserController: UserCreateMerchantResponse
  UserController-->>Client: ApiResponse<UserCreateMerchantResponse>
Loading
sequenceDiagram
  participant Client
  participant MarketController
  participant MarketService
  participant MarketRepository

  Client->>MarketController: GET /api/markets?keyword=...
  MarketController->>MarketService: searchMarkets(MarketSearchCondition)
  MarketService->>MarketRepository: findByNameOrAddressOrProductsContaining(keyword)
  MarketRepository-->>MarketService: List<Market>
  MarketService-->>MarketController: List<MarketSummary>
  MarketController-->>Client: ApiResponse<List<MarketSummary>>
Loading

Possibly related issues

  • [Feature] 가게 도메인 API 구현 #4: 마켓 도메인 API 구현 및 판매자 회원가입 시 마켓 동시 생성, 고객/판매자 회원가입 분리 요구사항을 코드와 기능적으로 모두 반영합니다.

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 5

🧹 Nitpick comments (2)
src/main/java/danji/danjiapi/domain/market/repository/MarketRepository.java (1)

11-20: JPQL 쿼리 구현이 올바르지만 성능 최적화를 고려해주세요.

키워드 검색 로직이 적절하게 구현되어 있고, LEFT JOIN을 사용하여 상품이 없는 가게도 포함되도록 한 것이 좋습니다.

다만 LIKE %:keyword% 패턴을 사용할 때 성능 이슈가 발생할 수 있으니, 데이터베이스 인덱스 설정을 고려해보시기 바랍니다.

성능 최적화를 위해 다음 사항들을 고려해보세요:

  • name, address 필드에 대한 인덱스 추가
  • 키워드 검색량이 많을 경우 전문 검색 엔진(Elasticsearch 등) 도입 검토
src/main/java/danji/danjiapi/domain/product/entity/Product.java (1)

42-45: 수량 제약 조건 검증 로직을 추가하는 것을 권장합니다.

minQuantitymaxQuantity 필드가 있지만, 최소 수량이 최대 수량보다 큰 경우에 대한 검증 로직이 없습니다. 비즈니스 로직 일관성을 위해 검증을 추가하는 것을 고려해보세요.

엔티티 레벨에서 검증을 추가할 수 있습니다:

@PrePersist
@PreUpdate
private void validateQuantities() {
    if (minQuantity != null && maxQuantity != null && minQuantity > maxQuantity) {
        throw new IllegalArgumentException("최소 수량은 최대 수량보다 클 수 없습니다.");
    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ffbdaa and b19641d.

📒 Files selected for processing (16)
  • src/main/java/danji/danjiapi/domain/auth/controller/AuthController.java (2 hunks)
  • src/main/java/danji/danjiapi/domain/market/controller/MarketController.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/market/dto/request/MarketSearchCondition.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/market/dto/response/MarketSummary.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/market/entity/Market.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/market/repository/MarketRepository.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/market/service/MarketService.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/product/entity/Product.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/user/controller/UserController.java (2 hunks)
  • src/main/java/danji/danjiapi/domain/user/dto/request/UserCreateCustomerRequest.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/user/dto/request/UserCreateMerchantRequest.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/user/dto/response/UserCreateCustomerResponse.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/user/dto/response/UserCreateMerchantResponse.java (1 hunks)
  • src/main/java/danji/danjiapi/domain/user/service/UserService.java (1 hunks)
  • src/main/java/danji/danjiapi/global/config/SecurityConfig.java (1 hunks)
  • src/main/java/danji/danjiapi/global/config/SwaggerConfig.java (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/danji/danjiapi/domain/market/entity/Market.java (1)
src/main/java/danji/danjiapi/domain/product/entity/Product.java (1)
  • Entity (23-56)
src/main/java/danji/danjiapi/domain/product/entity/Product.java (1)
src/main/java/danji/danjiapi/domain/market/entity/Market.java (1)
  • Entity (25-70)
🔇 Additional comments (17)
src/main/java/danji/danjiapi/domain/user/dto/request/UserCreateCustomerRequest.java (1)

6-14: 고객 회원가입 요청 DTO 구조가 잘 설계되었습니다.

record 사용으로 불변성이 보장되고, 유효성 검증 어노테이션과 한국어 메시지가 적절히 적용되어 사용자 경험을 향상시킵니다.

src/main/java/danji/danjiapi/domain/user/dto/request/UserCreateMerchantRequest.java (1)

6-20: 판매자 회원가입 요청 DTO가 잘 설계되었습니다.

사용자 정보와 마켓 정보를 함께 관리하는 구조가 적절하며, 필수 필드에 대한 유효성 검증과 한국어 메시지가 잘 적용되어 있습니다. marketImageUrl을 선택사항으로 둔 것도 합리적입니다.

src/main/java/danji/danjiapi/domain/market/dto/request/MarketSearchCondition.java (1)

3-6: 마켓 검색 조건 DTO가 간결하고 명확합니다.

단순한 키워드 검색 구조로 시작하여 향후 검색 조건 확장이 용이한 설계입니다. 빈 검색을 허용하는 것도 합리적입니다.

src/main/java/danji/danjiapi/domain/user/dto/response/UserCreateMerchantResponse.java (1)

5-20: 판매자 회원가입 응답 DTO가 잘 설계되었습니다.

@builder 어노테이션과 정적 팩토리 메서드를 함께 제공하여 객체 생성의 유연성을 높였습니다. 사용자 정보와 생성된 마켓 ID를 함께 반환하는 구조가 적절합니다.

src/main/java/danji/danjiapi/domain/auth/controller/AuthController.java (2)

8-8: SecurityRequirement import가 적절히 추가되었습니다.

Swagger 문서화 개선을 위한 필요한 import입니다.


23-24: 로그인 엔드포인트의 보안 요구사항 설정이 적절합니다.

로그인 엔드포인트에 빈 보안 요구사항을 명시하여 인증이 필요 없음을 명확히 표현했습니다. Swagger 문서화 개선에 기여합니다.

src/main/java/danji/danjiapi/domain/market/dto/response/MarketSummary.java (1)

5-19: 깔끔한 DTO 구현입니다.

Record 클래스를 사용한 DTO 설계가 적절하고, 정적 팩토리 메서드 from을 통해 엔티티에서 DTO로의 변환이 명확하게 구현되어 있습니다.

src/main/java/danji/danjiapi/global/config/SecurityConfig.java (1)

37-38: 고객/판매자 회원가입 플로우 분리가 적절하게 반영되었습니다.

단일 회원가입 엔드포인트를 고객과 판매자로 분리하여 보안 설정을 업데이트한 것이 적절합니다. 두 엔드포인트 모두 인증 없이 접근 가능하도록 설정되어 있어 회원가입 플로우에 문제가 없을 것으로 보입니다.

src/main/java/danji/danjiapi/domain/user/dto/response/UserCreateCustomerResponse.java (1)

6-17: 고객 회원가입 응답 DTO 리팩터링이 적절합니다.

클래스명을 UserCreateCustomerResponse로 변경하고 필드를 조정한 것이 고객/판매자 분리 플로우와 일치합니다. 정적 팩토리 메서드도 적절하게 업데이트되어 있습니다.

src/main/java/danji/danjiapi/domain/market/controller/MarketController.java (1)

15-26: 가게 API 컨트롤러가 잘 구현되었습니다.

REST 컨트롤러 구조가 명확하고, @ModelAttribute를 사용한 검색 조건 바인딩이 적절합니다. Swagger 문서화도 한국어로 잘 작성되어 있어 API 이해도가 높습니다. ApiResponse 래핑 패턴도 일관성 있게 적용되어 있습니다.

src/main/java/danji/danjiapi/global/config/SwaggerConfig.java (2)

7-17: JWT Bearer 인증 방식 변경이 적절하게 구현되었습니다.

API 키 방식에서 JWT Bearer 토큰 방식으로의 변경이 올바르게 구현되었습니다. 보안 스키마 설정과 글로벌 보안 요구사항이 적절하게 구성되어 있습니다.


19-25: 보안 스키마 설정이 올바르게 구성되었습니다.

JWT Bearer 토큰을 위한 보안 스키마가 적절하게 설정되었습니다. bearerFormat = "JWT"scheme = "bearer" 설정이 정확합니다.

src/main/java/danji/danjiapi/domain/market/entity/Market.java (2)

54-55: 양방향 관계 설정이 적절하게 구성되었습니다.

@OneToMany 관계에서 cascade = CascadeType.ALLorphanRemoval = true 설정이 적절하게 구성되어 있습니다. 이는 마켓이 삭제될 때 관련된 모든 상품도 함께 삭제되는 비즈니스 로직에 맞습니다.


66-69: 양방향 관계 동기화가 올바르게 구현되었습니다.

addProduct 메서드에서 양방향 관계를 적절하게 동기화하고 있습니다. 이는 JPA에서 양방향 관계를 관리하는 모범 사례입니다.

src/main/java/danji/danjiapi/domain/user/controller/UserController.java (3)

3-6: 새로운 DTO 및 보안 어노테이션 import가 적절히 추가되었습니다.

고객/판매자 분리된 가입 플로우를 위한 전용 DTO들과 Swagger 보안 설정을 위한 SecurityRequirement import가 올바르게 추가되었습니다.

Also applies to: 10-10


24-29: 고객 가입 엔드포인트가 잘 구현되었습니다.

  • 명확한 엔드포인트 경로 (/signup/customer)
  • 적절한 Swagger 문서화 (요약 및 설명)
  • 인증되지 않은 접근을 허용하는 빈 보안 요구사항 설정
  • @Valid 어노테이션을 통한 요청 검증

31-36: 판매자 가입 엔드포인트가 잘 구현되었습니다.

  • 명확한 엔드포인트 경로 (/signup/merchant)
  • 회원가입과 가게 생성이 하나의 프로세스로 진행된다는 내용이 Swagger 설명에 명확히 기술됨
  • 인증되지 않은 접근을 허용하는 빈 보안 요구사항 설정
  • @Valid 어노테이션을 통한 요청 검증

가입 플로우의 비즈니스 로직이 문서화에 잘 반영되어 있습니다.

mingdodev added 2 commits July 6, 2025 01:16
- 검색어가 비어있는 경우에 대한 처리는 서비스 계층에서 수행되어야 함

#4
- 하나의 화면에서 전부 받으면서 관련 에러를 띄우는 게 좋을 듯

#4
@mingdodev mingdodev merged commit e3548c7 into main Jul 5, 2025
1 check passed
@mingdodev mingdodev deleted the feature/4-market branch July 5, 2025 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 가게 도메인 API 구현

1 participant