Skip to content

[docs] Swagger 명세 관련 설정 및 기존 API 명세#109

Merged
buzz0331 merged 22 commits intodevelopfrom
docs/#108-swagger-config
Jul 30, 2025
Merged

[docs] Swagger 명세 관련 설정 및 기존 API 명세#109
buzz0331 merged 22 commits intodevelopfrom
docs/#108-swagger-config

Conversation

@buzz0331
Copy link
Contributor

@buzz0331 buzz0331 commented Jul 28, 2025

#️⃣ 연관된 이슈

closes #108

📝 작업 내용

Springdocs를 이용한 Swagger 명세를 하기 위해 설정하였습니다.
앞으로 API 작성하실 때 다음 3가지에 대한 설명 작성부탁드리겠습니다.

  1. 컨트롤러 핸들러 위에 @Operation을 통한 API 설명
  2. 각 파라미터 (RequestParam, PathVariable)에 대하여 @Parameter를 이용해서 설명 및 예시 추가 (Post 요청인 경우, RequestDTO에 @Schema를 이용해서 필드에 대한 설명 추가)
  3. 예외 메시지 명세를 위해 핸들러 위에 @ExceptionDescritption 설정하고, SwaggerResponseDescrpition ENUM에서 작업하고 계신 API에서 사용하고 있는 모든 ErrorCode를 그룹핑

자세한 내용은 기존 API 명세 참고해주세요!

📸 스크린샷

pull 받아서 직접 확인해보시는게 더 나을 것 같아서 따로 첨부하진 않겠습니다!

💬 리뷰 요구사항

  • 추가적으로 계속 '토큰을 찾을 수 없습니다'라는 에러메시지가 떠서 로그인과 Swagger에 대한 path는 Security Filter에서 제외시켰습니다.
  • 소셜 로그인의 경우 API를 어떻게 명세해야할지 몰라서 일단 누락된 채로 남겨두었습니다. 좀더 알아보고 추가해볼게요.

📌 PR 진행 시 이러한 점들을 참고해 주세요

* P1 : 꼭 반영해 주세요 (Request Changes) - 이슈가 발생하거나 취약점이 발견되는 케이스 등
* P2 : 반영을 적극적으로 고려해 주시면 좋을 것 같아요 (Comment)
* P3 : 이런 방법도 있을 것 같아요~ 등의 사소한 의견입니다 (Chore)

Summary by CodeRabbit

Summary by CodeRabbit

  • 신규 기능

    • OpenAPI(Swagger) 기반의 API 문서 자동화 및 예시 응답 제공 기능이 추가되었습니다.
    • Swagger UI 및 OpenAPI 문서를 위한 보안 및 예외 응답 예시가 자동으로 생성됩니다.
  • 문서화

    • 모든 주요 API 엔드포인트, 요청/응답 DTO, 파라미터에 Swagger(OpenAPI) 어노테이션이 추가되어 API 명세가 상세하게 개선되었습니다.
    • 각 컨트롤러 및 메서드에 그룹, 설명, 예외 상황 등이 명확히 문서화되었습니다.
  • 버그 수정

    • 일부 오류 코드의 HTTP 상태값이 보다 적절하게 조정되었습니다.
  • 기타

    • Swagger 관련 엔드포인트는 인증 필터를 우회하도록 개선되었습니다.
    • 기존 닉네임 중복 확인 API가 위치를 변경하였으며, 일부 메서드가 이동 또는 제거되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jul 28, 2025

"""

Walkthrough

이 변경 사항은 프로젝트 전반에 걸쳐 Swagger(OpenAPI) 명세를 강화하고, 관련 설정 및 예외 응답 예시 자동화를 위한 코드를 추가합니다. 주요 컨트롤러, 요청 DTO, 예외 코드, 시큐리티 필터, 그리고 OpenAPI 설정 클래스가 대거 수정 또는 추가되었습니다. Swagger 문서화와 관련된 주석 및 어노테이션이 대량 적용되었습니다.

Changes

Cohort / File(s) Change Summary
Swagger/OpenAPI 설정 및 예시 자동화
src/main/java/konkuk/thip/config/OpenApiConfig.java, src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java, src/main/java/konkuk/thip/common/swagger/annotation/ExceptionDescription.java, src/main/java/konkuk/thip/common/swagger/ExampleHolder.java
OpenAPI 문서화 설정, JWT 보안 스키마, 예외 응답 예시 자동 생성, 커스텀 어노테이션 및 예제 매핑 enum/클래스 추가
컨트롤러 Swagger 문서화
src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java, src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java, src/main/java/konkuk/thip/comment/adapter/in/web/CommentCommandController.java, src/main/java/konkuk/thip/feed/adapter/in/web/FeedCommandController.java, src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java, src/main/java/konkuk/thip/record/adapter/in/web/RecordCommandController.java, src/main/java/konkuk/thip/record/adapter/in/web/RecordQueryController.java, src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java, src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java, src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java, src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java, src/main/java/konkuk/thip/vote/adapter/in/web/VoteCommandController.java, src/main/java/konkuk/thip/vote/adapter/in/web/VoteQueryController.java
각 컨트롤러 및 엔드포인트에 Swagger(OpenAPI) 관련 어노테이션(@Tag, @Operation, @Parameter, @ExceptionDescription 등) 추가 및 API 문서화 메타데이터 강화, 일부 메서드 시그니처에 Swagger 파라미터 주석 추가, 불필요한 메서드(UserCommandController의 닉네임 검증 등) 이동
요청 DTO Swagger 주석화
src/main/java/konkuk/thip/book/adapter/in/web/request/PostBookIsSavedRequest.java, src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentCreateRequest.java, src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentIsLikeRequest.java, src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java, src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedIsSavedRequest.java, src/main/java/konkuk/thip/record/adapter/in/web/request/RecordCreateRequest.java, src/main/java/konkuk/thip/room/adapter/in/web/request/RoomCreateRequest.java, src/main/java/konkuk/thip/room/adapter/in/web/request/RoomJoinRequest.java, src/main/java/konkuk/thip/room/adapter/in/web/request/RoomVerifyPasswordRequest.java, src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java, src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java, src/main/java/konkuk/thip/user/adapter/in/web/request/UserVerifyNicknameRequest.java, src/main/java/konkuk/thip/vote/adapter/in/web/request/VoteCreateRequest.java
각 요청 DTO 및 필드에 @Schema 어노테이션 추가, 설명 및 예시값 명시, API 문서 자동화 강화
예외 코드 및 시큐리티 필터
src/main/java/konkuk/thip/common/exception/code/ErrorCode.java, src/main/java/konkuk/thip/common/security/filter/JwtAuthenticationFilter.java
일부 예외 코드의 HTTP 상태 변경, Swagger 관련 경로 JWT 필터 예외 처리(화이트리스트) 추가
빌드 설정
build.gradle
Swagger 지원 라이브러리(springdoc-openapi-starter-webmvc-ui:2.8.8) 의존성 추가
기타 리팩토링/정리
src/main/java/konkuk/thip/post/application/port/out/PostLikeQueryPort.java, src/main/java/konkuk/thip/record/application/service/RecordSearchService.java
불필요한 공백 제거, 내부 메서드 시그니처 파라미터 정리

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant SwaggerUI
    participant SpringBootAPI
    participant JwtAuthFilter
    participant OpenApiConfig

    Client->>SwaggerUI: GET /swagger-ui/...
    SwaggerUI->>SpringBootAPI: 요청 전송
    JwtAuthFilter->>SpringBootAPI: shouldNotFilter()로 Swagger 경로 예외 처리
    SpringBootAPI->>OpenApiConfig: OpenAPI 문서, 예외 응답 예시 제공
    SpringBootAPI-->>SwaggerUI: Swagger 문서/예시 응답 반환
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40분

Assessment against linked issues

Objective Addressed Explanation
Swagger 명세 작업 설정 및 문서화 어노테이션 적용 (#108)
Swagger 예외 응답 예시 자동화 및 커스텀 어노테이션 도입 (#108)
Swagger 관련 빌드/의존성 설정 추가 (#108)
주요 API 컨트롤러 및 DTO에 Swagger 메타데이터 적용 (#108)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected.

Suggested labels

🧹 chore

Poem

🐰
Swagger 바람이 불어와
API 문서가 반짝여요
예외 예시, 태그, 설명까지
토끼도 이해할 만큼 친절해졌죠!
문서화의 숲에서 뛰노는 오늘,
개발자와 사용자 모두가 웃어요 :)

─ 코딩 토끼 드림 🥕
"""

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 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 f8d2731 and 279ad57.

