feat: 어드민에서 출신 대학을 관리하는 기능 추가#725
Conversation
Walkthrough이 PR은 협정 대학교에 대한 관리자용 CRUD 기능을 추가합니다. 생성/수정 요청 DTO와 응답 DTO를 정의하고, 협정 대학 관련 에러 코드 3가지( Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 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.
🧹 Nitpick comments (4)
src/main/java/com/example/solidconnection/admin/university/service/AdminHomeUniversityService.java (1)
82-96: ⚡ Quick win중복 검증 로직을 하나로 합치면 더 깔끔해질 것 같아요.
validateNameNotExists와validateNameNotDuplicated는 사실상 같은 일을 하고 있고,excludeId를null로 넘긴validateNameNotDuplicated(name, null)이validateNameNotExists(name)과 동일하게 동작합니다(existing.getId().equals(null)은 항상false이므로 생성 시에도 의도대로 예외가 발생합니다). 하나로 통합하면 의미 중복을 줄이고 유지보수가 쉬워집니다.♻️ 검증 메서드 통합 제안
- private void validateNameNotExists(String name) { - homeUniversityRepository.findByName(name) - .ifPresent(existing -> { - throw new CustomException(HOME_UNIVERSITY_ALREADY_EXISTS); - }); - } - - private void validateNameNotDuplicated(String name, Long excludeId) { + private void validateNameNotDuplicated(String name, Long excludeId) { homeUniversityRepository.findByName(name) .ifPresent(existing -> { if (!existing.getId().equals(excludeId)) { throw new CustomException(HOME_UNIVERSITY_ALREADY_EXISTS); } }); }생성 시 호출부도 함께 변경합니다.
- validateNameNotExists(request.name()); + validateNameNotDuplicated(request.name(), null);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/example/solidconnection/admin/university/service/AdminHomeUniversityService.java` around lines 82 - 96, Combine the two validators into a single method (keep the name validateNameNotDuplicated(String name, Long excludeId) or choose a clear single name) that uses homeUniversityRepository.findByName(name).ifPresent(existing -> { if (excludeId == null || !existing.getId().equals(excludeId)) throw new CustomException(HOME_UNIVERSITY_ALREADY_EXISTS); }); then replace all calls to validateNameNotExists(name) with validateNameNotDuplicated(name, null) (or call the new single method from both create and update flows) so duplicate-check logic is centralized and correctly handles null excludeId.src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.java (3)
39-44: ⚡ Quick win생성 성공 시 201 Created 상태 코드와 Location 헤더를 반환하는 것을 권장합니다.
현재 구현은 200 OK를 반환하지만, REST 모범 사례에 따르면 리소스 생성 시에는 201 Created 상태 코드를 사용하고 생성된 리소스의 URI를 Location 헤더에 포함해야 합니다. 이렇게 하면 API 사용자가 새로 생성된 리소스에 직접 접근할 수 있습니다.
♻️ 제안하는 개선 방안
+import org.springframework.http.HttpStatus; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import java.net.URI; + `@PostMapping` public ResponseEntity<AdminHomeUniversityResponse> createHomeUniversity( `@Valid` `@RequestBody` AdminHomeUniversityCreateRequest request ) { - return ResponseEntity.ok(adminHomeUniversityService.createHomeUniversity(request)); + AdminHomeUniversityResponse response = adminHomeUniversityService.createHomeUniversity(request); + URI location = ServletUriComponentsBuilder + .fromCurrentRequest() + .path("/{id}") + .buildAndExpand(response.id()) + .toUri(); + return ResponseEntity.created(location).body(response); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.java` around lines 39 - 44, The createHomeUniversity endpoint currently returns 200 OK; change it to return 201 Created with a Location header pointing to the new resource URI. Update the createHomeUniversity controller method to call adminHomeUniversityService.createHomeUniversity(request) to obtain the created resource or its id, build the resource URI (e.g., using ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(created.getId()).toUri()), and return ResponseEntity.created(location).body(createdResponse) so the response status is 201 and the Location header is set.
54-60: ⚡ Quick win삭제 성공 시 204 No Content 상태 코드를 반환하는 것을 권장합니다.
현재 구현은 200 OK를 반환하지만, REST 모범 사례에 따르면 응답 본문이 없는 DELETE 요청은 204 No Content 상태 코드를 사용하는 것이 더 적절합니다.
♻️ 제안하는 개선 방안
`@DeleteMapping`("/{home-university-id}") public ResponseEntity<Void> deleteHomeUniversity( `@PathVariable`("home-university-id") Long homeUniversityId ) { adminHomeUniversityService.deleteHomeUniversity(homeUniversityId); - return ResponseEntity.ok().build(); + return ResponseEntity.noContent().build(); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.java` around lines 54 - 60, Change the deleteHomeUniversity endpoint in AdminHomeUniversityController to return 204 No Content instead of 200 OK: after calling adminHomeUniversityService.deleteHomeUniversity(homeUniversityId) have the method return ResponseEntity.noContent().build() (i.e., use ResponseEntity.noContent() in the deleteHomeUniversity method).
20-23: 🏗️ Heavy lift관리자 엔드포인트(/admin/)는 전역 보안 설정으로 이미 보호되고 있습니다.**
- src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController 의 라우트(
/admin/home-universities)는 SecurityConfiguration에서requestMatchers("/admin/**").hasRole(ADMIN.name())로 처리되어 관리자 역할 없이는 접근이 차단됩니다.- 클래스/메서드 단에
@PreAuthorize를 추가하면 의도가 더 명확해지는 “방어적 가독성” 차원 개선으로 고려할 만합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.java` around lines 20 - 23, 현재 AdminHomeUniversityController 클래스(경로 "/admin/home-universities")는 SecurityConfiguration의 requestMatchers("/admin/**").hasRole(ADMIN.name())로 이미 보호되고 있으나 가독성·방어적 문서화를 위해 클래스나 핵심 메서드에 `@PreAuthorize`("hasRole('ADMIN')")를 추가하세요; 대상은 AdminHomeUniversityController 클래스 선언부 또는 개별 엔드포인트 메서드이며 SecurityConfiguration을 변경하지 말고 `@PreAuthorize` 어노테이션이 Spring Method Security가 활성화된 상태에서만 작동하도록 설정(예: `@EnableMethodSecurity` 또는 `@EnableGlobalMethodSecurity`)되어 있는지 확인하세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.java`:
- Around line 39-44: The createHomeUniversity endpoint currently returns 200 OK;
change it to return 201 Created with a Location header pointing to the new
resource URI. Update the createHomeUniversity controller method to call
adminHomeUniversityService.createHomeUniversity(request) to obtain the created
resource or its id, build the resource URI (e.g., using
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(created.getId()).toUri()),
and return ResponseEntity.created(location).body(createdResponse) so the
response status is 201 and the Location header is set.
- Around line 54-60: Change the deleteHomeUniversity endpoint in
AdminHomeUniversityController to return 204 No Content instead of 200 OK: after
calling adminHomeUniversityService.deleteHomeUniversity(homeUniversityId) have
the method return ResponseEntity.noContent().build() (i.e., use
ResponseEntity.noContent() in the deleteHomeUniversity method).
- Around line 20-23: 현재 AdminHomeUniversityController 클래스(경로
"/admin/home-universities")는 SecurityConfiguration의
requestMatchers("/admin/**").hasRole(ADMIN.name())로 이미 보호되고 있으나 가독성·방어적 문서화를 위해
클래스나 핵심 메서드에 `@PreAuthorize`("hasRole('ADMIN')")를 추가하세요; 대상은
AdminHomeUniversityController 클래스 선언부 또는 개별 엔드포인트 메서드이며 SecurityConfiguration을
변경하지 말고 `@PreAuthorize` 어노테이션이 Spring Method Security가 활성화된 상태에서만 작동하도록 설정(예:
`@EnableMethodSecurity` 또는 `@EnableGlobalMethodSecurity`)되어 있는지 확인하세요.
In
`@src/main/java/com/example/solidconnection/admin/university/service/AdminHomeUniversityService.java`:
- Around line 82-96: Combine the two validators into a single method (keep the
name validateNameNotDuplicated(String name, Long excludeId) or choose a clear
single name) that uses
homeUniversityRepository.findByName(name).ifPresent(existing -> { if (excludeId
== null || !existing.getId().equals(excludeId)) throw new
CustomException(HOME_UNIVERSITY_ALREADY_EXISTS); }); then replace all calls to
validateNameNotExists(name) with validateNameNotDuplicated(name, null) (or call
the new single method from both create and update flows) so duplicate-check
logic is centralized and correctly handles null excludeId.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7445e042-7163-4850-91b6-0a93255e5c60
📒 Files selected for processing (10)
src/main/java/com/example/solidconnection/admin/university/controller/AdminHomeUniversityController.javasrc/main/java/com/example/solidconnection/admin/university/dto/AdminHomeUniversityCreateRequest.javasrc/main/java/com/example/solidconnection/admin/university/dto/AdminHomeUniversityResponse.javasrc/main/java/com/example/solidconnection/admin/university/dto/AdminHomeUniversityUpdateRequest.javasrc/main/java/com/example/solidconnection/admin/university/service/AdminHomeUniversityService.javasrc/main/java/com/example/solidconnection/common/exception/ErrorCode.javasrc/main/java/com/example/solidconnection/siteuser/repository/SiteUserRepository.javasrc/main/java/com/example/solidconnection/university/domain/HomeUniversity.javasrc/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.javasrc/test/java/com/example/solidconnection/admin/university/service/AdminHomeUniversityServiceTest.java
Gyuhyeok99
left a comment
There was a problem hiding this comment.
오랜만에 솔커 코드 보니 마음이 편안해지네요.. 너무 잘읽힙니다
| import com.example.solidconnection.university.domain.HomeUniversity; | ||
|
|
||
| public record AdminHomeUniversityResponse( | ||
| Long id, |
There was a problem hiding this comment.
이런 건 null이될 수 없으니 long이 낫지 않나요? 머쓱하지만 오랜만에 pr봅니다..
| void 저장된_모든_협정대학을_반환한다() { | ||
| // given | ||
| HomeUniversity homeUniversity1 = homeUniversityFixture.인하대학교(); | ||
| HomeUniversity homeUniversity2 = homeUniversityRepository.save(new HomeUniversity(null, "연세대학교")); |
There was a problem hiding this comment.
오랜만에 코드봐서 제가 바뀐 컨벤션을 모르지만 얜 fixture 안쓴 이유가 혹시 있나요?
| private void validateNameNotExists(String name) { | ||
| homeUniversityRepository.findByName(name) | ||
| .ifPresent(existing -> { | ||
| throw new CustomException(HOME_UNIVERSITY_ALREADY_EXISTS); | ||
| }); | ||
| } |
There was a problem hiding this comment.
이제 private 함수는 맨 밑으로 보내게 바뀌었나보군요!
관련 이슈
작업 내용
어드민에서 출신(협정) 대학을 추가하는 CRUD를 추가합니다.
특이 사항
리뷰 요구사항 (선택)