From bc965d9bbdd3831decdb5cfa22fb2c392876c9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=95=84?= <143075401+alsdddk@users.noreply.github.com> Date: Wed, 1 Oct 2025 20:48:24 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=ED=99=9C=EC=84=B1=ED=99=94?= =?UTF-8?q?=EB=90=9C=20=EC=A7=80=EC=9B=90=EC=84=9C=EC=9D=98=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=9D=84=20=EB=B6=88=EB=9F=AC=EC=98=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 지원서 id와 제목, description을 list로 반환 --- .../club/controller/ClubApplyController.java | 34 ++++++++++-------- .../payload/dto/ClubActiveFormResult.java | 11 ++++++ .../club/payload/dto/ClubActiveFormSlim.java | 7 ++++ .../response/ClubActiveFormsResponse.java | 12 +++++++ .../ClubApplicationFormsRepository.java | 9 +++-- .../club/service/ClubApplyService.java | 35 +++++++++++++------ .../moadong/global/exception/ErrorCode.java | 1 + 7 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 backend/src/main/java/moadong/club/payload/dto/ClubActiveFormResult.java create mode 100644 backend/src/main/java/moadong/club/payload/dto/ClubActiveFormSlim.java create mode 100644 backend/src/main/java/moadong/club/payload/response/ClubActiveFormsResponse.java diff --git a/backend/src/main/java/moadong/club/controller/ClubApplyController.java b/backend/src/main/java/moadong/club/controller/ClubApplyController.java index fed484a52..07b4e18d0 100644 --- a/backend/src/main/java/moadong/club/controller/ClubApplyController.java +++ b/backend/src/main/java/moadong/club/controller/ClubApplyController.java @@ -49,19 +49,6 @@ public ResponseEntity createClubApplicationForm(@PathVariable String clubId, return Response.ok("success create application"); } - @GetMapping("/application") - @Operation(summary = "클럽 지원서 양식들 불러오기", description = "클럽 지원서 양식들을 학기별로 분류하여 불러옵니다") - @PreAuthorize("isAuthenticated()") - @SecurityRequirement(name = "BearerAuth") - public ResponseEntity getClubApplications(@PathVariable String clubId, - @CurrentUser CustomUserDetails user, - @RequestParam(defaultValue = "agg") String mode) { //agg면 aggregation사용, server면, 서비스에서 그룹 및 정렬 - if("server".equalsIgnoreCase(mode)) { - return Response.ok(clubApplyService.getGroupedClubApplicationForms(clubId, user)); - } - return Response.ok(clubApplyService.getClubApplicationForms(clubId, user)); - } - @PutMapping("/application/{applicationFormId}") @Operation(summary = "클럽 지원서 양식 수정", description = "클럽 지원서 양식을 수정합니다") @PreAuthorize("isAuthenticated()") @@ -74,6 +61,19 @@ public ResponseEntity editClubApplicationForm(@PathVariable String clubId, return Response.ok("success edit application"); } + @GetMapping("/application") + @Operation(summary = "클럽의 모든 지원서 양식 목록 불러오기", description = "클럽의 모든 지원서 양식들을 학기별로 분류하여 불러옵니다") + @PreAuthorize("isAuthenticated()") + @SecurityRequirement(name = "BearerAuth") + public ResponseEntity getClubApplications(@PathVariable String clubId, + @CurrentUser CustomUserDetails user, + @RequestParam(defaultValue = "agg") String mode) { //agg면 aggregation사용, server면, 서비스에서 그룹 및 정렬 + if("server".equalsIgnoreCase(mode)) { + return Response.ok(clubApplyService.getGroupedClubApplicationForms(clubId, user)); + } + return Response.ok(clubApplyService.getClubApplicationForms(clubId, user)); + } + @GetMapping("/apply/{applicationFormId}") @Operation(summary = "클럽 지원서 양식 불러오기", description = "클럽 지원서 양식을 불러옵니다") public ResponseEntity getClubApplication(@PathVariable String clubId, @@ -83,13 +83,19 @@ public ResponseEntity getClubApplication(@PathVariable String clubId, @PostMapping("/apply/{applicationFormId}") @Operation(summary = "클럽 지원", description = "클럽에 지원합니다") - public ResponseEntity applyToClub(@PathVariable String clubId, + public ResponseEntity applyToClub(@PathVariable String clubId, @PathVariable String applicationFormId, @RequestBody @Validated ClubApplyRequest request) { clubApplyService.applyToClub(clubId, applicationFormId, request); return Response.ok("success apply"); } + @GetMapping("/apply") + @Operation(summary = "클럽의 활성화된 지원서 목록 불러오기", description = "클럽의 활성화된 모든 지원서 목록을 불러옵니다") + public ResponseEntity getActiveApplicationForms(@PathVariable String clubId) { + return Response.ok(clubApplyService.getActiveApplicationForms(clubId)); + } + @GetMapping("/apply/info/{applicationFormId}") @Operation(summary = "클럽 지원자 현황", description = "클럽 지원자 현황을 불러옵니다") @PreAuthorize("isAuthenticated()") diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormResult.java b/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormResult.java new file mode 100644 index 000000000..5348f0a2d --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormResult.java @@ -0,0 +1,11 @@ +package moadong.club.payload.dto; + +import lombok.Builder; + +@Builder +public record ClubActiveFormResult( + String id, + String title, + String description +) { +} diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormSlim.java b/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormSlim.java new file mode 100644 index 000000000..00199fc28 --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/ClubActiveFormSlim.java @@ -0,0 +1,7 @@ +package moadong.club.payload.dto; + +public interface ClubActiveFormSlim { + String getId(); + String getTitle(); + String getDescription(); +} diff --git a/backend/src/main/java/moadong/club/payload/response/ClubActiveFormsResponse.java b/backend/src/main/java/moadong/club/payload/response/ClubActiveFormsResponse.java new file mode 100644 index 000000000..d182691da --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/response/ClubActiveFormsResponse.java @@ -0,0 +1,12 @@ +package moadong.club.payload.response; + +import lombok.Builder; +import moadong.club.payload.dto.ClubActiveFormResult; + +import java.util.List; + +@Builder +public record ClubActiveFormsResponse ( + List forms +){ +} diff --git a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java index eabc91062..06666d3d5 100644 --- a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java +++ b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java @@ -3,9 +3,8 @@ import java.util.List; import java.util.Optional; -import moadong.club.entity.Club; import moadong.club.entity.ClubApplicationForm; -import moadong.club.enums.SemesterTerm; +import moadong.club.payload.dto.ClubActiveFormSlim; import moadong.club.payload.dto.ClubApplicationFormSlim; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.repository.MongoRepository; @@ -24,4 +23,10 @@ public interface ClubApplicationFormsRepository extends MongoRepository findClubApplicationFormsByClubId(String clubId, Sort sort); + + @Query( + value = "{'clubId': ?0, 'status': 'ACTIVE'}", + fields = "{'_id': 1, 'title': 1, 'description': 1}" + ) + List findClubActiveFormsByClubId(String clubId); } diff --git a/backend/src/main/java/moadong/club/service/ClubApplyService.java b/backend/src/main/java/moadong/club/service/ClubApplyService.java index 7d66937b8..40a09ad2c 100644 --- a/backend/src/main/java/moadong/club/service/ClubApplyService.java +++ b/backend/src/main/java/moadong/club/service/ClubApplyService.java @@ -20,19 +20,13 @@ import moadong.club.entity.ClubQuestionOption; import moadong.club.enums.ClubApplicationQuestionType; import moadong.club.enums.SemesterTerm; -import moadong.club.payload.dto.ClubApplicantsResult; -import moadong.club.payload.dto.ClubApplicationFormSlim; -import moadong.club.payload.dto.ClubApplicationFormsResultItem; -import moadong.club.payload.dto.ClubApplicationFormsResult; +import moadong.club.payload.dto.*; import moadong.club.payload.request.ClubApplicationFormCreateRequest; import moadong.club.payload.request.ClubApplicationFormEditRequest; import moadong.club.payload.request.ClubApplicantEditRequest; import moadong.club.payload.request.ClubApplicantDeleteRequest; import moadong.club.payload.request.ClubApplyRequest; -import moadong.club.payload.response.ClubApplicationFormResponse; -import moadong.club.payload.response.ClubApplyInfoResponse; -import moadong.club.payload.response.ClubApplicationFormsResponse; -import moadong.club.payload.response.SemesterOptionResponse; +import moadong.club.payload.response.*; import moadong.club.repository.*; import moadong.global.exception.ErrorCode; import moadong.global.exception.RestApiException; @@ -103,7 +97,7 @@ public void createClubApplicationForm(String clubId, CustomUserDetails user, Clu public void editClubApplication(String clubId, String applicationFormId, CustomUserDetails user, ClubApplicationFormEditRequest request) { validateClubOwner(clubId, user); - ClubApplicationForm clubApplicationForm = clubApplicationFormsRepository.findById(applicationFormId) + ClubApplicationForm clubApplicationForm = clubApplicationFormsRepository.findByClubIdAndId(clubId, applicationFormId) .orElseThrow(() -> new RestApiException(ErrorCode.APPLICATION_NOT_FOUND)); clubApplicationForm.updateEditedAt(); @@ -202,8 +196,29 @@ private static String termName(SemesterTerm term) { private record SemesterKey(Integer year, SemesterTerm term) {} + public ClubActiveFormsResponse getActiveApplicationForms(String clubId) { + List forms = clubApplicationFormsRepository.findClubActiveFormsByClubId(clubId); + + if(forms == null || forms.isEmpty()) + throw new RestApiException(ErrorCode.ACTIVE_APPLICATION_NOT_FOUND); + + List results = new ArrayList<>(); + for (ClubActiveFormSlim form : forms) { + ClubActiveFormResult result = ClubActiveFormResult.builder() + .id(form.getId()) + .title(form.getTitle()) + .description(form.getDescription()) + .build(); + results.add(result); + } + + return ClubActiveFormsResponse.builder() + .forms(results) + .build(); + + } -public void applyToClub(String clubId, String applicationFormId, ClubApplyRequest request) { + public void applyToClub(String clubId, String applicationFormId, ClubApplyRequest request) { ClubApplicationForm clubApplicationForm = clubApplicationFormsRepository.findByClubIdAndId(clubId, applicationFormId) .orElseThrow(() -> new RestApiException(ErrorCode.APPLICATION_NOT_FOUND)); diff --git a/backend/src/main/java/moadong/global/exception/ErrorCode.java b/backend/src/main/java/moadong/global/exception/ErrorCode.java index a0c284197..47ef18d7a 100644 --- a/backend/src/main/java/moadong/global/exception/ErrorCode.java +++ b/backend/src/main/java/moadong/global/exception/ErrorCode.java @@ -42,6 +42,7 @@ public enum ErrorCode { LONG_EXCEED_LENGTH(HttpStatus.BAD_REQUEST, "800-3", "장문형 최대 글자를 초과하였습니다."), QUESTION_NOT_FOUND(HttpStatus.NOT_FOUND, "800-4", "존재하지 않은 질문입니다."), REQUIRED_QUESTION_MISSING(HttpStatus.BAD_REQUEST, "800-5", "필수 응답 질문이 누락되었습니다."), + ACTIVE_APPLICATION_NOT_FOUND(HttpStatus.NOT_FOUND, "800-6", "활성화된 지원서 양식이 존재하지 않습니다."), AES_CIPHER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "900-1", "암호화 중 오류가 발생했습니다."), APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "지원서가 존재하지 않습니다."), From 11480f566e15a2c30c70c6f386e69c7455fcd3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=95=84?= <143075401+alsdddk@users.noreply.github.com> Date: Wed, 1 Oct 2025 20:58:53 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20active=20null=EA=B0=92=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/payload/request/ClubApplicationFormEditRequest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/moadong/club/payload/request/ClubApplicationFormEditRequest.java b/backend/src/main/java/moadong/club/payload/request/ClubApplicationFormEditRequest.java index c65b4a8e6..4c0182b80 100644 --- a/backend/src/main/java/moadong/club/payload/request/ClubApplicationFormEditRequest.java +++ b/backend/src/main/java/moadong/club/payload/request/ClubApplicationFormEditRequest.java @@ -15,7 +15,8 @@ public record ClubApplicationFormEditRequest( @Size(max = 3000) String description, - boolean active, + @NotNull + Boolean active, @NotNull @Valid From 21e714018f6eec8113bb7290be6ff2883165876a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=95=84?= <143075401+alsdddk@users.noreply.github.com> Date: Thu, 2 Oct 2025 19:28:45 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=EC=84=9C=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20response=EC=97=90=20status=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TODO: status가 null인 경우(마이그레이션X), default로 할 status 결정해야 함 --- .../moadong/club/payload/dto/ClubApplicationFormSlim.java | 2 ++ .../club/payload/dto/ClubApplicationFormsResultItem.java | 5 ++++- .../club/repository/ClubApplicationFormsRepository.java | 2 +- .../repository/ClubApplicationFormsRepositoryCustom.java | 4 +++- .../src/main/java/moadong/club/service/ClubApplyService.java | 4 +++- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormSlim.java b/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormSlim.java index 35031b06e..08f4d1e6e 100644 --- a/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormSlim.java +++ b/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormSlim.java @@ -1,5 +1,6 @@ package moadong.club.payload.dto; +import moadong.club.enums.ApplicationFormStatus; import moadong.club.enums.SemesterTerm; import java.time.LocalDateTime; @@ -10,4 +11,5 @@ public interface ClubApplicationFormSlim { LocalDateTime getEditedAt(); Integer getSemesterYear(); SemesterTerm getSemesterTerm(); + ApplicationFormStatus getStatus(); } diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormsResultItem.java b/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormsResultItem.java index a6accbe32..a1dd9ec25 100644 --- a/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormsResultItem.java +++ b/backend/src/main/java/moadong/club/payload/dto/ClubApplicationFormsResultItem.java @@ -1,9 +1,12 @@ package moadong.club.payload.dto; +import moadong.club.enums.ApplicationFormStatus; + import java.time.LocalDateTime; public record ClubApplicationFormsResultItem( String id, String title, - LocalDateTime editedAt + LocalDateTime editedAt, + ApplicationFormStatus status ) { } diff --git a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java index 06666d3d5..bc3623353 100644 --- a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java +++ b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java @@ -20,7 +20,7 @@ public interface ClubApplicationFormsRepository extends MongoRepository findClubApplicationFormsByClubId(String clubId, Sort sort); diff --git a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepositoryCustom.java b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepositoryCustom.java index a80f1ed5a..844bb4b0d 100644 --- a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepositoryCustom.java +++ b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepositoryCustom.java @@ -29,6 +29,7 @@ public List findClubApplicationFormsByClubId(String .and("_id").as("_id") .and("title").as("title") .and("editedAt").as("editedAt") + .and("status").as("status") .and("semesterYear").as("semesterYear") .and("semesterTerm").as("semesterTerm")); @@ -42,7 +43,8 @@ public List findClubApplicationFormsByClubId(String GroupOperation groupOperation = Aggregation.group("semesterYear","semesterTerm") .push(new Document("_id", "$_id") .append("title", "$title") - .append("editedAt", "$editedAt")) + .append("editedAt", "$editedAt") + .append("status","$status")) .as("forms"); operations.add(groupOperation); diff --git a/backend/src/main/java/moadong/club/service/ClubApplyService.java b/backend/src/main/java/moadong/club/service/ClubApplyService.java index 40a09ad2c..4d453f981 100644 --- a/backend/src/main/java/moadong/club/service/ClubApplyService.java +++ b/backend/src/main/java/moadong/club/service/ClubApplyService.java @@ -155,7 +155,9 @@ public ClubApplicationFormsResponse getGroupedClubApplicationForms(String clubId .add(new ClubApplicationFormsResultItem( s.getId(), s.getTitle(), - editedAt + editedAt, + s.getStatus() + )); } From 1606f63e9ea0fd03ac4d078f35aed41278aac58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=95=84?= <143075401+alsdddk@users.noreply.github.com> Date: Fri, 3 Oct 2025 01:22:19 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20v1=20api=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구버전 호환용 v1 api 제공 --- .../club/controller/ClubApplyController.java | 6 +- .../controller/ClubApplyControllerV1.java | 104 ++++++++++++++++++ .../ClubApplicationFormsRepository.java | 5 + 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/moadong/club/controller/ClubApplyControllerV1.java diff --git a/backend/src/main/java/moadong/club/controller/ClubApplyController.java b/backend/src/main/java/moadong/club/controller/ClubApplyController.java index 07b4e18d0..f4bdc2c5b 100644 --- a/backend/src/main/java/moadong/club/controller/ClubApplyController.java +++ b/backend/src/main/java/moadong/club/controller/ClubApplyController.java @@ -90,11 +90,11 @@ public ResponseEntity applyToClub(@PathVariable String clubId, return Response.ok("success apply"); } - @GetMapping("/apply") + /*@GetMapping("/apply") @Operation(summary = "클럽의 활성화된 지원서 목록 불러오기", description = "클럽의 활성화된 모든 지원서 목록을 불러옵니다") public ResponseEntity getActiveApplicationForms(@PathVariable String clubId) { return Response.ok(clubApplyService.getActiveApplicationForms(clubId)); - } + }*/ @GetMapping("/apply/info/{applicationFormId}") @Operation(summary = "클럽 지원자 현황", description = "클럽 지원자 현황을 불러옵니다") @@ -121,7 +121,7 @@ public ResponseEntity editApplicantDetail(@PathVariable String clubId, return Response.ok("success edit applicant"); } - @DeleteMapping("/applicant/{applicationFormId}") + @DeleteMapping("/applicant/{applicationFormId}") // @Operation(summary = "지원자 삭제", description = "클럽 지원자의 지원서를 삭제합니다" ) diff --git a/backend/src/main/java/moadong/club/controller/ClubApplyControllerV1.java b/backend/src/main/java/moadong/club/controller/ClubApplyControllerV1.java new file mode 100644 index 000000000..e3ca3506e --- /dev/null +++ b/backend/src/main/java/moadong/club/controller/ClubApplyControllerV1.java @@ -0,0 +1,104 @@ +package moadong.club.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import moadong.club.entity.ClubApplicationForm; +import moadong.club.enums.ApplicationFormStatus; +import moadong.club.payload.request.ClubApplicantDeleteRequest; +import moadong.club.payload.request.ClubApplicantEditRequest; +import moadong.club.payload.request.ClubApplyRequest; +import moadong.club.repository.ClubApplicationFormsRepository; +import moadong.club.service.ClubApplyService; +import moadong.global.exception.ErrorCode; +import moadong.global.exception.RestApiException; +import moadong.global.payload.Response; +import moadong.user.annotation.CurrentUser; +import moadong.user.payload.CustomUserDetails; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/club/{clubId}") +@AllArgsConstructor +@Tag(name = "Club_Apply_V1", + description = "클럽 지원서 수정 전 API
" + + "구버전 호환을 위한 임시 API입니다.
" + + "프론트에서 formId 기반 신규 규격으로 전환하기 전까지 clubId 기반 요청을 한시적으로 지원합니다.
" + + "(clubId로 활성화된 최신 지원서 양식의 formId를 가져옴)") +public class ClubApplyControllerV1 { + + private final ClubApplyService clubApplyService; + private final ClubApplicationFormsRepository clubApplicationFormsRepository; + + @GetMapping("/apply") // + @Operation(summary = "클럽 지원서 양식 불러오기", + description = "clubId를 기반으로 활성화된 최신 지원서를 반환합니다.
" + + "
v2 api : /api/club/{clubId}/apply/{applicationFormId}") + public ResponseEntity getClubApplication(@PathVariable String clubId) { + + return clubApplyService.getClubApplicationForm(clubId, convertClubIdToFormId(clubId)); + } + + @PostMapping("/apply") + @Operation(summary = "클럽 지원", description = "clubId를 기반으로 활성화된 최신 지원서에 지원합니다.
" + + "
v2 api : /api/club/{clubId}/apply/{applicationFormId}") + public ResponseEntity applyToClub(@PathVariable String clubId, + @RequestBody @Validated ClubApplyRequest request) { + clubApplyService.applyToClub(clubId, convertClubIdToFormId(clubId), request); + return Response.ok("success apply"); + } + + @GetMapping("/apply/info") + @Operation(summary = "클럽 지원자 현황", description = "clubId를 기반으로 활성화된 최신 지원서의 지원자 현황을 불러옵니다
" + + "
v2 api : /api/club/{clubId}/apply/info/{applicationFormId}") + @PreAuthorize("isAuthenticated()") + @SecurityRequirement(name = "BearerAuth") + public ResponseEntity getApplyInfo(@PathVariable String clubId, + @CurrentUser CustomUserDetails user) { + return Response.ok(clubApplyService.getClubApplyInfo(clubId, convertClubIdToFormId(clubId), user)); + } + + @PutMapping("/applicant") + @Operation(summary = "지원자의 지원서 정보 변경", + description = "여러 지원자의 지원서 정보를 일괄 수정합니다.
" + + "요청 본문은 ClubApplicantEditRequest 객체의 배열이며, 각 원소는 applicantId, memo, status를 포함합니다." + + "

v2 api : /api/club/{clubId}/applicant/{applicationFormId}" + ) + @PreAuthorize("isAuthenticated()") + @SecurityRequirement(name = "BearerAuth") + public ResponseEntity editApplicantDetail(@PathVariable String clubId, + @RequestBody @Valid @NotEmpty List request, + @CurrentUser CustomUserDetails user) { + clubApplyService.editApplicantDetail(clubId, convertClubIdToFormId(clubId), request, user); + return Response.ok("success edit applicant"); + } + + @DeleteMapping("/applicant") + @Operation(summary = "지원자 삭제", + description = "clubId를 기반으로 활성화된 최신 지원서의 지원자의 지원서를 삭제합니다.
" + + "
v2 api : /api/club/{clubId}/applicant/{applicationFormId}" + ) + @PreAuthorize("isAuthenticated()") + @SecurityRequirement(name = "BearerAuth") + public ResponseEntity removeApplicant(@PathVariable String clubId, + @RequestBody @Validated ClubApplicantDeleteRequest request, + @CurrentUser CustomUserDetails user) { + clubApplyService.deleteApplicant(clubId,convertClubIdToFormId(clubId), request, user); + return Response.ok("success delete applicant"); + } + + + private String convertClubIdToFormId(String clubId) { + return clubApplicationFormsRepository.findTopByClubIdAndStatusOrderByEditedAtDesc(clubId, ApplicationFormStatus.ACTIVE) + .map(ClubApplicationForm::getId) + .orElseThrow(() -> new RestApiException(ErrorCode.APPLICATION_NOT_FOUND)); + } +} diff --git a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java index bc3623353..de0459543 100644 --- a/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java +++ b/backend/src/main/java/moadong/club/repository/ClubApplicationFormsRepository.java @@ -4,6 +4,7 @@ import java.util.Optional; import moadong.club.entity.ClubApplicationForm; +import moadong.club.enums.ApplicationFormStatus; import moadong.club.payload.dto.ClubActiveFormSlim; import moadong.club.payload.dto.ClubApplicationFormSlim; import org.springframework.data.domain.Sort; @@ -29,4 +30,8 @@ public interface ClubApplicationFormsRepository extends MongoRepository findClubActiveFormsByClubId(String clubId); + + //clubApply api v1 종료 후 삭제 예정 + Optional findTopByClubIdAndStatusOrderByEditedAtDesc(String clubId, ApplicationFormStatus status); } + From 1258eccc7c14261915cce0a645ced212e80e1443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=95=84?= <143075401+alsdddk@users.noreply.github.com> Date: Sat, 4 Oct 2025 01:31:04 +0900 Subject: [PATCH 5/5] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/moadong/club/controller/ClubApplyController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/moadong/club/controller/ClubApplyController.java b/backend/src/main/java/moadong/club/controller/ClubApplyController.java index f4bdc2c5b..1fa027bfd 100644 --- a/backend/src/main/java/moadong/club/controller/ClubApplyController.java +++ b/backend/src/main/java/moadong/club/controller/ClubApplyController.java @@ -121,7 +121,7 @@ public ResponseEntity editApplicantDetail(@PathVariable String clubId, return Response.ok("success edit applicant"); } - @DeleteMapping("/applicant/{applicationFormId}") // + @DeleteMapping("/applicant/{applicationFormId}") @Operation(summary = "지원자 삭제", description = "클럽 지원자의 지원서를 삭제합니다" )