-
Notifications
You must be signed in to change notification settings - Fork 3
feat(Document): 스웨거 정리 및 스웨거 페이지별 그룹 처리(#78) #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,13 @@ | |||||||||||||||||||||||||||||
| import org.springframework.http.ResponseEntity; | ||||||||||||||||||||||||||||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||||||||||||||||||||||||||
| import org.springframework.web.bind.annotation.*; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import io.swagger.v3.oas.annotations.Operation; | ||||||||||||||||||||||||||||||
| import io.swagger.v3.oas.annotations.Parameter; | ||||||||||||||||||||||||||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||||||||||||||||||||||||||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||||||||||||||||||||||||||||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||||||||||||||||||||||||||||||
| @Tag(name = "Chat Read State", description = "채팅 만음 상태 관리 API") | ||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오타: "채팅 만음 상태 관리 API" → "채팅 읽음 상태 관리 API" 사용자 노출 문구의 오탈자입니다. 스웨거 UI 가독성을 위해 즉시 수정 권장. 적용 예: -@Tag(name = "Chat Read State", description = "채팅 만음 상태 관리 API")
+@Tag(name = "Chat Read State", description = "채팅 읽음 상태 관리 API")🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| @RestController | ||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||
| @RequestMapping("/api/chat-rooms") | ||||||||||||||||||||||||||||||
|
|
@@ -20,8 +27,16 @@ public class ChatReadController { | |||||||||||||||||||||||||||||
| private final ChatReadService chatReadService; | ||||||||||||||||||||||||||||||
| private final ChatMembershipRepository membershipRepository; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Operation(summary = "릶음 상태 조회", description = "사용자의 마지막 읽은 메시지와 미읽 개수를 조회합니다") | ||||||||||||||||||||||||||||||
| @ApiResponses(value = { | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "200", description = "읽음 상태 조회 성공"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "401", description = "인증되지 않은 사용자"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "403", description = "채팅방 멤버가 아님"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "500", description = "내부 서버 오류") | ||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오타: "릶음 상태 조회" → "읽음 상태 조회" 스웨거 Operation 요약의 철자 오류입니다. - @Operation(summary = "릶음 상태 조회", description = "사용자의 마지막 읽은 메시지와 미읽 개수를 조회합니다")
+ @Operation(summary = "읽음 상태 조회", description = "사용자의 마지막 읽은 메시지와 미읽 개수를 조회합니다")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| @GetMapping("/{roomId}/read-state") | ||||||||||||||||||||||||||||||
| public ResponseEntity<?> getReadState(@PathVariable UUID roomId, | ||||||||||||||||||||||||||||||
| public ResponseEntity<?> getReadState( | ||||||||||||||||||||||||||||||
| @Parameter(description = "채팅방 ID", required = true) @PathVariable UUID roomId, | ||||||||||||||||||||||||||||||
| @AuthenticationPrincipal CustomUserDetails cud) { | ||||||||||||||||||||||||||||||
| if (cud == null || cud.getUser() == null) { | ||||||||||||||||||||||||||||||
| log.debug("[read-state] 401: no principal"); | ||||||||||||||||||||||||||||||
|
|
@@ -46,9 +61,18 @@ public ResponseEntity<?> getReadState(@PathVariable UUID roomId, | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @Operation(summary = "메시지 읽음 처리", description = "지정된 메시지까지 읽음으로 표시합니다") | ||||||||||||||||||||||||||||||
| @ApiResponses(value = { | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "200", description = "읽음 처리 성공"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "400", description = "잘못된 메시지 ID"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "401", description = "인증되지 않은 사용자"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "403", description = "채팅방 멤버가 아님"), | ||||||||||||||||||||||||||||||
| @ApiResponse(responseCode = "500", description = "내부 서버 오류") | ||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||
| @PostMapping("/{roomId}/read-state") | ||||||||||||||||||||||||||||||
| public ResponseEntity<?> markRead(@PathVariable UUID roomId, | ||||||||||||||||||||||||||||||
| @RequestBody(required = false) Map<String, String> body, | ||||||||||||||||||||||||||||||
| public ResponseEntity<?> markRead( | ||||||||||||||||||||||||||||||
| @Parameter(description = "채팅방 ID", required = true) @PathVariable UUID roomId, | ||||||||||||||||||||||||||||||
| @Parameter(description = "읽음 요청 데이터 (messageId 포함)") @RequestBody(required = false) Map<String, String> body, | ||||||||||||||||||||||||||||||
| @AuthenticationPrincipal CustomUserDetails cud) { | ||||||||||||||||||||||||||||||
| if (cud == null || cud.getUser() == null) { | ||||||||||||||||||||||||||||||
| log.debug("[mark-read] 401: no principal"); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,13 @@ | |
| import likelion.mlb.backendProject.domain.chat.service.ChatRoomQueryService; | ||
| import likelion.mlb.backendProject.domain.chat.service.ChatRoomService; | ||
|
|
||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
|
|
||
| @Tag(name = "Chat Room", description = "채팅방 조회 및 관리 API") | ||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/chat-rooms") | ||
|
|
@@ -21,36 +28,46 @@ public class ChatRoomQueryController { | |
| private final ChatRoomService chatRoomService; | ||
| private final ChatRoomRepository chatRoomRepository; | ||
|
|
||
| /** | ||
| * 방 스코어보드 (4명, 점수/랭크) | ||
| */ | ||
| @Operation(summary = "채팅방 스코어보드 조회", description = "채팅방 참가자들의 점수와 순위를 조회합니다") | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "스코어보드 조회 성공"), | ||
| @ApiResponse(responseCode = "404", description = "채팅방을 찾을 수 없음") | ||
| }) | ||
| @GetMapping("/{roomId}/scoreboard") | ||
| public List<ScoreboardItem> scoreboard(@PathVariable UUID roomId) { | ||
| public List<ScoreboardItem> scoreboard(@Parameter(description = "채팅방 ID", required = true) @PathVariable UUID roomId) { | ||
| return queryService.getScoreboard(roomId); | ||
| } | ||
|
|
||
| /** | ||
| * 특정 참가자의 로스터(11인) + 포메이션 | ||
| */ | ||
| @Operation(summary = "참가자 로스터 조회", description = "특정 참가자의 11명 로스터와 포메이션 정보를 조회합니다") | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "로스터 조회 성공"), | ||
| @ApiResponse(responseCode = "404", description = "참가자를 찾을 수 없음") | ||
| }) | ||
| @GetMapping("/{roomId}/participants/{participantId}/roster") | ||
| public RosterResponse roster(@PathVariable UUID roomId, @PathVariable UUID participantId) { | ||
| public RosterResponse roster( | ||
| @Parameter(description = "채팅방 ID", required = true) @PathVariable UUID roomId, | ||
| @Parameter(description = "참가자 ID", required = true) @PathVariable UUID participantId) { | ||
| return queryService.getRoster(roomId, participantId); | ||
| } | ||
|
|
||
| /** | ||
| * 드래프트로 채팅방 조회 | ||
| */ | ||
| @Operation(summary = "드래프트 채팅방 조회", description = "드래프트 ID로 해당 채팅방을 조회합니다") | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "채팅방 조회 성공"), | ||
| @ApiResponse(responseCode = "404", description = "드래프트에 해당하는 채팅방을 찾을 수 없음") | ||
| }) | ||
| @GetMapping("/by-draft/{draftId}") | ||
| public ChatRoom getChatRoomByDraft(@PathVariable UUID draftId) { | ||
| public ChatRoom getChatRoomByDraft(@Parameter(description = "드래프트 ID", required = true) @PathVariable UUID draftId) { | ||
| return chatRoomRepository.findByDraftId(draftId) | ||
| .orElseThrow(() -> new IllegalArgumentException("ChatRoom not found for draft " + draftId)); | ||
| } | ||
|
Comment on lines
+59
to
62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문서(404)와 런타임 불일치: 404로 매핑되도록 예외 형식 변경 필요 현재는 - return chatRoomRepository.findByDraftId(draftId)
- .orElseThrow(() -> new IllegalArgumentException("ChatRoom not found for draft " + draftId));
+ return chatRoomRepository.findByDraftId(draftId)
+ .orElseThrow(() -> new org.springframework.web.server.ResponseStatusException(
+ org.springframework.http.HttpStatus.NOT_FOUND, "ChatRoom not found for draft " + draftId));필요 시 import 추가: +import org.springframework.http.HttpStatus;
+import org.springframework.web.server.ResponseStatusException;🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * 채팅방 생성 (드래프트용) | ||
| */ | ||
| @Operation(summary = "채팅방 생성", description = "드래프트를 위한 새 채팅방을 생성합니다") | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "채팅방 생성 성공"), | ||
| @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터") | ||
| }) | ||
| @PostMapping | ||
| public ChatRoom createChatRoom(@RequestBody CreateChatRoomRequest request) { | ||
| public ChatRoom createChatRoom(@Parameter(description = "채팅방 생성 요청") @RequestBody CreateChatRoomRequest request) { | ||
| return chatRoomService.createForDraft(request.getDraftId()); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
400(잘못된 커서 값) 응답 문서와 실제 동작 불일치 — 컨트롤러에서 변환 예외 매핑 필요
다음과 같이 400 매핑을 추가해 문서와 일치시키는 것을 권장합니다:
@GetMapping("/{roomId}/messages/before") public ResponseEntity<ChatHistoryPage> before( @Parameter(description = "채팅방 ID", required = true) @PathVariable UUID roomId, - @Parameter(description = "페이지 커서 (이전 조회의 nextCursor 값)", required = true) @RequestParam String cursor, - @Parameter(description = "조회할 메시지 개수 (기본값: 30)") @RequestParam(defaultValue = "30") int limit) { - - return ResponseEntity.ok(chatHistoryService.loadBefore(roomId, cursor, limit)); + @Parameter(description = "페이지 커서 (이전 조회의 nextCursor 값)", required = true) @RequestParam String cursor, + @Parameter(description = "조회할 메시지 개수 (1-100, 기본값: 30)") @RequestParam(defaultValue = "30") int limit) { + try { + return ResponseEntity.ok(chatHistoryService.loadBefore(roomId, cursor, limit)); + } catch (IllegalArgumentException ex) { + return ResponseEntity.badRequest().build(); + } }🤖 Prompt for AI Agents