Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import moadong.club.entity.ClubApplication;
import moadong.club.payload.request.ClubApplicantEditRequest;
import moadong.club.payload.request.ClubApplicationCreateRequest;
import moadong.club.payload.request.ClubApplicationEditRequest;
import moadong.club.payload.request.ClubApplyRequest;
import moadong.club.payload.response.ClubApplicationResponse;
import moadong.club.service.ClubApplyService;
import moadong.global.payload.Response;
import moadong.user.annotation.CurrentUser;
Expand All @@ -18,8 +17,6 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/club/{clubId}")
@AllArgsConstructor
Expand Down Expand Up @@ -73,4 +70,19 @@ public ResponseEntity<?> getApplyInfo(@PathVariable String clubId,
return Response.ok(clubApplyService.getClubApplyInfo(clubId, user));
}

@PutMapping("/apply/{appId}")
@Operation(summary = "지원서 변경",
description = "클럽 자원자의 지원서 정보를 수정합니다.<br>"
+ "appId - 지원서 아이디"
)
@PreAuthorize("isAuthenticated()")
@SecurityRequirement(name = "BearerAuth")
public ResponseEntity<?> editApplicantDetail(@PathVariable String clubId,
@PathVariable String appId,
@RequestBody @Validated ClubApplicantEditRequest request,
@CurrentUser CustomUserDetails user) {
clubApplyService.editApplicantDetail(clubId, appId, request, user);
return Response.ok("success edit applicant");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ public class ClubApplication {
@Builder.Default
ApplicationStatus status = ApplicationStatus.SUBMITTED;

@Builder.Default
private String memo = "";

@Builder.Default
private List<ClubQuestionAnswer> answers = new ArrayList<>();

@Builder.Default
LocalDateTime createdAt = ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime();

public void updateDetail(String memo, ApplicationStatus status) {
this.memo = memo;
this.status = status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
import moadong.global.exception.RestApiException;
import moadong.global.util.AESCipher;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Builder
@Slf4j
public record ClubApplicantsResult(
String questionId,
String id,
ApplicationStatus status,
List<ClubQuestionAnswer> answers
List<ClubQuestionAnswer> answers,
LocalDateTime createdAt
) {
public static ClubApplicantsResult of(ClubApplication application, AESCipher cipher) {
List<ClubQuestionAnswer> decryptedAnswers = new ArrayList<>();
Expand All @@ -35,9 +37,10 @@ public static ClubApplicantsResult of(ClubApplication application, AESCipher cip
}

return ClubApplicantsResult.builder()
.questionId(application.getQuestionId())
.id(application.getId())
.status(application.getStatus())
.answers(decryptedAnswers)
.createdAt(application.getCreatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package moadong.club.payload.request;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import moadong.club.enums.ApplicationStatus;

public record ClubApplicantEditRequest(
@NotNull
@Size(max = 500)
String memo,

ApplicationStatus status
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
import org.springframework.data.mongodb.repository.Query;

import java.util.List;
import java.util.Optional;

public interface ClubApplicationRepository extends MongoRepository<ClubApplication, String> {
@Query("{ 'questionId': ?0, 'status': { $exists: true, $ne: 'DRAFT' } }")
List<ClubApplication> findAllByQuestionId(String questionId);

Optional<ClubApplication> findByIdAndQuestionId(String id, String questionId);
}
19 changes: 19 additions & 0 deletions backend/src/main/java/moadong/club/service/ClubApplyService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package moadong.club.service;

import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import moadong.club.entity.*;
import moadong.club.enums.ClubApplicationQuestionType;
import moadong.club.payload.dto.ClubApplicantsResult;
import moadong.club.payload.request.ClubApplicantEditRequest;
import moadong.club.payload.request.ClubApplicationCreateRequest;
import moadong.club.payload.request.ClubApplicationEditRequest;
import moadong.club.payload.request.ClubApplyRequest;
Expand Down Expand Up @@ -123,6 +125,23 @@ public ClubApplyInfoResponse getClubApplyInfo(String clubId, CustomUserDetails u
.build();
}

@Transactional
public void editApplicantDetail(String clubId, String appId, ClubApplicantEditRequest request, CustomUserDetails user) {
Club club = clubRepository.findById(clubId)
.orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));

if (!user.getId().equals(club.getUserId())) {
throw new RestApiException(ErrorCode.USER_UNAUTHORIZED);
}

ClubApplication application = clubApplicationRepository.findByIdAndQuestionId(appId, clubId)
.orElseThrow(() -> new RestApiException(ErrorCode.APPLICANT_NOT_FOUND));

application.updateDetail(request.memo(), request.status());

clubApplicationRepository.save(application);
}

private void validateAnswers(List<ClubApplyRequest.Answer> answers, ClubQuestion clubQuestion) {
// 미리 질문과 응답 id 만들어두기
Map<Long, ClubApplicationQuestion> questionMap = clubQuestion.getQuestions().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public enum ErrorCode {
QUESTION_NOT_FOUND(HttpStatus.NOT_FOUND, "800-4", "존재하지 않은 질문입니다."),
REQUIRED_QUESTION_MISSING(HttpStatus.BAD_REQUEST, "800-5", "필수 응답 질문이 누락되었습니다."),

AES_CIPHER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "900-1", "암호화 중 오류가 발생했습니다.")
AES_CIPHER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "900-1", "암호화 중 오류가 발생했습니다."),
APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "지원서가 존재하지 않습니다."),
Comment on lines +42 to +43
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

기존 에러코드와 메시지가 중복됩니다.

36번째 줄의 APPLICATION_NOT_FOUND와 새로운 APPLICANT_NOT_FOUND가 동일한 메시지 "지원서가 존재하지 않습니다."를 사용하고 있습니다. 두 에러코드의 용도가 다르다면 메시지를 구별하여 명확성을 높이는 것이 좋겠습니다.

예시:

-    APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "지원서가 존재하지 않습니다."),
+    APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "해당 지원자를 찾을 수 없습니다."),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
AES_CIPHER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "900-1", "암호화 중 오류가 발생했습니다."),
APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "지원서가 존재하지 않습니다."),
AES_CIPHER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "900-1", "암호화 중 오류가 발생했습니다."),
APPLICANT_NOT_FOUND(HttpStatus.NOT_FOUND, "900-2", "해당 지원자를 찾을 수 없습니다."),
🤖 Prompt for AI Agents
In backend/src/main/java/moadong/global/exception/ErrorCode.java around lines 42
to 43, the error message for APPLICANT_NOT_FOUND duplicates the message used by
APPLICATION_NOT_FOUND on line 36. To improve clarity, update the
APPLICANT_NOT_FOUND message to be distinct and reflect its specific context,
ensuring each error code has a unique and clear message.

;

private final HttpStatus httpStatus;
Expand Down
Loading