-
Notifications
You must be signed in to change notification settings - Fork 1
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
[DDING-107] 최종 합격 지원자 동아리원 명단 등록 API 구현 #247
Changes from 7 commits
127d48d
526bf35
a16b83f
a927c42
2ab53e0
ba53a19
51b952b
ecc1e7b
89b8511
62414a7
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 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -68,17 +68,20 @@ void deleteForm( | |||||||||||||||||||||||||
@ResponseStatus(HttpStatus.OK) | ||||||||||||||||||||||||||
@SecurityRequirement(name = "AccessToken") | ||||||||||||||||||||||||||
@GetMapping("/my/forms") | ||||||||||||||||||||||||||
List<FormListResponse> getAllMyForm( | ||||||||||||||||||||||||||
@AuthenticationPrincipal PrincipalDetails principalDetails | ||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||
List<FormListResponse> getAllMyForm(@AuthenticationPrincipal PrincipalDetails principalDetails); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
@Operation(summary = "동아리 지원 폼지 상세조회 API") | ||||||||||||||||||||||||||
@ApiResponse(responseCode = "200", description = "동아리 지원 폼지 상세조회 성공", | ||||||||||||||||||||||||||
content = @Content(schema = @Schema(implementation = FormResponse.class))) | ||||||||||||||||||||||||||
@ResponseStatus(HttpStatus.OK) | ||||||||||||||||||||||||||
@SecurityRequirement(name = "AccessToken") | ||||||||||||||||||||||||||
@GetMapping("/my/forms/{formId}") | ||||||||||||||||||||||||||
FormResponse getForm( | ||||||||||||||||||||||||||
@PathVariable("formId") Long formId | ||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||
FormResponse getForm(@PathVariable("formId") Long formId); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
@Operation(summary = "동아리 최종 합격 지원자 동아리원 명단 등록API") | ||||||||||||||||||||||||||
@ApiResponse(responseCode = "200", description = "최종 합격 지원자 동아리원 명단 등록 성공") | ||||||||||||||||||||||||||
5uhwann marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
@ResponseStatus(HttpStatus.CREATED) | ||||||||||||||||||||||||||
@SecurityRequirement(name = "AccessToken") | ||||||||||||||||||||||||||
@GetMapping("/my/forms/{formId}/members/register-applicants") | ||||||||||||||||||||||||||
5uhwann marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
void registerMember(@PathVariable("formId") Long formId); | ||||||||||||||||||||||||||
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. HTTP 메서드 및 응답 상태 코드 수정 필요 현재 구현에는 다음과 같은 문제가 있습니다:
다음과 같이 수정하는 것을 제안합니다: @Operation(summary = "동아리 최종 합격 지원자 동아리원 명단 등록API")
- @ApiResponse(responseCode = "200", description = "최종 합격 지원자 동아리원 명단 등록 성공")
+ @ApiResponse(responseCode = "201", description = "최종 합격 지원자 동아리원 명단 등록 성공")
@ResponseStatus(HttpStatus.CREATED)
@SecurityRequirement(name = "AccessToken")
- @GetMapping("/my/forms/{formId}/members/register-applicants")
+ @PostMapping("/my/forms/{formId}/members/register-applicants")
void registerMember(@PathVariable("formId") Long formId); 📝 Committable suggestion
Suggested change
5uhwann marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,4 +58,9 @@ public FormResponse getForm(Long formId) { | |
FormQuery query = facadeCentralFormService.getForm(formId); | ||
return FormResponse.from(query); | ||
} | ||
|
||
@Override | ||
public void registerMember(Long formId) { | ||
facadeCentralFormService.registerApplicantAsMember(formId); | ||
} | ||
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. 🛠️ Refactor suggestion 에러 처리 및 로깅 추가 필요 중요한 작업에 대한 로깅이 누락되었으며, 예외 처리가 미흡합니다. 다음과 같이 개선하는 것을 제안합니다: + private static final Logger log = LoggerFactory.getLogger(CentralFormController.class);
+
@Override
public void registerMember(Long formId) {
+ log.info("Starting member registration process for form ID: {}", formId);
+ try {
facadeCentralFormService.registerApplicantAsMember(formId);
+ log.info("Successfully registered members for form ID: {}", formId);
+ } catch (Exception e) {
+ log.error("Failed to register members for form ID: {}", formId, e);
+ throw e;
+ }
} |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
package ddingdong.ddingdongBE.domain.form.service; | ||
|
||
import static ddingdong.ddingdongBE.domain.club.entity.Position.MEMBER; | ||
|
||
import ddingdong.ddingdongBE.common.exception.AuthenticationException.NonHaveAuthority; | ||
import ddingdong.ddingdongBE.common.utils.TimeUtils; | ||
import ddingdong.ddingdongBE.domain.club.entity.Club; | ||
import ddingdong.ddingdongBE.domain.club.service.ClubService; | ||
import ddingdong.ddingdongBE.domain.clubmember.entity.ClubMember; | ||
import ddingdong.ddingdongBE.domain.form.entity.Form; | ||
import ddingdong.ddingdongBE.domain.form.entity.FormField; | ||
import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand; | ||
|
@@ -12,6 +15,8 @@ | |
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand.UpdateFormFieldCommand; | ||
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; | ||
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormQuery; | ||
import ddingdong.ddingdongBE.domain.formapplication.entity.FormApplication; | ||
import ddingdong.ddingdongBE.domain.formapplication.service.FormApplicationService; | ||
import ddingdong.ddingdongBE.domain.user.entity.User; | ||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
@@ -28,6 +33,7 @@ public class FacadeCentralFormServiceImpl implements FacadeCentralFormService { | |
private final FormService formService; | ||
private final FormFieldService formFieldService; | ||
private final ClubService clubService; | ||
private final FormApplicationService formApplicationService; | ||
|
||
@Transactional | ||
@Override | ||
|
@@ -79,6 +85,23 @@ public FormQuery getForm(Long formId) { | |
return FormQuery.of(form, formFields); | ||
} | ||
|
||
@Override | ||
@Transactional | ||
public void registerApplicantAsMember(Long formId) { | ||
List<FormApplication> finalPassedFormApplications = formApplicationService.getAllFinalPassedByFormId(formId); | ||
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. p2) 제 의견은 상태 수정 API에서 hasInterview가 false일 경우 서류 통과시 First pass가 아닌 final pass로 변경되는게 좋아보입니다 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. hasInterview가 false일 경우 합격 처리가 되면 FINAL_PASS로 변경이 아닌 FIRST_PASS라는 뜻인가요??? 최종 합격 상태
이게 맞을까요?? 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. 네 최종합격을 판단하는 부분에서 위처럼 해도 좋을 것 같습니다. |
||
finalPassedFormApplications.forEach(formApplication -> { | ||
Club club = formApplication.getForm().getClub(); | ||
ClubMember clubMember = ClubMember.builder() | ||
.name(formApplication.getName()) | ||
.studentNumber(formApplication.getStudentNumber()) | ||
.department(formApplication.getDepartment()) | ||
.phoneNumber(formApplication.getPhoneNumber()) | ||
.position(MEMBER) | ||
.build(); | ||
club.addClubMember(clubMember); | ||
}); | ||
} | ||
Comment on lines
+111
to
+126
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. 보안 및 유효성 검사 추가 필요 다음 사항들을 고려해야 합니다:
다음과 같이 수정하는 것을 제안합니다: @Override
@Transactional
public void registerApplicantAsMember(Long formId) {
+ Form form = formService.getById(formId);
+ Club club = form.getClub();
+ User currentUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+ validateEqualsClub(club, form);
List<FormApplication> finalPassedFormApplications = formApplicationService.getAllFinalPassedByFormId(formId);
finalPassedFormApplications.forEach(formApplication -> {
- Club club = formApplication.getForm().getClub();
+ if (isDuplicateClubMember(club, formApplication.getStudentNumber())) {
+ throw new DuplicateClubMemberException(formApplication.getStudentNumber());
+ }
ClubMember clubMember = ClubMember.builder()
.name(formApplication.getName())
.studentNumber(formApplication.getStudentNumber())
.department(formApplication.getDepartment())
.phoneNumber(formApplication.getPhoneNumber())
.position(MEMBER)
.build();
club.addClubMember(clubMember);
});
}
+ private boolean isDuplicateClubMember(Club club, String studentNumber) {
+ return club.getClubMembers().stream()
+ .anyMatch(member -> member.getStudentNumber().equals(studentNumber));
+ }
|
||
|
||
private FormListQuery buildFormListQuery(Form form) { | ||
boolean isActive = TimeUtils.isDateInRange(LocalDate.now(), form.getStartDate(), form.getEndDate()); | ||
return FormListQuery.from(form, isActive); | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -26,6 +26,12 @@ public class FormApplication extends BaseEntity { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Column(nullable = false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private String department; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Column(nullable = false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private String phoneNumber; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Column(nullable = false) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private String email; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+29
to
+34
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. 🛠️ Refactor suggestion 전화번호와 이메일 필드에 유효성 검증이 필요합니다. 전화번호와 이메일 형식에 대한 유효성 검증이 없습니다. 잘못된 형식의 데이터가 저장될 수 있으므로 다음과 같은 검증을 추가하는 것이 좋겠습니다: + @Pattern(regexp = "^\\d{3}-\\d{3,4}-\\d{4}$", message = "올바른 전화번호 형식이 아닙니다.")
@Column(nullable = false)
private String phoneNumber;
+ @Email(message = "올바른 이메일 형식이 아닙니다.")
@Column(nullable = false)
private String email; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Enumerated(EnumType.STRING) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Column(nullable = false, name = "status") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private FormApplicationStatus status; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -34,10 +40,13 @@ public class FormApplication extends BaseEntity { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private Form form; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private FormApplication(String name, String studentNumber, String department, FormApplicationStatus status, Form form) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private FormApplication(String name, String studentNumber, String department, String phoneNumber, String email, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FormApplicationStatus status, Form form) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.name = name; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.studentNumber = studentNumber; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.department = department; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.phoneNumber = phoneNumber; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.email = email; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.status = status; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.form = form; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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. 🛠️ Refactor suggestion 생성자에 유효성 검증 로직 추가가 필요합니다. 생성자에서 전화번호와 이메일의 유효성을 검증하는 로직을 추가하면 좋겠습니다. @Builder
private FormApplication(String name, String studentNumber, String department, String phoneNumber, String email,
FormApplicationStatus status, Form form) {
+ validatePhoneNumber(phoneNumber);
+ validateEmail(email);
this.name = name;
this.studentNumber = studentNumber;
this.department = department;
this.phoneNumber = phoneNumber;
this.email = email;
this.status = status;
this.form = form;
}
+ private void validatePhoneNumber(String phoneNumber) {
+ if (!phoneNumber.matches("^\\d{3}-\\d{3,4}-\\d{4}$")) {
+ throw new IllegalArgumentException("올바른 전화번호 형식이 아닙니다.");
+ }
+ }
+
+ private void validateEmail(String email) {
+ if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
+ throw new IllegalArgumentException("올바른 이메일 형식이 아닙니다.");
+ }
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,6 +37,11 @@ public List<FormApplication> getAllById(List<Long> applicationIds) { | |||||||||||||||||||||||||||||||||||||
return formApplicationRepository.findAllById(applicationIds); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||
public List<FormApplication> getAllFinalPassedByFormId(Long formId) { | ||||||||||||||||||||||||||||||||||||||
return formApplicationRepository.findAllFinalPassedByFormId(formId); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+42
to
+45
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. 🛠️ Refactor suggestion 메서드 문서화 및 유효성 검사 추가 필요 메서드에 대한 JavaDoc 문서화가 누락되었으며, formId에 대한 유효성 검사가 필요합니다. 다음과 같이 개선하는 것을 제안합니다: + /**
+ * 주어진 폼 ID에 해당하는 최종 합격된 지원서 목록을 조회합니다.
+ *
+ * @param formId 조회할 폼의 ID
+ * @return 최종 합격된 지원서 목록
+ * @throws IllegalArgumentException formId가 null이거나 0 이하인 경우
+ */
@Override
public List<FormApplication> getAllFinalPassedByFormId(Long formId) {
+ if (formId == null || formId <= 0) {
+ throw new IllegalArgumentException("Invalid formId: " + formId);
+ }
return formApplicationRepository.findAllFinalPassedByFormId(formId);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
@Override | ||||||||||||||||||||||||||||||||||||||
public FormApplication getById(Long applicationId) { | ||||||||||||||||||||||||||||||||||||||
return formApplicationRepository.findById(applicationId) | ||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ALTER TABLE form_application | ||
ADD email VARCHAR(255) NULL; | ||
|
||
ALTER TABLE form_application | ||
ADD phone_number VARCHAR(255) NULL; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
package ddingdong.ddingdongBE.domain.form.repository; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import com.navercorp.fixturemonkey.FixtureMonkey; | ||
import ddingdong.ddingdongBE.common.support.DataJpaTestSupport; | ||
import ddingdong.ddingdongBE.common.support.FixtureMonkeyFactory; | ||
|
@@ -13,18 +15,15 @@ | |
import ddingdong.ddingdongBE.domain.user.entity.Role; | ||
import ddingdong.ddingdongBE.domain.user.entity.User; | ||
import ddingdong.ddingdongBE.domain.user.repository.UserRepository; | ||
import java.math.BigDecimal; | ||
import java.time.LocalDate; | ||
import java.util.List; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.data.domain.Slice; | ||
|
||
import java.math.BigDecimal; | ||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class FormApplicationRepositoryTest extends DataJpaTestSupport { | ||
|
||
@Autowired | ||
|
@@ -98,7 +97,6 @@ void findPageByFormIdOrderById() { | |
Form savedForm1 = formRepository.save(form1); | ||
Form savedForm2 = formRepository.save(form2); | ||
|
||
|
||
FormApplication formApplication1 = FormApplication.builder() | ||
.name("지원자1") | ||
.studentNumber("60201111") | ||
|
@@ -138,15 +136,78 @@ void findPageByFormIdOrderById() { | |
.status(FormApplicationStatus.SUBMITTED) | ||
.form(savedForm1) | ||
.build(); | ||
formApplicationRepository.saveAll(List.of(formApplication1, formApplication2, formApplication3, formApplication4, formApplication5)); | ||
formApplicationRepository.saveAll( | ||
List.of(formApplication1, formApplication2, formApplication3, formApplication4, formApplication5)); | ||
|
||
int size = 2; | ||
Long currentCursorId = -1L; | ||
// when | ||
Slice<FormApplication> newestFormApplications = formApplicationRepository.findPageByFormIdOrderById(savedForm1.getId(), size, currentCursorId); | ||
Slice<FormApplication> newestFormApplications = formApplicationRepository.findPageByFormIdOrderById( | ||
savedForm1.getId(), size, currentCursorId); | ||
// then | ||
List<FormApplication> retrievedApplications = newestFormApplications.getContent(); | ||
assertThat(retrievedApplications.size()).isEqualTo(2); | ||
assertThat(retrievedApplications.get(0).getId()).isGreaterThan(retrievedApplications.get(1).getId()); | ||
} | ||
|
||
@DisplayName("최종 합격한 지원서를 폼 ID로 조회한다") | ||
@Test | ||
void findFinalPassApplicationsByFormId() { | ||
//given | ||
Form formA = formRepository.save(Form.builder() | ||
.title("formA") | ||
.startDate(LocalDate.now()) | ||
.endDate(LocalDate.now()) | ||
.hasInterview(false) | ||
.sections(List.of()) | ||
.build()); | ||
Form formB = formRepository.save(Form.builder() | ||
.title("formB") | ||
.startDate(LocalDate.now()) | ||
.endDate(LocalDate.now()) | ||
.hasInterview(false) | ||
.sections(List.of()) | ||
.build()); | ||
|
||
FormApplication applicationA = FormApplication.builder() | ||
.name("nameA") | ||
.studentNumber("test") | ||
.department("test") | ||
.phoneNumber("test") | ||
.email("[email protected]") | ||
.status(FormApplicationStatus.FINAL_PASS) | ||
.form(formA) | ||
.build(); | ||
|
||
FormApplication applicationB = FormApplication.builder() | ||
.name("nameB") | ||
.studentNumber("test") | ||
.department("test") | ||
.phoneNumber("test") | ||
.email("[email protected]") | ||
.status(FormApplicationStatus.SUBMITTED) | ||
.form(formA) | ||
.build(); | ||
|
||
FormApplication applicationC = FormApplication.builder() | ||
.name("nameC") | ||
.studentNumber("test") | ||
.department("test") | ||
.phoneNumber("test") | ||
.email("[email protected]") | ||
.status(FormApplicationStatus.FINAL_PASS) | ||
.form(formB) | ||
.build(); | ||
|
||
formApplicationRepository.saveAll(List.of(applicationA, applicationB, applicationC)); | ||
|
||
//when | ||
List<FormApplication> result = formApplicationRepository.findAllFinalPassedByFormId( | ||
formA.getId()); | ||
|
||
//then | ||
assertThat(result).hasSize(1) | ||
.extracting(FormApplication::getName) | ||
.containsExactly("nameA"); | ||
} | ||
} |
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
메서드 이름과 유효성 검사 개선 필요
메서드 이름이 목적을 명확하게 표현하지 않으며, club 매개변수에 대한 null 검사가 누락되었습니다.
다음과 같이 개선하는 것을 제안합니다:
📝 Committable suggestion