Skip to content

20260221 #229 게시판 관리 기능 이관#238

Merged
discipline24 merged 4 commits intomainfrom
20260221-#229-게시판-관리-기능-이관
Feb 23, 2026

Hidden character warning

The head ref may contain hidden characters: "20260221-#229-\uac8c\uc2dc\ud310-\uad00\ub9ac-\uae30\ub2a5-\uc774\uad00"
Merged

20260221 #229 게시판 관리 기능 이관#238
discipline24 merged 4 commits intomainfrom
20260221-#229-게시판-관리-기능-이관

Conversation

@nayoung04
Copy link
Contributor

@nayoung04 nayoung04 commented Feb 22, 2026

Summary by CodeRabbit

Release Notes

  • Refactor

    • 게시판 관리 기능을 관리자 전용 API로 이동하여 접근 제어 강화
  • Bug Fixes

    • 게시판 접근 권한 오류 코드명 개선
  • Tests

    • 관련 테스트 케이스 정리

@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

Walkthrough

게시판 생성 및 삭제 기능을 일반 PostService에서 새로운 AdminBoardService로 이전합니다. 기존 BoardController의 공개 엔드포인트를 제거하고, 관리자 전용 AdminBoardController를 신규 생성하여 권한 제어를 강화합니다.

Changes

Cohort / File(s) Summary
공개 API 엔드포인트 제거
backend/src/main/java/org/sejongisc/backend/board/controller/BoardController.java
게시판 생성(POST /{boardId}) 및 삭제(DELETE /{boardId}) 메서드와 Swagger 메타데이터 제거, BoardRequest 임포트 삭제
PostService 인터페이스 정리
backend/src/main/java/org/sejongisc/backend/board/service/PostService.java
createBoard(BoardRequest, UUID)deleteBoard(UUID, UUID) 메서드 제거, BoardRequest 임포트 삭제
PostServiceImpl 구현 단순화
backend/src/main/java/org/sejongisc/backend/board/service/PostServiceImpl.java
두 공개 메서드 제거로 게시판 검증, 소유권 확인, 계층 구조 처리 로직 제거; 관련 임포트 정리
에러 코드 명칭 변경
backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java
INVALID_BOARD_OWNERBOARD_ACCESS_DENIED로 재명명 (상태 및 메시지는 유지)
테스트 케이스 정리
backend/src/test/java/org/sejongisc/backend/board/service/PostServiceImplTest.java
createBoard_Success() 테스트 메서드 제거, ArgumentCaptorBoardRequest 임포트 제거
관리자 전용 API 추가
backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java
/api/board/admin 경로의 게시판 생성(POST) 및 삭제(DELETE /{boardId}) 엔드포인트 신규 추가, 인증 및 Swagger 문서화 포함
관리자 서비스 신규 구현
backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java
게시판 생성/삭제 로직 신규 구현, PRESIDENT 역할 권한 검증, 게시판 계층 구조 처리, 관련 포스트 삭제 기능 포함

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

BE

Suggested reviewers

  • discipline24

Poem

🐰 관리자님의 손으로 게시판을 부르니,
일반 서비스에서는 이제 안녕,
권한 분리의 성 위에 올라앉은
AdminBoardService 왕국 탄생!
코드의 정원이 더욱 깔끔해졌네! 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 게시판 관리 기능을 AdminBoardController와 AdminBoardService로 이관하는 주요 변경사항을 정확하게 반영하고 있습니다.
Docstring Coverage ✅ Passed Docstring coverage is 92.31% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 20260221-#229-게시판-관리-기능-이관

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.

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

🧹 Nitpick comments (3)
backend/src/test/java/org/sejongisc/backend/board/service/PostServiceImplTest.java (1)

40-40: AdminBoardService 테스트 커버리지 누락

