Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthrough게시판에 Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Controller as BoardAdminController
participant Service as GetBoardQueryService
participant Repo as BoardRepository
participant DB as Database
Client->>Controller: GET /admin/clubs/{clubId}/boards/name-duplicate?name=...&boardId=...
Controller->>Service: checkBoardNameDuplicate(clubId, userId, name, boardId)
Service->>Repo: existsByClubIdAndNameAndIsDeletedFalse(clubId, name)
alt boardId provided
Service->>Repo: existsByClubIdAndNameAndIdNotAndIsDeletedFalse(clubId, name, boardId)
end
Repo->>DB: query
DB-->>Repo: result (true/false)
Repo-->>Service: duplicated flag
Service-->>Controller: BoardNameDuplicateResponse(duplicated)
Controller-->>Client: 200 BOARD_NAME_DUPLICATE_CHECK_SUCCESS + payload
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/test/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryServiceTest.kt (1)
196-214: 중복 검출 분기 양방향 케이스를 추가하면 더 견고해집니다.현재
boardId가null이 아닌 분기에서는false를 반환하는 케이스만 검증하고 있습니다.existsByClubIdAndNameAndIsDeletedFalseAndIdNot이true를 반환하는 경우(다른 게시판이 같은 이름을 사용 중인 경우 →duplicated = true)도 추가해두면 분기 양쪽이 모두 검증되어 회귀 방지에 도움이 됩니다.♻️ 추가 케이스 예시
+ it("수정 대상 boardId가 있어도 다른 게시판이 같은 이름을 쓰면 중복으로 반환한다") { + every { + boardRepository.existsByClubIdAndNameAndIsDeletedFalseAndIdNot(clubId, "운영", 3L) + } returns true + + val result = queryService.checkBoardNameDuplicate(clubId, userId, "운영", 3L) + + result.duplicated shouldBe true + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/test/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryServiceTest.kt` around lines 196 - 214, Add the missing positive-duplication case for the branch where a boardId is provided: in GetBoardQueryServiceTest within the "checkBoardNameDuplicate" describe block add a test that stubs boardRepository.existsByClubIdAndNameAndIsDeletedFalseAndIdNot(clubId, "운영", 3L) to return true and assert queryService.checkBoardNameDuplicate(clubId, userId, "운영", 3L).duplicated is true so both sides of the branch in checkBoardNameDuplicate are covered.src/main/kotlin/com/weeth/domain/board/presentation/BoardAdminController.kt (1)
64-76:name쿼리 파라미터 검증 누락
@RequestParam name: String에@NotBlank/@Size(max = 100)같은 제약이 없어 빈 문자열이나 과도하게 긴 값이 그대로 서비스/리포지토리까지 전달됩니다.CreateBoardRequest.name검증과 정책을 맞추시는 것을 권장합니다. 또한 메서드 파라미터 제약을 활성화하려면 클래스에@Validated가 필요하니 함께 확인해 주세요.♻️ 제안 변경
+import org.springframework.validation.annotation.Validated +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size ... +@Validated `@Tag`(name = "Board-Admin", description = "Board Admin API") `@RestController` `@RequestMapping`("/api/v4/admin/clubs/{clubId}/boards") ... fun checkBoardNameDuplicate( `@TsidParam` `@TsidPathVariable` clubId: Long, - `@RequestParam` name: String, + `@RequestParam` `@NotBlank` `@Size`(max = 100) name: String, `@RequestParam`(required = false) boardId: Long?, `@Parameter`(hidden = true) `@CurrentUser` userId: Long, ): CommonResponse<BoardNameDuplicateResponse> =🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/kotlin/com/weeth/domain/board/presentation/BoardAdminController.kt` around lines 64 - 76, The checkBoardNameDuplicate endpoint is missing request parameter validation: add bean validation annotations (e.g., `@NotBlank` and `@Size`(max = 100)) to the name parameter in the checkBoardNameDuplicate method so it rejects blank/oversized names consistent with CreateBoardRequest, and annotate the controller class (BoardAdminController) with `@Validated` to enable method-level constraint enforcement; ensure the correct javax/jakarta.validation imports are present and update any tests that rely on validation behavior.src/main/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryService.kt (1)
84-100:name입력 검증 부재컨트롤러 측에서
name에@NotBlank/@Size검증이 걸려 있지 않아, 빈 문자열이나 비정상적으로 긴 입력이 그대로 이 메서드까지 전달되어 불필요한 DB 조회가 발생할 수 있습니다.CreateBoardRequest.name(@NotBlank,@Size(max = 100))과 일관되게 컨트롤러 파라미터에도 동일한 검증을 적용하시거나, 이 메서드 시작부에서require(name.isNotBlank())정도의 가드를 추가하는 것을 권장합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryService.kt` around lines 84 - 100, checkBoardNameDuplicate currently accepts a raw name and may trigger unnecessary DB lookups for blank or overly long strings; add input guards at the start of GetBoardQueryService.checkBoardNameDuplicate (e.g., require(name.isNotBlank()) and require(name.length <= 100)) to mirror CreateBoardRequest.name constraints, or alternatively ensure the controller parameter for name uses `@NotBlank` and `@Size`(max = 100); keep clubPermissionPolicy.requireAdmin and the repository checks unchanged and return BoardNameDuplicateResponse as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/main/kotlin/com/weeth/domain/board/application/dto/request/CreateBoardRequest.kt`:
- Around line 15-18: The CreateBoardRequest.description field uses `@Size`(max =
30) but the Board entity column is declared with `@Column`(nullable = false,
length = 500), causing a mismatch; update either
CreateBoardRequest.description's `@Size` to match the intended DB capacity (e.g.,
increase to 100 or 500) or change Board's `@Column`(length = 30 or 100) to reflect
the intended UI limit—adjust the annotation on CreateBoardRequest (or the Board
entity) so `@Size` and `@Column`(length=...) are consistent and pick a reasonable
limit (recommend ~100) for Korean descriptions.
In
`@src/main/kotlin/com/weeth/domain/board/application/dto/request/UpdateBoardRequest.kt`:
- Around line 11-13: Update the UpdateBoardRequest DTO to prevent
blank/whitespace-only descriptions from passing validation by adding
`@field`:NotBlank to the description property; keep it nullable (val description:
String? = null) so absent values remain allowed, but when a value is provided
the `@field`:NotBlank (together with the existing `@field`:Size(max = 30) and
`@field`:Schema) will reject empty/whitespace-only strings at the DTO validation
layer and avoid downstream IllegalArgumentException in
Board.updateDescription().
---
Nitpick comments:
In
`@src/main/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryService.kt`:
- Around line 84-100: checkBoardNameDuplicate currently accepts a raw name and
may trigger unnecessary DB lookups for blank or overly long strings; add input
guards at the start of GetBoardQueryService.checkBoardNameDuplicate (e.g.,
require(name.isNotBlank()) and require(name.length <= 100)) to mirror
CreateBoardRequest.name constraints, or alternatively ensure the controller
parameter for name uses `@NotBlank` and `@Size`(max = 100); keep
clubPermissionPolicy.requireAdmin and the repository checks unchanged and return
BoardNameDuplicateResponse as before.
In `@src/main/kotlin/com/weeth/domain/board/presentation/BoardAdminController.kt`:
- Around line 64-76: The checkBoardNameDuplicate endpoint is missing request
parameter validation: add bean validation annotations (e.g., `@NotBlank` and
`@Size`(max = 100)) to the name parameter in the checkBoardNameDuplicate method so
it rejects blank/oversized names consistent with CreateBoardRequest, and
annotate the controller class (BoardAdminController) with `@Validated` to enable
method-level constraint enforcement; ensure the correct javax/jakarta.validation
imports are present and update any tests that rely on validation behavior.
In
`@src/test/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryServiceTest.kt`:
- Around line 196-214: Add the missing positive-duplication case for the branch
where a boardId is provided: in GetBoardQueryServiceTest within the
"checkBoardNameDuplicate" describe block add a test that stubs
boardRepository.existsByClubIdAndNameAndIsDeletedFalseAndIdNot(clubId, "운영", 3L)
to return true and assert queryService.checkBoardNameDuplicate(clubId, userId,
"운영", 3L).duplicated is true so both sides of the branch in
checkBoardNameDuplicate are covered.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7baa2fc4-6618-4a20-84cb-e4e2be1f661e
📒 Files selected for processing (16)
src/main/kotlin/com/weeth/domain/board/application/dto/request/CreateBoardRequest.ktsrc/main/kotlin/com/weeth/domain/board/application/dto/request/UpdateBoardRequest.ktsrc/main/kotlin/com/weeth/domain/board/application/dto/response/BoardDetailResponse.ktsrc/main/kotlin/com/weeth/domain/board/application/mapper/BoardMapper.ktsrc/main/kotlin/com/weeth/domain/board/application/usecase/command/ManageBoardUseCase.ktsrc/main/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryService.ktsrc/main/kotlin/com/weeth/domain/board/domain/entity/Board.ktsrc/main/kotlin/com/weeth/domain/board/presentation/BoardAdminController.ktsrc/main/kotlin/com/weeth/domain/board/presentation/BoardResponseCode.ktsrc/main/kotlin/com/weeth/domain/club/application/usecase/command/ManageClubUseCase.ktsrc/test/kotlin/com/weeth/domain/board/application/usecase/command/ManageBoardUseCaseTest.ktsrc/test/kotlin/com/weeth/domain/board/application/usecase/query/GetBoardQueryServiceTest.ktsrc/test/kotlin/com/weeth/domain/board/domain/entity/BoardEntityTest.ktsrc/test/kotlin/com/weeth/domain/board/fixture/BoardTestFixture.ktsrc/test/kotlin/com/weeth/domain/comment/application/usecase/command/CommentConcurrencyTest.ktsrc/test/kotlin/com/weeth/domain/comment/application/usecase/query/CommentQueryPerformanceTest.kt
| @field:Schema(description = "게시판 설명", example = "공지사항 게시판입니다.") | ||
| @field:NotBlank | ||
| @field:Size(max = 30) | ||
| val description: String, |
There was a problem hiding this comment.
description 최대 길이 정책이 엔티티와 불일치
요청 DTO에서는 @Size(max = 30)로 제한하지만, Board 엔티티는 @Column(nullable = false, length = 500)로 선언되어 있어 컬럼 용량과 실제 입력 한계가 크게 어긋납니다. 둘 중 한쪽으로 정책을 일치시키는 것을 권장합니다(예: 짧은 요약이 의도라면 컬럼을 length = 30(혹은 여유 있게 100 정도)로 줄이거나, 더 긴 설명을 허용할 의도라면 @Size를 늘려 주세요). 또한 30자는 한국어 설명으로는 다소 짧아 사용자 입력이 자주 막힐 수 있어 한 번 검토 부탁드립니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/kotlin/com/weeth/domain/board/application/dto/request/CreateBoardRequest.kt`
around lines 15 - 18, The CreateBoardRequest.description field uses `@Size`(max =
30) but the Board entity column is declared with `@Column`(nullable = false,
length = 500), causing a mismatch; update either
CreateBoardRequest.description's `@Size` to match the intended DB capacity (e.g.,
increase to 100 or 500) or change Board's `@Column`(length = 30 or 100) to reflect
the intended UI limit—adjust the annotation on CreateBoardRequest (or the Board
entity) so `@Size` and `@Column`(length=...) are consistent and pick a reasonable
limit (recommend ~100) for Korean descriptions.
| @field:Schema(description = "게시판 설명", example = "운영 관련 새 공지사항입니다.", nullable = true) | ||
| @field:Size(max = 30) | ||
| val description: String? = null, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -t f 'CreateBoardRequest.kt' | xargs -I{} sh -c 'echo "=== {} ==="; cat "{}"'Repository: Team-Weeth/weeth-server
Length of output: 1241
🏁 Script executed:
fd -t f -i board -e kt | grep -E '(entity|domain)' | head -20Repository: Team-Weeth/weeth-server
Length of output: 1852
🏁 Script executed:
find . -type f -name "Board.kt" -o -name "*Board*.kt" | grep -E 'domain.*entity' | head -10Repository: Team-Weeth/weeth-server
Length of output: 205
🏁 Script executed:
rg "class Board" --type kt -A 10 | head -50Repository: Team-Weeth/weeth-server
Length of output: 94
🏁 Script executed:
cat -n src/main/kotlin/com/weeth/domain/board/domain/entity/Board.ktRepository: Team-Weeth/weeth-server
Length of output: 3963
🏁 Script executed:
rg "updateDescription" --type-list | head -5Repository: Team-Weeth/weeth-server
Length of output: 457
🏁 Script executed:
rg "updateDescription" -A 15 src/main/kotlin/com/weeth/domain/board/domain/entity/Board.ktRepository: Team-Weeth/weeth-server
Length of output: 464
🏁 Script executed:
cat -n src/main/kotlin/com/weeth/domain/board/application/usecase/command/ManageBoardUseCase.ktRepository: Team-Weeth/weeth-server
Length of output: 8671
description 필드에 @NotBlank 추가하여 공백 입력을 DTO 단계에서 차단하세요.
현재 description은 nullable이지만 @field:NotBlank가 없어 빈 문자열이나 공백만으로 이루어진 값이 그대로 통과합니다. 이 값이 Board.updateDescription()에 도달하면 require(newDescription.isNotBlank()) 검증에서 IllegalArgumentException을 발생시켜 400 대신 500으로 응답됩니다.
nullable 의미는 유지하면서(값 미제공 시 null 허용) 값이 있을 때만 공백을 강제하려면 @NotBlank를 함께 추가하세요. Bean Validation의 @NotBlank는 null에 대해서는 검증을 건너뛰므로 nullable 시맨틱을 유지합니다.
참고로 CreateBoardRequest의 description은 이미 @NotBlank와 @Size(max = 30)이 함께 적용되어 있으므로, 일관성 있게 UpdateBoardRequest도 동일하게 구성하는 것이 좋습니다.
🛡️ 제안 수정
`@field`:Schema(description = "게시판 설명", example = "운영 관련 새 공지사항입니다.", nullable = true)
+ `@field`:NotBlank
`@field`:Size(max = 30)
val description: String? = null,-import jakarta.validation.constraints.Size
+import jakarta.validation.constraints.NotBlank
+import jakarta.validation.constraints.Size🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/kotlin/com/weeth/domain/board/application/dto/request/UpdateBoardRequest.kt`
around lines 11 - 13, Update the UpdateBoardRequest DTO to prevent
blank/whitespace-only descriptions from passing validation by adding
`@field`:NotBlank to the description property; keep it nullable (val description:
String? = null) so absent values remain allowed, but when a value is provided
the `@field`:NotBlank (together with the existing `@field`:Size(max = 30) and
`@field`:Schema) will reject empty/whitespace-only strings at the DTO validation
layer and avoid downstream IllegalArgumentException in
Board.updateDescription().
soo0711
left a comment
There was a problem hiding this comment.
수고하셨습니다! 궁금한게 있어서 밑에 질문 달아뒀습니당
| BoardDetailResponse( | ||
| id = null, | ||
| name = "전체", | ||
| description = null, |
There was a problem hiding this comment.
전체에는 하드코딩으로 설명을 넣어주지 않아도 괜찮을까용?
There was a problem hiding this comment.
기본 생성은 하드코딩을 해두는게 좋겠네요!
빌드랑 같이 수정해두겠습니닷
📌 Summary
📝 Changes
What
""
Why
How
📸 Screenshots / Logs
💡 Reviewer 참고사항
✅ Checklist
Summary by CodeRabbit
New Features
Tests