📒 Files selected for processing (2)
  • src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java (1 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java
⏰ 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
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/#108-swagger-config

🪧 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 generate unit tests to generate unit tests for 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: 6

🔭 Outside diff range comments (1)
src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java (1)

13-15: toCommand 메서드를 인스턴스 메서드로 전환하시길 권장합니다.

현재 static 메서드에 type 파라미터를 다시 받으면서 레코드 내부 컴포넌트(this.type)와 중복-혼동이 생깁니다. 호출부에서도 DTO에서 값을 꺼내지 않고 직접 Boolean 값을 넘겨야 하므로 가독성과 일관성이 떨어집니다.

-        public static UserFollowCommand toCommand(Long userId, Long targetUserId, Boolean type) {
-                return new UserFollowCommand(userId, targetUserId, type);
+        public UserFollowCommand toCommand(Long userId, Long targetUserId) {
+                return new UserFollowCommand(userId, targetUserId, this.type);
         }
🧹 Nitpick comments (5)
build.gradle (1)

74-76: Swagger 라이브러리 버전 및 BOM 관리 검토 필요

Spring Boot 3.5.0 과 springdoc 2.8.8 조합이 아직 충분히 검증되지 않았을 수 있습니다. springdoc 측의 권장 버전을 확인하거나, springdoc-openapi-starter-parent BOM을 함께 사용해 의존성 충돌을 방지하는 방안을 검토해 주세요.

+implementation platform("org.springdoc:springdoc-openapi-starter-parent:2.8.8")
 implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8'
src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java (1)

21-21: 공개 설정 설명을 더 명확하게 개선할 수 있습니다.

현재 "방 공개 설정 여부"라고 되어 있는데, 피드 생성 요청이므로 "피드 공개 설정 여부"가 더 적절할 것 같습니다.

-        @Schema(description = "방 공개 설정 여부 (true: 공개, false: 비공개)", example = "true")
+        @Schema(description = "피드 공개 설정 여부 (true: 공개, false: 비공개)", example = "true")
src/main/java/konkuk/thip/room/adapter/in/web/request/RoomJoinRequest.java (1)

9-11: type 값을 Enum으로 제한하거나 패턴 검증을 추가해주세요.

join / cancel 두 값만 허용될 것으로 보입니다.
문자열로 열어두면 오타·대소문자 오류가 런타임까지 넘어갑니다. enum RoomJoinType { JOIN, CANCEL } 을 도입하거나

@Pattern(regexp = "join|cancel", flags = Pattern.Flag.CASE_INSENSITIVE)

같은 검증을 추가하면 API 신뢰도가 올라갑니다.

src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentCreateRequest.java (1)

19-24: 비즈니스 규칙 검증이 부족합니다.

isReplyRequest == true 이면서 parentId == null 인 경우, 혹은 반대로 reply 아님인데 parentId 가 채워진 경우를 방지할 로직/Validator 가 없습니다.
DTO 단계에서 @AssertTrue 커스텀 메서드 또는 커스텀 Validator 로 교차 검증을 추가해 주세요.

src/main/java/konkuk/thip/config/OpenApiConfig.java (1)

134-134: API 응답 설명이 비어있습니다

apiResponse.setDescription("");에서 빈 문자열 대신 의미 있는 설명을 추가하는 것이 좋겠습니다.

-                    apiResponse.setDescription("");
+                    apiResponse.setDescription("Error response");

또는 HTTP 상태 코드에 따른 설명을 추가할 수 있습니다:

-                    apiResponse.setDescription("");
+                    apiResponse.setDescription(getStatusDescription(status));
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6c70012 and 61d1895.

📒 Files selected for processing (35)
  • build.gradle (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java (1 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (2 hunks)
  • src/main/java/konkuk/thip/book/adapter/in/web/request/PostBookIsSavedRequest.java (1 hunks)
  • src/main/java/konkuk/thip/comment/adapter/in/web/CommentCommandController.java (3 hunks)
  • src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentCreateRequest.java (1 hunks)
  • src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentIsLikeRequest.java (1 hunks)
  • src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1 hunks)
  • src/main/java/konkuk/thip/common/security/filter/JwtAuthenticationFilter.java (1 hunks)
  • src/main/java/konkuk/thip/common/swagger/ExampleHolder.java (1 hunks)
  • src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java (1 hunks)
  • src/main/java/konkuk/thip/common/swagger/annotation/ExceptionDescription.java (1 hunks)
  • src/main/java/konkuk/thip/config/OpenApiConfig.java (1 hunks)
  • src/main/java/konkuk/thip/feed/adapter/in/web/FeedCommandController.java (3 hunks)
  • src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (2 hunks)
  • src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java (1 hunks)
  • src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedIsSavedRequest.java (1 hunks)
  • src/main/java/konkuk/thip/post/application/port/out/PostLikeQueryPort.java (0 hunks)
  • src/main/java/konkuk/thip/record/adapter/in/web/RecordCommandController.java (1 hunks)
  • src/main/java/konkuk/thip/record/adapter/in/web/RecordQueryController.java (2 hunks)
  • src/main/java/konkuk/thip/record/adapter/in/web/request/RecordCreateRequest.java (1 hunks)
  • src/main/java/konkuk/thip/record/application/service/RecordSearchService.java (2 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java (4 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (3 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/request/RoomCreateRequest.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/request/RoomJoinRequest.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/request/RoomVerifyPasswordRequest.java (1 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java (2 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (1 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/request/UserFollowRequest.java (1 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java (1 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/request/UserVerifyNicknameRequest.java (1 hunks)
  • src/main/java/konkuk/thip/vote/adapter/in/web/VoteCommandController.java (2 hunks)
  • src/main/java/konkuk/thip/vote/adapter/in/web/VoteQueryController.java (1 hunks)
  • src/main/java/konkuk/thip/vote/adapter/in/web/request/VoteCreateRequest.java (2 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/konkuk/thip/post/application/port/out/PostLikeQueryPort.java
🧰 Additional context used
🧠 Learnings (8)
src/main/java/konkuk/thip/vote/adapter/in/web/VoteQueryController.java (2)

Learnt from: buzz0331
PR: #75
File: src/main/java/konkuk/thip/vote/adapter/out/persistence/VoteQueryRepositoryImpl.java:50-83
Timestamp: 2025-07-14T14:19:38.796Z
Learning: Vote와 VoteItem 엔티티는 자주 함께 사용되므로, N+1 문제를 방지하기 위해 양방향 매핑과 fetch join을 고려하는 것이 좋습니다. 특히 기록장 조회 API 등에서도 함께 사용될 가능성이 높습니다.

Learnt from: buzz0331
PR: #78
File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3
Timestamp: 2025-07-14T18:22:56.538Z
Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

src/main/java/konkuk/thip/vote/adapter/in/web/request/VoteCreateRequest.java (1)

Learnt from: buzz0331
PR: #75
File: src/main/java/konkuk/thip/vote/adapter/out/persistence/VoteQueryRepositoryImpl.java:50-83
Timestamp: 2025-07-14T14:19:38.796Z
Learning: Vote와 VoteItem 엔티티는 자주 함께 사용되므로, N+1 문제를 방지하기 위해 양방향 매핑과 fetch join을 고려하는 것이 좋습니다. 특히 기록장 조회 API 등에서도 함께 사용될 가능성이 높습니다.

src/main/java/konkuk/thip/comment/adapter/in/web/CommentCommandController.java (1)

Learnt from: hd0rable
PR: #101
File: src/test/java/konkuk/thip/comment/adapter/in/web/CommentControllerTest.java:118-265
Timestamp: 2025-07-23T17:41:55.507Z
Learning: CommentControllerTest는 댓글 생성 API의 검증 로직과 예외 상황만을 테스트하는 단위 테스트이며, 성공 케이스는 별도의 통합 테스트(CommentCreateAPITest)에서 다룬다.

src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (2)

Learnt from: buzz0331
PR: #78
File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3
Timestamp: 2025-07-14T18:22:56.538Z
Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

Learnt from: seongjunnoh
PR: #43
File: src/main/java/konkuk/thip/book/application/port/out/BookCommandPort.java:0-0
Timestamp: 2025-07-03T03:05:05.031Z
Learning: THIP 프로젝트에서는 CQRS Port 분리 시 다음 컨벤션을 따름: CommandPort에는 findByXXX를 통해 도메인 엔티티를 찾아오는 메서드를 추가하고, QueryPort에는 조회 API의 response에 해당하는 데이터들을 DB로부터 조회하는 메서드를 추가함.

src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (2)

Learnt from: buzz0331
PR: #78
File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3
Timestamp: 2025-07-14T18:22:56.538Z
Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

Learnt from: seongjunnoh
PR: #101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서는 "사용자가 방에 속하는지 검증" 로직을 RoomParticipantPolicy 도메인 서비스로 캡슐화하여 재사용성을 높이고 비즈니스 로직의 중복을 방지하는 방식을 선호한다.

src/main/java/konkuk/thip/record/adapter/in/web/RecordQueryController.java (1)

Learnt from: seongjunnoh
PR: #101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서 Record와 Vote는 Room에 속하지만 Feed는 Room에 속하지 않는 구조이며, 댓글 작성 시 Record/Vote에 대해서만 사용자가 해당 Room의 참가자인지 검증이 필요하다.

src/main/java/konkuk/thip/record/adapter/in/web/RecordCommandController.java (1)

Learnt from: seongjunnoh
PR: #101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서 Record와 Vote는 Room에 속하지만 Feed는 Room에 속하지 않는 구조이며, 댓글 작성 시 Record/Vote에 대해서만 사용자가 해당 Room의 참가자인지 검증이 필요하다.

src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java (1)

Learnt from: seongjunnoh
PR: #101
File: src/main/java/konkuk/thip/comment/application/service/CommentCreateService.java:36-39
Timestamp: 2025-07-26T06:09:00.850Z
Learning: THIP 프로젝트에서는 "사용자가 방에 속하는지 검증" 로직을 RoomParticipantPolicy 도메인 서비스로 캡슐화하여 재사용성을 높이고 비즈니스 로직의 중복을 방지하는 방식을 선호한다.

🧬 Code Graph Analysis (4)
src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java (1)
src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (1)
  • Tag (24-73)
src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (1)
src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java (1)
  • Tag (24-84)
src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java (2)
src/main/java/konkuk/thip/feed/adapter/in/web/FeedCommandController.java (1)
  • Tag (26-76)
src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java (1)
  • Tag (24-84)
src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java (1)
src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (1)
  • Tag (25-83)
⏰ 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
🔇 Additional comments (62)
src/main/java/konkuk/thip/common/swagger/annotation/ExceptionDescription.java (1)

10-15: 어노테이션 메타정보 보강 및 다중 지정 지원 제안

  1. API 문서에서도 노출되도록 @Documented 추가
  2. 하나의 엔드포인트가 여러 오류 그룹을 가질 수 있으므로 배열 형태로 변경 + @Repeatable 지원 검토
+import java.lang.annotation.Documented;
+import java.lang.annotation.Repeatable;

-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Repeatable(ExceptionDescriptions.class)   // 별도 컨테이너 어노테이션 필요
 public @interface ExceptionDescription {
-    SwaggerResponseDescription value();
+    SwaggerResponseDescription[] value();
 }

컨테이너 어노테이션 ExceptionDescriptions 도 함께 정의해 주셔야 합니다.
[ suggest_essential_refactor ]

src/main/java/konkuk/thip/common/swagger/ExampleHolder.java (1)

7-14: 불필요한 중간 객체·네이밍 혼란

  • 필드명이 holder 인데 타입이 Example 으로, 클래스명이 ExampleHolder 와 중복되어 가독성이 떨어집니다.
  • 순수 DTO 용도라면 @Value(불변 객체) + 명확한 필드명(example)이 더 직관적입니다.
-@Getter
-@Builder
-public class ExampleHolder {
-
-    private Example holder;
-    private String name;
-    private int code;
+@Value
+@Builder
+public class ExampleHolder {
+    Example example;
+    String name;
+    int code;
 }

[ suggest_optional_refactor ]

src/main/java/konkuk/thip/vote/adapter/in/web/VoteQueryController.java (1)

3-8: Swagger 태그 추가는 👍, 그러나 빈 컨트롤러 여부 확인 필요

현재 클래스에 실제 엔드포인트가 정의돼 있지 않아 Swagger UI 에는 태그만 노출되고 API 목록이 비어 있을 가능성이 있습니다. 의도한 placeholder 가 아니라면 구현 누락 여부를 한번 더 확인해 주세요.

src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedCreateRequest.java (2)

10-10: 스키마 설명이 명확하고 적절합니다.

피드 생성 요청 DTO에 대한 설명이 명확하며, 이후 필드별 상세 설명과 잘 매칭됩니다.


25-25: 태그 예시가 도메인에 적합합니다.

한국어 도서 태그 예시들이 실제 사용 시나리오를 잘 반영하고 있어 API 사용자에게 도움이 될 것입니다.

src/main/java/konkuk/thip/common/security/filter/JwtAuthenticationFilter.java (1)

79-89: Swagger 엔드포인트 화이트리스트 검토 완료

  • JwtAuthenticationFiltershouldNotFilter에서 Swagger UI(/swagger-ui*, /swagger-ui.html), API 문서(/v3/api-docs*, /api-docs*), OAuth2 콜백(/oauth2/authorization*, /login/oauth2/code*) 경로가 올바르게 제외되고 있습니다.
  • SecurityConfig에도 동일한 경로들이 WHITELIST로 선언되어 있어 JWT 필터와 보안 설정 간 충돌은 없습니다.
  • application.ymlapplication-prod.yml에서는 Swagger 관련 설정이 별도로 정의되어 있지 않습니다.

프로덕션 환경에서는 Swagger UI와 API 문서 접근을 비활성화하거나 별도의 인증(예: Basic Auth, IP 화이트리스트 등)을 적용하는 것을 권장드립니다.

src/main/java/konkuk/thip/room/adapter/in/web/request/RoomCreateRequest.java (4)

11-11: 전체적인 스키마 구조가 잘 정의되었습니다.

방 생성 요청 DTO에 대한 명확한 설명과 함께 모든 필드가 체계적으로 문서화되어 있습니다.


29-34: 날짜 형식 예시와 검증 패턴이 일치합니다.

날짜 필드의 예시값이 검증 패턴(yyyy.MM.dd)과 정확히 일치하며, 사용자가 이해하기 쉽게 작성되었습니다.

Also applies to: 36-41


43-46: 모집 인원 제한이 합리적입니다.

1명에서 30명까지의 모집 인원 제한이 실제 독서 모임 운영에 적합한 범위로 설정되어 있습니다.


48-51: 비밀번호 필드 처리가 적절합니다.

@Nullable 어노테이션과 4자리 숫자 패턴 검증이 올바르게 적용되어 있으며, 선택적 비밀번호 설정을 잘 지원합니다.

src/main/java/konkuk/thip/user/adapter/in/web/request/UserVerifyNicknameRequest.java (2)

7-7: DTO 설명이 명확하고 목적에 부합합니다.

사용자 닉네임 중복 확인 요청 DTO라는 설명이 해당 기능의 목적을 명확히 표현하고 있습니다.


9-12: 닉네임 예시와 검증 규칙이 일치합니다.

"홍길동_123" 예시값이 한글, 영어, 숫자 조합 규칙과 10자 제한에 부합하며, 실제 사용 패턴을 잘 반영하고 있습니다.

src/main/java/konkuk/thip/vote/adapter/in/web/request/VoteCreateRequest.java (4)

12-12: 투표 생성 DTO 설명이 명확합니다.

투표 생성 요청의 목적이 잘 표현되어 있으며, 이후 필드 설명들과 일관성을 유지하고 있습니다.


14-16: 페이지 번호 필드가 도메인 로직에 적합합니다.

책의 특정 페이지에 대한 투표 생성이라는 도메인 요구사항을 잘 반영한 필드 설계입니다.


27-31: 투표 항목 리스트 제약이 실용적입니다.

1개 이상 5개 이하의 투표 항목 제한이 실제 투표 UI/UX 관점에서 합리적이며, 예시 JSON 형태도 이해하기 쉽습니다.


33-40: 중첩된 DTO 구조가 잘 문서화되었습니다.

VoteItemCreateRequest 레코드에도 적절한 @Schema 어노테이션이 적용되어 전체 API 문서의 일관성을 유지하고 있습니다.

참고로, 이전 학습 내용에 따르면 Vote와 VoteItem 엔티티는 자주 함께 사용되므로 조회 API에서 N+1 문제 방지를 위한 fetch join 고려가 필요할 수 있습니다.

src/main/java/konkuk/thip/room/adapter/in/web/request/RoomVerifyPasswordRequest.java (1)

7-13: Swagger 메타데이터 적용 👍

DTO 자체 및 필드에 상세한 @Schema 설명이 잘 추가되었습니다. Validation 애노테이션과 예시도 명확하여 별다른 이슈가 없습니다.

src/main/java/konkuk/thip/feed/adapter/in/web/request/FeedIsSavedRequest.java (1)

3-3: Swagger 스키마 어노테이션이 적절하게 추가되었습니다.

요청 DTO에 대한 명확한 설명과 필드 예시값이 포함된 @Schema 어노테이션이 올바르게 적용되었습니다. API 문서화에 도움이 될 것입니다.

Also applies to: 7-7, 9-9

src/main/java/konkuk/thip/comment/adapter/in/web/request/CommentIsLikeRequest.java (1)

3-3: Swagger 스키마 어노테이션이 일관성 있게 추가되었습니다.

댓글 좋아요 상태 변경에 대한 명확한 설명과 boolean 타입 필드의 의미가 잘 문서화되었습니다.

Also applies to: 7-7, 9-9

src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java (1)

3-3: 사용자 회원가입 DTO의 Swagger 문서화가 완료되었습니다.

각 필드에 대한 명확한 설명과 한국어 예시값이 적절하게 제공되어 API 문서의 가독성을 높였습니다.

Also applies to: 9-9, 11-11, 15-15

src/main/java/konkuk/thip/book/adapter/in/web/BookQueryController.java (1)

3-6: 포괄적인 Swagger API 문서화가 훌륭하게 구현되었습니다.

컨트롤러의 모든 엔드포인트에 대해 명확한 설명, 적절한 파라미터 문서화, 그리고 내부 파라미터 숨김 처리가 잘 적용되었습니다. 특히 userId 파라미터를 hidden으로 처리한 점과 각 파라미터에 실용적인 예시값을 제공한 점이 좋습니다.

Also applies to: 22-24, 33-42, 47-57, 62-70

src/main/java/konkuk/thip/record/application/service/RecordSearchService.java (1)

81-81: getGroupRecordBySortParams 메서드 시그니처 정리 적절

  • 해당 메서드는 RecordSearchService.java 내부에서만 호출됨
  • 구현부에서 사용되지 않던 isPageFilter 파라미터가 제거되어 호출부와 선언부가 일치함
  • 다른 호출부가 없으므로 인터페이스 변경에 따른 영향 범위가 없음

위 변경은 불필요한 파라미터 제거를 통한 올바른 리팩토링이므로 승인합니다.

src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (6)

3-11: Swagger 어노테이션 import가 잘 정리되어 있습니다.

새로 추가된 Swagger 관련 import들이 적절하게 구성되어 있고, @Valid 어노테이션도 새로운 POST 엔드포인트를 위해 정상적으로 추가되었습니다.


25-25: API 태그 설정이 명확합니다.

@Tag 어노테이션의 name과 description이 명확하게 사용자 조회 API의 목적을 나타내고 있습니다.


34-43: 닉네임 중복 확인 엔드포인트가 적절히 구현되었습니다.

새로 추가된 POST /users/nickname 엔드포인트는 다음과 같이 잘 구현되었습니다:

  • @Operation 어노테이션으로 명확한 API 설명 제공
  • @Valid 어노테이션으로 요청 validation 처리
  • 적절한 응답 래핑 구조 사용

45-54: 기존 엔드포인트에 Swagger 문서화가 잘 적용되었습니다.

별칭 선택 화면 조회 API에 @Operation 어노테이션이 추가되어 API 문서의 가독성이 향상되었습니다.


56-68: 팔로워 조회 API의 파라미터 문서화가 상세합니다.

각 파라미터에 대한 @Parameter 어노테이션이 잘 작성되어 있고, @ExceptionDescription으로 예외 케이스도 문서화되어 있습니다. 특히 size 파라미터의 범위 제한(1~10)이 명확하게 표시되어 있습니다.


70-82: 내 팔로잉 조회 API 문서화가 완성도 높습니다.

@Parameter(hidden = true)를 통해 userId 파라미터를 Swagger 문서에서 숨기는 처리가 적절하며, 나머지 파라미터들의 설명도 명확합니다.

src/main/java/konkuk/thip/record/adapter/in/web/RecordQueryController.java (4)

3-8: Swagger 관련 import가 적절히 추가되었습니다.

필요한 Swagger 어노테이션들과 예외 처리를 위한 import가 정확하게 구성되어 있습니다.


20-20: API 그룹 태그가 명확합니다.

Record Query API 태그가 기록 조회 관련 기능을 잘 나타내고 있습니다.


27-31: API 작업 설명이 상세하고 명확합니다.

@Operation 어노테이션의 summary와 description이 방의 게시글 목록 조회 기능을 명확하게 설명하고 있으며, type 파라미터에 따른 동작 차이도 잘 언급되어 있습니다.


34-49: 파라미터 문서화가 매우 상세합니다.

각 파라미터에 대한 @Parameter 어노테이션이 다음과 같이 잘 작성되었습니다:

  • 명확한 설명과 예시 값 제공
  • 복잡한 sort 파라미터에 대한 상세한 설명
  • @Parameter(hidden = true)로 userId 숨김 처리

특히 sort 파라미터의 설명에서 그룹 기록과 내 기록에서의 동작 차이를 명시한 것이 좋습니다.

src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1)

54-57: Naver API 관련 에러의 HTTP 상태 코드 변경이 적절합니다.

다음 에러들을 BAD_REQUEST에서 INTERNAL_SERVER_ERROR로 변경한 것이 의미적으로 올바릅니다:

  • BOOK_NAVER_API_REQUEST_ERROR
  • BOOK_NAVER_API_URL_ERROR
  • BOOK_NAVER_API_URL_HTTP_CONNECT_FAILED

이들은 모두 외부 API 연동 문제로 서버 내부 오류에 해당하므로 500번대 상태 코드가 적합합니다.

src/main/java/konkuk/thip/vote/adapter/in/web/VoteCommandController.java (3)

3-5: Swagger 어노테이션 import가 적절합니다.

필요한 Swagger 어노테이션들이 정확하게 import되어 있습니다.


18-18: API 태그가 명확하게 설정되었습니다.

"Vote Command API" 태그와 "투표 상태변경 관련 API" 설명이 컨트롤러의 역할을 잘 나타냅니다.


25-32: 투표 생성 API 문서화가 잘 되어 있습니다.

  • @Operation 어노테이션의 summary와 description이 명확함
  • @Parameter(hidden = true)로 userId 파라미터를 적절히 숨김 처리
  • roomId 파라미터에 대한 설명과 예시가 적절함
src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java (3)

6-9: LinkedHashSet 사용이 적절합니다.

에러 코드의 순서를 보장하기 위해 LinkedHashSet을 사용한 것이 좋은 선택입니다. static import로 ErrorCode를 깔끔하게 처리한 것도 가독성에 도움이 됩니다.


12-220: 포괄적인 에러 코드 매핑이 잘 구성되었습니다.

각 API 작업별로 관련된 에러 코드들이 체계적으로 정리되어 있습니다:

  • 도메인별 그룹화가 명확함 (Auth, User, Room, Record, Vote, Feed, Comment, Book)
  • 각 작업의 특성에 맞는 에러 코드들이 적절히 매핑됨
  • 생성자에서 공통 API 에러를 자동으로 추가하는 설계가 우수함

196-219: 공통 에러 처리 로직이 효율적입니다.

생성자에서 모든 enum 값에 공통 API 에러들을 자동 추가하는 방식이 중복을 방지하고 유지보수성을 높입니다. 주석 처리된 인증 관련 에러들은 현재 요구사항에 맞게 제외된 것으로 보입니다.

src/main/java/konkuk/thip/book/adapter/in/web/BookCommandController.java (1)

3-6: Swagger 어노테이션이 올바르게 적용되었습니다!

PR 목표에 따라 다음 항목들이 적절히 구현되었습니다:

  • @Tag로 컨트롤러 그룹화
  • @Operation으로 API 설명 추가
  • @Parameter로 각 파라미터 설명 및 예시 제공
  • @ExceptionDescription으로 예외 응답 문서화
  • userId 파라미터를 hidden = true로 설정하여 API 문서에서 숨김

Also applies to: 13-13, 21-21, 23-23, 31-42

src/main/java/konkuk/thip/record/adapter/in/web/RecordCommandController.java (1)

3-5: Swagger 어노테이션이 일관성 있게 적용되었습니다!

다른 컨트롤러와 동일한 패턴으로 구현되어 있어 API 문서의 일관성이 유지됩니다:

  • 기록 생성 API에 대한 명확한 설명
  • 방 ID 파라미터에 적절한 예시 값 제공
  • 예외 응답 문서화 완료

Also applies to: 9-9, 19-19, 21-21, 27-36

src/main/java/konkuk/thip/config/OpenApiConfig.java (1)

1-139: OpenAPI 설정이 포괄적으로 구현되었습니다!

Swagger 문서화를 위한 핵심 설정들이 잘 구현되어 있습니다:

  • JWT 인증 스키마 설정
  • 다중 서버 URL 지원 (HTTPS, HTTP, localhost)
  • @ExceptionDescription 어노테이션 처리를 위한 커스터마이저
  • 동적 에러 응답 예시 생성
src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (1)

3-5: Swagger 문서화가 완벽하게 구현되었습니다!

모든 API 엔드포인트에 대해 다음 사항들이 일관되게 적용되었습니다:

  • 각 메서드별 명확한 요약과 설명
  • 모든 파라미터에 대한 상세한 문서화
  • 예외 응답 문서화 완료
  • 일관된 예시 값 제공

특히 다양한 조회 API들에 대한 문서화가 체계적으로 잘 정리되어 있습니다.

Also applies to: 8-8, 27-27, 29-29, 41-119

src/main/java/konkuk/thip/feed/adapter/in/web/FeedCommandController.java (5)

3-9: Swagger 어노테이션 import가 적절하게 추가됨

필요한 Swagger 어노테이션들과 ExceptionDescription이 올바르게 import되었습니다.

Also applies to: 24-24


26-26: API 그룹화를 위한 @tag 어노테이션 적절함

"Feed Command API"라는 명확한 이름으로 컨트롤러를 그룹화하고 한국어 설명을 제공하여 문서의 가독성을 높였습니다.


35-46: 피드 작성 API 문서화가 잘 구성됨

@operation 어노테이션으로 API의 목적을 명확히 하고, @parameter 어노테이션으로 각 파라미터에 대한 설명을 제공했습니다. 특히 userIdhidden = true로 설정하여 API 문서에서 숨기는 것이 적절합니다.


48-61: 피드 수정 API의 설명이 명확함

"책 빼고 변경가능"이라는 구체적인 제약사항을 summary에 포함하여 API 사용자가 기능을 정확히 이해할 수 있도록 했습니다.


63-75: 피드 저장 상태 변경 API의 문서화가 상세함

description에서 "저장: true, 저장해제(삭제): false"라고 명시하여 boolean 값의 의미를 명확히 했습니다. 이는 API 사용자의 혼동을 방지할 수 있습니다.

src/main/java/konkuk/thip/comment/adapter/in/web/CommentCommandController.java (4)

3-15: Swagger 관련 import와 static import가 적절함

필요한 Swagger 어노테이션과 ExceptionDescription 상수들이 올바르게 import되었습니다.

Also applies to: 22-23


25-25: Comment API 그룹화가 명확함

"Comment Command API"로 명확하게 그룹화하고 한국어 설명을 추가했습니다.


38-51: 댓글/답글 구분 로직이 상세히 문서화됨

기존 주석의 복잡한 로직(parentId와 isReplyRequest의 조합)을 @operation의 description에서 명확하게 설명했습니다. 이는 API 사용자가 댓글과 답글 작성의 차이를 쉽게 이해할 수 있도록 합니다.


53-64: 좋아요 상태 변경 로직 설명이 명확함

boolean 값의 의미를 "(true -> 좋아요, false -> 좋아요 취소)"로 명시하여 API 사용자의 혼동을 방지했습니다.

src/main/java/konkuk/thip/room/adapter/in/web/RoomCommandController.java (5)

3-9: Swagger 어노테이션 import가 올바름

필요한 모든 Swagger 관련 import가 적절하게 추가되었습니다.

Also applies to: 22-22


24-24: Room API 그룹화가 적절함

"Room Command API"로 명확하게 그룹화하고 "방 상태변경 관련 API"라는 한국어 설명을 제공했습니다.


36-49: 방 생성 API 문서화가 적절함

@operation으로 방 생성의 목적을 명확히 하고, 멀티라인 메소드 시그니처로 가독성을 향상시켰습니다. @parameter(hidden = true)로 userId를 숨기는 것도 적절합니다.


54-67: 방 참여 상태 변경 로직이 명확히 문서화됨

"join -> 방 참여, cancel -> 방 참여 취소"라는 명시적인 설명으로 API 동작을 이해하기 쉽게 했습니다. PathVariable에 대한 설명과 예시값도 적절합니다.


72-83: 방 모집 마감 API 문서화가 상세함

"방장이 방의 모집을 마감합니다"라는 설명으로 권한과 동작을 명확히 했습니다. 예시값을 포함한 PathVariable 설명도 적절합니다.

src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java (5)

3-12: Swagger 관련 import가 적절하게 추가됨

필요한 Swagger 어노테이션들이 올바르게 import되었고, ExceptionDescription 상수들도 적절하게 static import되었습니다.

Also applies to: 27-28


30-30: User Command API 그룹화가 명확함

"User Command API"와 "사용자가 주체가 되는 정보 수정"이라는 설명으로 Command API의 역할을 명확히 했습니다.


39-52: 회원가입 API 문서화가 적절함

OAuth2 ID를 통한 사용자 식별 방식을 description에서 명확히 설명했습니다. @parameter(hidden = true)로 oauth2Id를 숨기는 것도 적절합니다.


54-67: 팔로우 상태 변경 API 문서화가 명확함

boolean 값의 의미를 "true 이면 팔로우, false 이면 언팔로우"로 명시하여 API 사용자의 혼동을 방지했습니다. PathVariable에 대한 설명도 적절합니다.


1-68: 닉네임 검증 기능의 Command/Query 분리가 적절함

닉네임 검증 기능이 UserQueryController로 이동한 것은 CQRS 패턴에 따른 적절한 분리입니다. 조회성 작업은 Query Controller에서 처리하는 것이 아키텍처 관점에서 올바릅니다.

Comment on lines +172 to +174
// DUPLICATED_BOOKS_IN_COLLECTION,
// BOOK_NOT_SAVED_DB_CANNOT_DELETE
))),
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

주석 처리된 에러 코드에 대한 정리가 필요합니다.

DUPLICATED_BOOKS_IN_COLLECTIONBOOK_NOT_SAVED_DB_CANNOT_DELETE 에러 코드가 주석 처리되어 있습니다. 이들이 더 이상 사용되지 않는다면 완전히 제거하는 것을 고려해보세요.

다음 스크립트로 해당 에러 코드들의 사용 여부를 확인할 수 있습니다:


🏁 Script executed:

#!/bin/bash
# 주석 처리된 에러 코드의 실제 사용 여부 확인

echo "=== DUPLICATED_BOOKS_IN_COLLECTION 사용처 확인 ==="
rg "DUPLICATED_BOOKS_IN_COLLECTION"

echo "=== BOOK_NOT_SAVED_DB_CANNOT_DELETE 사용처 확인 ==="
rg "BOOK_NOT_SAVED_DB_CANNOT_DELETE"

Length of output: 1469


SwaggerResponseDescription에 누락된 에러 코드 복원 필요

DUPLICATED_BOOKS_IN_COLLECTIONBOOK_NOT_SAVED_DB_CANNOT_DELETE는 여전히 코드 전반에서 참조 중이므로, Swagger 응답 설명에서 주석을 해제하여 복원해야 합니다.

  • 대상 파일 및 위치

    • src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java (약 172–174행)
  • 제안하는 수정(diff 예시)

@@ -171,7 +171,7 @@
     )),
     @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = ErrorResponse.class),
-            //            DUPLICATED_BOOKS_IN_COLLECTION,
-            //            BOOK_NOT_SAVED_DB_CANNOT_DELETE
+            DUPLICATED_BOOKS_IN_COLLECTION,
+            BOOK_NOT_SAVED_DB_CANNOT_DELETE
     ))),
📝 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
// DUPLICATED_BOOKS_IN_COLLECTION,
// BOOK_NOT_SAVED_DB_CANNOT_DELETE
))),
)),
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = ErrorResponse.class),
DUPLICATED_BOOKS_IN_COLLECTION,
BOOK_NOT_SAVED_DB_CANNOT_DELETE
))),
🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/common/swagger/SwaggerResponseDescription.java
around lines 172 to 174, the error codes DUPLICATED_BOOKS_IN_COLLECTION and
BOOK_NOT_SAVED_DB_CANNOT_DELETE are commented out but still referenced elsewhere
in the code. To fix this, uncomment these two error codes in the Swagger
response description to restore them.