createBoard_Success 테스트가 PostServiceImplTest에서 제거되었지만, 새로 추가된 AdminBoardService에 대한 테스트 클래스(AdminBoardServiceTest)가 PR에 포함되어 있지 않습니다. createBoarddeleteBoard 로직(PRESIDENT 역할 검증, 하위 게시판 계단식 삭제 등)에 대한 단위 테스트를 별도로 추가해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/test/java/org/sejongisc/backend/board/service/PostServiceImplTest.java`
at line 40, PostServiceImplTest에서 빠진 createBoard 커버리지를 보완하려면 AdminBoardService에
대한 단위 테스트 클래스(AdminBoardServiceTest)를 추가하고 createBoard 및 deleteBoard 경로를 모두
검증하세요: AdminBoardService의 createBoard가 PRESIDENT 역할을 가진 사용자만 성공하도록
UserRepository(또는 UserService)를 모킹해서 성공 케이스와 권한 부족(권한 예외) 케이스를 각각 작성하고,
deleteBoard는 하위 게시판을 계단식으로 삭제하는 로직을 BoardRepository(또는 BoardService)를 모킹해 하위
엔티티들이 모두 삭제되는 성공 케이스와 존재하지 않는 게시판/권한 실패 케이스를 추가해 검증하세요.
backend/src/main/java/org/sejongisc/backend/board/service/AdminBoardService.java (1)

82-85: deletePost에 게시물 작성자 ID를 전달하는 우회 패턴

postService.deletePost(row.getPostId(), row.getUserId())deletePost의 작성자 소유권 검사를 통과시키기 위해 포스트 작성자의 userId를 그대로 전달합니다. 현재는 동작하지만, 향후 deletePost에 감사(audit) 로그나 알림 로직이 추가될 경우 실제 수행자(회장)가 아닌 게시물 작성자 ID가 기록되는 문제가 생깁니다.

관리자용 삭제 경로를 소유권 검사에 의존하지 않도록 분리하는 것이 좋습니다. 예를 들어 PostServiceadminDeletePost(UUID postId) 메서드를 추가하거나, 레포지토리를 직접 호출하는 전용 헬퍼를 AdminBoardService 내부에 두는 방식을 고려해 주세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/board/service/AdminBoardService.java`
around lines 82 - 85, The current loop in AdminBoardService calls
postService.deletePost(row.getPostId(), row.getUserId()) which incorrectly
records the post author as the actor; instead add an admin-specific deletion
path and call it here (e.g., implement PostService.adminDeletePost(UUID postId)
and replace the deletePost call with
postService.adminDeletePost(row.getPostId())), or perform repository-level
deletion from AdminBoardService using postRepository.deleteById(row.getPostId())
to avoid owner-based checks and ensure audit/notification logic uses the admin
actor; update usages of postRepository.findPostIdAndUserIdByBoardId and
boardRepository.deleteById accordingly.
backend/src/main/java/org/sejongisc/backend/board/controller/AdminBoardController.java (1)

54-61: ResponseEntity<?> 대신 구체적인 타입 사용 권장

deleteBoard의 반환 타입이 ResponseEntity<?>로 선언되어 있어 타입 안전성이 낮습니다. 응답 본문이 String이므로 ResponseEntity<String>으로 명시하거나, createBoard와 일관성을 맞춰 ResponseEntity<Void>에 빈 바디로 통일하는 방향을 고려해 주세요.

♻️ 수정 제안 (구체적 타입으로 변경)
-  public ResponseEntity<?> deleteBoard(
+  public ResponseEntity<String> deleteBoard(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/board/controller/AdminBoardController.java`
around lines 54 - 61, Change the method signature in
AdminBoardController.deleteBoard from ResponseEntity<?> to a concrete type
(e.g., ResponseEntity<String>) and update the return to match; specifically,
replace ResponseEntity<?> deleteBoard(...) with ResponseEntity<String>
deleteBoard(...) and keep returning ResponseEntity.ok("게시판 삭제가 완료되었습니다."); (or
alternatively switch to ResponseEntity<Void> and return
ResponseEntity.noContent().build() if you prefer empty-body consistency with
createBoard). Ensure imports and method signature references reflect the new
concrete ResponseEntity type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@backend/src/main/java/org/sejongisc/backend/board/controller/AdminBoardController.java`:
- Around line 32-37: In AdminBoardController update the `@Operation` description
for the createBoard endpoint: replace the incorrect phrase "회장만 삭제할 수 있습니다."
with "회장만 생성할 수 있습니다." so the summary/description for the createBoard method
accurately states that only the president can create boards; locate the
annotation on the createBoard method and change that single word.
- Around line 20-27: Remove the unused empty AdminBoardController class in the
admin.controller package (the file
backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java)
to avoid the duplicate with
org.sejongisc.backend.board.controller.AdminBoardController; delete the
class/file and any unused imports or bean references pointing to that
admin.controller.AdminBoardController, ensuring the remaining
board.controller.AdminBoardController (annotated with `@RestController` and
`@RequestMapping`("/api/board/admin")) is the sole controller for admin board
endpoints.

In
`@backend/src/main/java/org/sejongisc/backend/board/service/AdminBoardService.java`:
- Around line 66-86: After role validation in AdminBoardService.deleteBoard,
explicitly verify the target board exists by calling
boardRepository.findById(boardId).orElseThrow(() -> new
CustomException(ErrorCode.BOARD_NOT_FOUND)) before using boardId to fetch child
boards or delete; this ensures a meaningful BOARD_NOT_FOUND error is thrown and
prevents downstream EmptyResultDataAccessException when calling
boardRepository.findAllByParentBoard_BoardId(boardId) or deleteById.
- Around line 43-51: When creating a board with request.getParentBoardId(),
verify the fetched parentBoard (from boardRepository.findById(...)) is a
top-level board by checking parentBoard.getParentBoard() == null; if it isn’t,
throw a CustomException (use an appropriate ErrorCode such as a new or existing
one for invalid parent/depth) before building the new Board so you cannot create
a 3rd-level board that would block posting. Ensure this check is placed
immediately after obtaining parentBoard and before using Board.builder().

---

Nitpick comments:
In
`@backend/src/main/java/org/sejongisc/backend/board/controller/AdminBoardController.java`:
- Around line 54-61: Change the method signature in
AdminBoardController.deleteBoard from ResponseEntity<?> to a concrete type
(e.g., ResponseEntity<String>) and update the return to match; specifically,
replace ResponseEntity<?> deleteBoard(...) with ResponseEntity<String>
deleteBoard(...) and keep returning ResponseEntity.ok("게시판 삭제가 완료되었습니다."); (or
alternatively switch to ResponseEntity<Void> and return
ResponseEntity.noContent().build() if you prefer empty-body consistency with
createBoard). Ensure imports and method signature references reflect the new
concrete ResponseEntity type.

In
`@backend/src/main/java/org/sejongisc/backend/board/service/AdminBoardService.java`:
- Around line 82-85: The current loop in AdminBoardService calls
postService.deletePost(row.getPostId(), row.getUserId()) which incorrectly
records the post author as the actor; instead add an admin-specific deletion
path and call it here (e.g., implement PostService.adminDeletePost(UUID postId)
and replace the deletePost call with
postService.adminDeletePost(row.getPostId())), or perform repository-level
deletion from AdminBoardService using postRepository.deleteById(row.getPostId())
to avoid owner-based checks and ensure audit/notification logic uses the admin
actor; update usages of postRepository.findPostIdAndUserIdByBoardId and
boardRepository.deleteById accordingly.

In
`@backend/src/test/java/org/sejongisc/backend/board/service/PostServiceImplTest.java`:
- Line 40: PostServiceImplTest에서 빠진 createBoard 커버리지를 보완하려면 AdminBoardService에
대한 단위 테스트 클래스(AdminBoardServiceTest)를 추가하고 createBoard 및 deleteBoard 경로를 모두
검증하세요: AdminBoardService의 createBoard가 PRESIDENT 역할을 가진 사용자만 성공하도록
UserRepository(또는 UserService)를 모킹해서 성공 케이스와 권한 부족(권한 예외) 케이스를 각각 작성하고,
deleteBoard는 하위 게시판을 계단식으로 삭제하는 로직을 BoardRepository(또는 BoardService)를 모킹해 하위
엔티티들이 모두 삭제되는 성공 케이스와 존재하지 않는 게시판/권한 실패 케이스를 추가해 검증하세요.

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

🧹 Nitpick comments (5)
backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java (2)

38-45: 생성 응답에 201 Created 사용 권장

RESTful 관례상 리소스 생성 시 200 OK 대신 201 Created를 반환하는 것이 더 적합합니다.

♻️ 수정 제안
-    return ResponseEntity.ok().build();
+    return ResponseEntity.status(HttpStatus.CREATED).build();

HttpStatus import 추가 필요:

import org.springframework.http.HttpStatus;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java`
around lines 38 - 45, The createBoard method in AdminBoardController currently
returns ResponseEntity.ok() (200); change it to return a 201 Created response
when a board is created by using
ResponseEntity.status(HttpStatus.CREATED).build() (or equivalent) in the
createBoard method that calls adminBoardService.createBoard(request, userId);
also add the import for org.springframework.http.HttpStatus to the file so the
HttpStatus.CREATED symbol is available.

54-61: deleteBoard 반환 타입 불일치 및 응답 코드

createBoardResponseEntity<Void>를 반환하지만, deleteBoardResponseEntity<?>를 반환합니다. 반환 타입의 일관성을 위해 구체적인 타입을 명시하는 것이 좋습니다. 또한 삭제 시에는 204 No Content가 RESTful 관례에 부합합니다.

♻️ 수정 제안
-  public ResponseEntity<?> deleteBoard(
+  public ResponseEntity<Void> deleteBoard(
       `@PathVariable` UUID boardId,
       `@AuthenticationPrincipal` CustomUserDetails customUserDetails) {
     UUID userId = customUserDetails.getUserId();
     adminBoardService.deleteBoard(boardId, userId);
-    return ResponseEntity.ok("게시판 삭제가 완료되었습니다.");
+    return ResponseEntity.noContent().build();
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java`
around lines 54 - 61, Change deleteBoard's signature to return
ResponseEntity<Void> and update its response to use 204 No Content; keep calling
adminBoardService.deleteBoard(boardId, userId) but replace the current
ResponseEntity.ok(...) return with ResponseEntity.noContent().build() so it
matches createBoard's explicit Void type and RESTful conventions.
backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java (3)

26-29: PostRepository 직접 의존 — 서비스 간 책임 경계

AdminBoardServicePostRepository를 직접 주입받아 게시물 조회에 사용하고 있습니다. 게시물 관련 조회/삭제는 PostService를 통해 처리하는 것이 계층 간 책임 분리에 더 부합합니다. 벌크 삭제 메서드를 PostService에 추가하면 PostRepository 직접 의존도 제거할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`
around lines 26 - 29, AdminBoardService가 직접 PostRepository에 의존하고 있으니
PostRepository 주입을 제거하고 게시물 관련 작업은 PostService로 위임하세요: PostService에 게시물 일괄삭제/조회용
메서드(예: deletePostsByBoardIds(Collection<Long> boardIds) 또는 deleteByBoardId(Long
boardId) 등)를 추가하고 기존 AdminBoardService에서 postRepository를 사용하던 모든 위치를 해당
PostService 메서드 호출로 대체한 뒤 생성자에서 PostRepository 필드를 제거하세요.

44-60: createBoard의 if/else 분기에서 빌더 코드 중복

parentBoard 설정 여부만 다르고 나머지 빌더 코드가 동일합니다. 하나의 빌더 체인으로 통합하면 중복을 줄일 수 있습니다.

♻️ 리팩터링 제안
-    Board board;
-    // 하위 게시판인 경우
-    if (request.getParentBoardId() != null) {
-      Board parentBoard = boardRepository.findById(request.getParentBoardId())
-          .orElseThrow(() -> new CustomException(ErrorCode.BOARD_NOT_FOUND));
-
-      board = Board.builder()
-          .boardName(request.getBoardName())
-          .createdBy(user)
-          .parentBoard(parentBoard)
-          .build();
-    } else {
-      // 상위 게시판인 경우
-      board = Board.builder()
-          .boardName(request.getBoardName())
-          .createdBy(user)
-          .parentBoard(null)
-          .build();
-    }
+    Board parentBoard = null;
+    if (request.getParentBoardId() != null) {
+      parentBoard = boardRepository.findById(request.getParentBoardId())
+          .orElseThrow(() -> new CustomException(ErrorCode.BOARD_NOT_FOUND));
+    }
+
+    Board board = Board.builder()
+        .boardName(request.getBoardName())
+        .createdBy(user)
+        .parentBoard(parentBoard)
+        .build();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`
around lines 44 - 60, The createBoard method duplicates the Board.builder()
chain in both branches; instead, compute a single parentBoard reference (resolve
via boardRepository.findById(request.getParentBoardId()).orElseThrow(...) when
request.getParentBoardId() != null, otherwise set parentBoard = null) and then
build the entity once with
Board.builder().boardName(request.getBoardName()).createdBy(user).parentBoard(parentBoard).build(),
keeping the existing error handling that throws
CustomException(ErrorCode.BOARD_NOT_FOUND) when lookup fails.

85-89: 게시물 삭제 — N+1 성능 이슈

postService.deletePost()를 게시물마다 개별 호출하면, 게시판에 게시물이 많을수록 불필요한 DB 쿼리가 증가합니다. findPostIdAndUserIdByBoardId로 데이터를 이미 조회한 후, deletePost 내부에서 다시 게시물을 조회하는 N+1 패턴이 발생합니다.

관리자 전용 벌크 삭제 메서드(deletePostsByBoardId 등)를 PostService에 추가하여, 게시판 삭제 시 게시물을 한 번에 삭제하도록 개선하는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`
around lines 85 - 89, The current loop uses postService.deletePost(...) per post
causing N+1 queries: replace this with a bulk delete call on PostService (e.g.,
add and call PostService.deletePostsByBoardId or deletePostsByBoardIds) that
accepts a boardId or list of boardIds and deletes posts in one repository
operation; update the code that currently uses
targetBoardIds.stream().flatMap(id ->
postRepository.findPostIdAndUserIdByBoardId(id)...) and
postService.deletePost(...) to instead call the new bulk method (and keep the
subsequent boardRepository::deleteById after posts are removed).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java`:
- Around line 20-27: The AdminBoardController endpoints under
"/api/board/admin/**" are not covered by the SecurityFilterChain and only rely
on a service-layer Role.PRESIDENT check; either add the path to the centralized
SecurityConstants.ADMIN_ONLY_URLS pattern or apply method-level security on
AdminBoardController (e.g., annotate controller methods or the class with
`@PreAuthorize`("hasAnyRole('PRESIDENT','SYSTEM_ADMIN')") to match
AdminUserController) so requests are rejected at the filter layer and
unnecessary service calls are avoided.

In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`:
- Around line 78-83: The current collection of targetBoardIds in
AdminBoardService only includes the given boardId and its immediate children via
findAllByParentBoard_BoardId(boardId); replace this with a defensive recursive
or iterative descendant traversal to collect all descendant Board IDs (e.g.,
implement a helper method getAllDescendantBoardIds(UUID rootId) that uses
findAllByParentBoard_BoardId to fetch children, then recurses or BFS/DFS to
accumulate grandchildren etc.), then use that result (plus the rootId) where
targetBoardIds is used; alternatively, enforce depth validation in createBoard
to prevent >2 levels, but the recommended fix is to add the recursive/iterative
collector and reference it from the deletion logic in AdminBoardService.

---

Duplicate comments:
In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`:
- Around line 44-52: AdminBoardService의 게시판 생성 로직(요청 블록에서
request.getParentBoardId() 처리)에서 parentBoard가 이미 부모를 가지고 있는지를 검증하지 않아 3단계 계층이
만들어질 수 있으므로, boardRepository.findById(request.getParentBoardId())로 조회한
parentBoard에 대해 parentBoard.getParentBoard() != null 인지 확인하고, 해당 경우에는 새 Board 생성
대신 CustomException을 던지도록 변경하세요(예: throw new
CustomException(ErrorCode.BOARD_DEPTH_EXCEEDED) 또는 적절한 ErrorCode 사용). 이 검증은
Board.builder(...)를 호출하기 전에 적용되어야 하며, 참조 대상은 AdminBoardService, Board,
request.getParentBoardId(), boardRepository.findById(...)입니다.

---

Nitpick comments:
In
`@backend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.java`:
- Around line 38-45: The createBoard method in AdminBoardController currently
returns ResponseEntity.ok() (200); change it to return a 201 Created response
when a board is created by using
ResponseEntity.status(HttpStatus.CREATED).build() (or equivalent) in the
createBoard method that calls adminBoardService.createBoard(request, userId);
also add the import for org.springframework.http.HttpStatus to the file so the
HttpStatus.CREATED symbol is available.
- Around line 54-61: Change deleteBoard's signature to return
ResponseEntity<Void> and update its response to use 204 No Content; keep calling
adminBoardService.deleteBoard(boardId, userId) but replace the current
ResponseEntity.ok(...) return with ResponseEntity.noContent().build() so it
matches createBoard's explicit Void type and RESTful conventions.

In
`@backend/src/main/java/org/sejongisc/backend/admin/service/AdminBoardService.java`:
- Around line 26-29: AdminBoardService가 직접 PostRepository에 의존하고 있으니
PostRepository 주입을 제거하고 게시물 관련 작업은 PostService로 위임하세요: PostService에 게시물 일괄삭제/조회용
메서드(예: deletePostsByBoardIds(Collection<Long> boardIds) 또는 deleteByBoardId(Long
boardId) 등)를 추가하고 기존 AdminBoardService에서 postRepository를 사용하던 모든 위치를 해당
PostService 메서드 호출로 대체한 뒤 생성자에서 PostRepository 필드를 제거하세요.
- Around line 44-60: The createBoard method duplicates the Board.builder() chain
in both branches; instead, compute a single parentBoard reference (resolve via
boardRepository.findById(request.getParentBoardId()).orElseThrow(...) when
request.getParentBoardId() != null, otherwise set parentBoard = null) and then
build the entity once with
Board.builder().boardName(request.getBoardName()).createdBy(user).parentBoard(parentBoard).build(),
keeping the existing error handling that throws
CustomException(ErrorCode.BOARD_NOT_FOUND) when lookup fails.
- Around line 85-89: The current loop uses postService.deletePost(...) per post
causing N+1 queries: replace this with a bulk delete call on PostService (e.g.,
add and call PostService.deletePostsByBoardId or deletePostsByBoardIds) that
accepts a boardId or list of boardIds and deletes posts in one repository
operation; update the code that currently uses
targetBoardIds.stream().flatMap(id ->
postRepository.findPostIdAndUserIdByBoardId(id)...) and
postService.deletePost(...) to instead call the new bulk method (and keep the
subsequent boardRepository::deleteById after posts are removed).

Copy link
Contributor

@discipline24 discipline24 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~

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.

2 participants