Comment on lines +22 to 32
@Operation(
summary = "피드 전체 조회",
description = "사용자가 작성한 피드를 전체 조회합니다."
)
@GetMapping("/feeds")
public BaseResponse<FeedShowAllResponse> showAllFeeds(
@UserId final Long userId,
@Parameter(hidden = true) @UserId final Long userId,
@Parameter(description = "커서 (첫번째 요청시 : null, 다음 요청시 : 이전 요청에서 반환받은 nextCursor 값)")
@RequestParam(value = "cursor", required = false) final String cursor) {
return BaseResponse.ok(feedShowAllUseCase.showAllFeeds(userId, cursor));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

@ExceptionDescription 어노테이션이 누락되었습니다

다른 컨트롤러들과 달리 showAllFeeds 메서드에 @ExceptionDescription 어노테이션이 없습니다. PR 목표에 따르면 모든 핸들러에 예외 응답 문서화를 위한 이 어노테이션을 추가해야 합니다.

다음과 같이 추가해주세요:

+import konkuk.thip.common.swagger.annotation.ExceptionDescription;
+import static konkuk.thip.common.swagger.SwaggerResponseDescription.*;

 @Tag(name = "Feed Query API", description = "피드 조회 관련 API")
 @RestController
 @RequiredArgsConstructor
 public class FeedQueryController {

     private final FeedShowAllUseCase feedShowAllUseCase;

     @Operation(
             summary = "피드 전체 조회",
             description = "사용자가 작성한 피드를 전체 조회합니다."
     )
+    @ExceptionDescription(FEED_SHOW_ALL)
     @GetMapping("/feeds")

SwaggerResponseDescription enum에 FEED_SHOW_ALL 상수도 추가해야 합니다.

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

🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/feed/adapter/in/web/FeedQueryController.java around
lines 22 to 32, the showAllFeeds method is missing the @ExceptionDescription
annotation required for exception response documentation. Add the
@ExceptionDescription annotation to this method to align with other controllers.
Additionally, update the SwaggerResponseDescription enum by adding the
FEED_SHOW_ALL constant to support this annotation.

Comment on lines +13 to 16
@Schema(description = "기록을 생성할 책의 페이지 번호", example = "20")
@NotNull(message = "page는 필수입니다.")
Integer page,

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

페이지 번호 유효성 검증 추가 권장

page 가 0 이하로 들어와도 통과합니다. 필드에 @Positive@Min(1) 을 추가해 음수/0 을 차단해 주세요.

-@NotNull(message = "page는 필수입니다.")
-Integer page,
+@NotNull(message = "page는 필수입니다.")
+@Positive(message = "page는 1 이상이어야 합니다.")
+Integer page,

추가로 jakarta.validation.constraints.Positive 임포트가 필요합니다.

🤖 Prompt for AI Agents
In
src/main/java/konkuk/thip/record/adapter/in/web/request/RecordCreateRequest.java
around lines 13 to 16, the page field currently allows zero or negative values.
Add the @Positive or @Min(1) annotation to the page field to enforce that only
positive integers are accepted. Also, import
jakarta.validation.constraints.Positive to support this validation annotation.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between dc1271a and f8d2731.

📒 Files selected for processing (3)
  • src/main/java/konkuk/thip/common/exception/code/ErrorCode.java (1 hunks)
  • src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java (3 hunks)
  • src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/konkuk/thip/room/adapter/in/web/RoomQueryController.java
  • src/main/java/konkuk/thip/common/exception/code/ErrorCode.java
⏰ 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
🔇 Additional comments (6)
src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java (6)

3-6: Import 구성이 적절합니다.

Swagger/OpenAPI 문서화를 위한 필수 어노테이션들과 새로운 기능을 위한 클래스들이 올바르게 import되었습니다. static import도 적절히 사용되었습니다.

Also applies to: 11-11, 15-15, 19-19, 23-23, 25-26


27-27: API 그룹화를 위한 @tag 어노테이션이 적절합니다.

컨트롤러의 목적을 명확히 설명하는 한국어 설명과 함께 적절한 태그명을 사용했습니다.


35-35: 새로운 UseCase 의존성 주입이 적절합니다.

닉네임 중복 확인 기능을 위한 UseCase가 올바르게 주입되었습니다.


48-57: 별칭 선택 화면 조회 API의 Swagger 문서화가 적절합니다.

@operation 어노테이션을 통해 API의 목적이 명확하게 문서화되었습니다. 단순한 조회 API이므로 추가적인 파라미터 문서화나 예외 처리 문서화가 필요하지 않아 보입니다.


59-71: 팔로워 조회 API의 Swagger 문서화가 매우 상세합니다.

@parameter 어노테이션을 통해 각 매개변수의 역할이 명확히 설명되어 있고, @ExceptionDescription을 통해 에러 응답도 문서화되어 있습니다. 페이지 크기 제한(1~10)에 대한 설명도 포함되어 있어 개발자가 API를 사용하기 쉽게 구성되었습니다.


73-85: 내 팔로잉 조회 API의 문서화가 적절합니다.

@userid 어노테이션에 hidden = true 속성을 적용하여 내부적으로만 사용되는 파라미터를 Swagger 문서에서 숨긴 것이 좋은 접근입니다. 다른 파라미터들도 적절히 문서화되어 있습니다.

Comment on lines +37 to +46
@Operation(
summary = "닉네임 중복 확인",
description = "사용자가 입력한 닉네임이 중복되는지 확인합니다."
)
@PostMapping("/users/nickname")
public BaseResponse<UserVerifyNicknameResponse> verifyNickname(@Valid @RequestBody final UserVerifyNicknameRequest request) {
return BaseResponse.ok(UserVerifyNicknameResponse.of(
userVerifyNicknameUseCase.isNicknameUnique(request.nickname()))
);
}
Copy link

@coderabbitai coderabbitai bot Jul 28, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

새로운 닉네임 중복 확인 API가 잘 구현되었습니다.

API 설계와 Swagger 문서화가 적절하게 이루어졌습니다. 그러나 몇 가지 개선 사항을 제안합니다:

  1. @ExceptionDescription 어노테이션이 누락되어 있어 에러 응답 문서화가 없습니다.
  2. @parameter 어노테이션을 통한 요청 body 설명이 있으면 더 좋겠습니다.

다음과 같이 개선을 제안합니다:

 @Operation(
         summary = "닉네임 중복 확인",
         description = "사용자가 입력한 닉네임이 중복되는지 확인합니다."
 )
+@ExceptionDescription(/* 적절한 에러 코드 그룹 */)
 @PostMapping("/users/nickname")
-public BaseResponse<UserVerifyNicknameResponse> verifyNickname(@Valid @RequestBody final UserVerifyNicknameRequest request) {
+public BaseResponse<UserVerifyNicknameResponse> verifyNickname(
+        @Parameter(description = "닉네임 중복 확인 요청") @Valid @RequestBody final UserVerifyNicknameRequest request) {
🤖 Prompt for AI Agents
In src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java around
lines 37 to 46, add the @ExceptionDescription annotation to document possible
error responses for the verifyNickname API. Also, enhance the method parameter
by adding the @Parameter annotation to describe the request body for better
Swagger documentation. This will improve API error documentation and request
clarity.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@coderabbitai 이건 request dto 내부에서 bean validation을 수행하고 있어서 @ExceptionDescripton을 따로 작성할 게 없어

Copy link

Choose a reason for hiding this comment

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

@seongjunnoh 맞습니다! 설명해주셔서 감사합니다.

Bean validation만 수행하는 API의 경우 표준 validation 에러만 발생하므로 별도의 @ExceptionDescription이 필요하지 않네요. 비즈니스 로직에서 발생하는 커스텀 에러 코드가 있는 경우에만 @ExceptionDescription을 사용하는 것이 맞겠습니다.

앞으로는 이 점을 고려해서 리뷰하겠습니다!

ᕱ⑅ᕱ


✏️ Learnings added
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#109
File: src/main/java/konkuk/thip/user/adapter/in/web/UserQueryController.java:37-46
Timestamp: 2025-07-29T08:11:23.549Z
Learning: THIP 프로젝트에서 @ExceptionDescription 어노테이션은 비즈니스 로직에서 발생하는 커스텀 에러 코드가 있는 API에만 사용하며, bean validation만 수행하는 API에는 사용하지 않는다.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: buzz0331
PR: THIP-TextHip/THIP-Server#78
File: src/main/java/konkuk/thip/user/application/port/out/FollowingQueryPort.java:3-3
Timestamp: 2025-07-14T18:22:56.538Z
Learning: THIP 프로젝트에서는 Query API(조회 API)에 한해서는 application 계층에서 adapter.in.web.response 패키지의 response DTO를 직접 참조하는 것을 허용함. 이는 CQRS 아키텍처에서 읽기 전용 작업의 효율성을 위한 팀 컨벤션임.

Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#93
File: src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java:49-114
Timestamp: 2025-07-28T16:44:31.197Z
Learning: seongjunnoh는 코드 중복 문제에 대한 리팩토링 제안을 적극적으로 수용하고 함수형 인터페이스를 활용한 해결책을 선호한다.

seongjunnoh
seongjunnoh previously approved these changes Jul 29, 2025
Copy link
Collaborator

@seongjunnoh seongjunnoh left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!!! 항상 감사합니다 🫡

Comment on lines +11 to +12
@Getter
public enum SwaggerResponseDescription {
Copy link
Collaborator

Choose a reason for hiding this comment

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

고생많으셧습니다!!!

Comment on lines +34 to +42
@OpenAPIDefinition(
info = @Info(
title = "Thip 백엔드 API 명세서",
description = "Springdoc을 이용한 Thip Swagger API 문서입니다.",
version = "1.0.0"
)
)
@Configuration
public class OpenApiConfig {
Copy link
Collaborator

Choose a reason for hiding this comment

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

오호 이건 뭔지 궁금하네요. SpringDocs 관련해서 찾아보겠습니다

@buzz0331 buzz0331 merged commit 6c53200 into develop Jul 30, 2025
2 checks passed
@buzz0331 buzz0331 deleted the docs/#108-swagger-config branch July 30, 2025 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[THIP2025-160] [docs] Swagger 명세 작업

2 participants