diff --git a/.github/workflows/issue-branch-pr-automation.yml b/.github/workflows/issue-branch-pr-automation.yml index 5122e465c..0b9ab9379 100644 --- a/.github/workflows/issue-branch-pr-automation.yml +++ b/.github/workflows/issue-branch-pr-automation.yml @@ -2,17 +2,7 @@ name: ALL/PM - Issue 자동 관리 on: issues: - types: [opened, assigned, closed] - -env: - Dobby-Kim: "U07BJABU6G1" - Chocochip101: "U07BUEJDS8G" - xogns1514: "U07AZ26UC2J" - lurgi: "U07BJB1M53K" - llqqssttyy: "U07AZ2992CW" - cutehumanS2: "U07B88ZQDU4" - HyungHoKim00: "U07B5HBKZM1" - seongjinme: "U07B9HQDF4M" + types: [assigned, closed] jobs: create-issue-branch: @@ -21,7 +11,7 @@ jobs: if: github.event.action == 'assigned' steps: - name: create the issue branch - uses: robvanderleek/create-issue-branch@main + uses: robvanderleek/create-issue-branch@1.7.0 id: create-issue-branch env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -34,15 +24,15 @@ jobs: - name: Set assignee variables id: set-vars run: | - echo "ASSIGNEE_SLACK_ID=${{ env[github.event.issue.assignee.login] }}" >> $GITHUB_ENV - + ASSIGNEE_LOGIN=${{ github.event.issue.assignee.login }} + echo "ASSIGNEE_SLACK_ID=${ASSIGNEE_LOGIN@L}" >> ${GITHUB_ENV} - name: 작업 시작 -> Slack 체널 알림 uses: slackapi/slack-github-action@v1.26.0 with: channel-id: ${{ secrets.IN_PROGRESS_SLACK_CHANNEL_ID }} payload: | { - "text": "pr review request", + "text": "🔔 작업 시작 알림 🔔", "blocks": [ { "type": "section", @@ -55,7 +45,7 @@ jobs: } env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - + notify-close-issue: name: "이슈 작업 종료 -> Slack 체널 알림" runs-on: ubuntu-latest @@ -64,15 +54,16 @@ jobs: - name: Set assignee variables id: set-vars run: | - echo "ASSIGNEE_SLACK_ID=${{ env[github.event.issue.assignee.login] }}" >> $GITHUB_ENV - + ASSIGNEE_LOGIN=${{ github.event.issue.assignee.login }} + echo "ASSIGNEE_SLACK_ID=${ASSIGNEE_LOGIN@L}" >> ${GITHUB_ENV} + - name: 작업 시작 -> Slack 체널 알림 uses: slackapi/slack-github-action@v1.26.0 with: channel-id: ${{ secrets.TASK_COMPLETE_SLACK_CHANNEL_ID }} payload: | { - "text": "pr review request", + "text": "🎉 작업 완료 알림 🎉", "blocks": [ { "type": "section", diff --git a/README.md b/README.md new file mode 100644 index 000000000..0f041c577 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# 서비스 이름 + +### 크루루 (cruru) + +# 크루루는 이런 서비스에요 + +## 주제 + +복잡한 리크루팅 과정을 간소화하는 맞춤형 리크루팅 관리 솔루션 + +## 설명 + +서비스 ‘크루루’는 대학생 연합 동아리를 위한 ATS(지원자 추적 시스템)입니다. 모집 공고 관리, 지원자 목록 관리, 지원 항목 커스터마이징 등을 제공합니다. 해당 서비스를 통해 소규모 리크루팅 프로세스를 효율적으로 관리할 수 있습니다. + +# 💻 개발자 + +| ![아르](https://github.com/user-attachments/assets/2f63c5ab-43bb-417b-92bf-73fd761208a9) | ![러기](https://github.com/user-attachments/assets/f2c8ff64-1a83-466c-851a-ab14cd5530bc)| ![렛서](https://github.com/user-attachments/assets/ff5d9e17-16d6-42fc-8754-c65554313e4e) | ![냥인](https://github.com/user-attachments/assets/4b20cc25-7104-413c-b89e-f22c34a8d0c9) | ![러쉬](https://github.com/user-attachments/assets/86225998-321c-4a11-9c30-2abff1b1c3a1) | ![명오](https://github.com/user-attachments/assets/5316b64b-bc98-446b-b55f-8fa014dbceaa) | ![도비](https://github.com/user-attachments/assets/777f53ac-07cf-43e3-8ebb-f11ae1dc8520) | ![초코칩](https://github.com/user-attachments/assets/dcbd7b64-0ee9-434e-936e-98bf4a36a03d) | +|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:| +| **FE** | **FE** | **FE** | **BE** | **BE** | **BE** | **BE** | **BE** | +|[아르](https://github.com/seongjinme)| [러기](https://github.com/lurgi) | [렛서](https://github.com/llqqssttyy) | [냥인](https://github.com/cutehumanS2) | [러쉬](https://github.com/xogns1514) | [명오](https://github.com/HyungHoKim00) | [도비](https://github.com/Dobby-Kim) | [초코칩](https://github.com/Chocochip101) | diff --git a/backend/src/docs/asciidoc/applyform.adoc b/backend/src/docs/asciidoc/applyform.adoc index 1ae9a27c2..4b8174ea5 100644 --- a/backend/src/docs/asciidoc/applyform.adoc +++ b/backend/src/docs/asciidoc/applyform.adoc @@ -34,6 +34,10 @@ operation::applicant/submit-fail/applyform-not-found[snippets="http-request,path operation::applicant/submit-fail/question-not-found[snippets="http-request,path-parameters,request-fields,http-response"] +==== 실패: 필수 질문에 응답하지 않음 + +operation::applicant/submit-fail/required-not-replied[snippets="http-request,path-parameters,request-fields,http-response"] + === 지원폼 조회 ==== 성공 diff --git a/backend/src/main/java/com/cruru/applyform/facade/ApplyFormFacade.java b/backend/src/main/java/com/cruru/applyform/facade/ApplyFormFacade.java index 862f50eb1..dc1c2ad1d 100644 --- a/backend/src/main/java/com/cruru/applyform/facade/ApplyFormFacade.java +++ b/backend/src/main/java/com/cruru/applyform/facade/ApplyFormFacade.java @@ -20,6 +20,7 @@ import java.time.Clock; import java.time.LocalDate; import java.util.List; +import java.util.Objects; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,9 +62,11 @@ public void submit(long applyFormId, ApplyFormSubmitRequest request) { Applicant applicant = applicantService.create(applicantCreateRequest, firstProcess); List answerCreateRequests = request.answerCreateRequest(); - for (AnswerCreateRequest answerCreateRequest : answerCreateRequests) { - Question targetQuestion = questionService.findById(answerCreateRequest.questionId()); - answerService.saveAnswerReplies(answerCreateRequest, targetQuestion, applicant); + List questions = questionService.findByApplyForm(applyForm); + + for (Question question : questions) { + AnswerCreateRequest answerCreateRequest = getAnswerCreateRequest(question, answerCreateRequests); + answerService.saveAnswerReplies(answerCreateRequest, question, applicant); } } @@ -83,6 +86,16 @@ private void validateSubmitDate(ApplyForm applyForm) { } } + private AnswerCreateRequest getAnswerCreateRequest( + Question question, + List answerCreateRequests + ) { + return answerCreateRequests.stream() + .filter(answerCreateRequest -> Objects.equals(answerCreateRequest.questionId(), question.getId())) + .findAny() + .orElseGet(() -> new AnswerCreateRequest(question.getId(), List.of())); + } + @Transactional public void update(ApplyFormWriteRequest request, long applyFormId) { ApplyForm applyForm = applyFormService.findById(applyFormId); diff --git a/backend/src/test/java/com/cruru/applyform/controller/ApplyFormControllerTest.java b/backend/src/test/java/com/cruru/applyform/controller/ApplyFormControllerTest.java index 1e02677ee..ee921be5b 100644 --- a/backend/src/test/java/com/cruru/applyform/controller/ApplyFormControllerTest.java +++ b/backend/src/test/java/com/cruru/applyform/controller/ApplyFormControllerTest.java @@ -349,6 +349,33 @@ void submit_questionNotFound() { .then().log().all().statusCode(400); } + @DisplayName("지원서 폼 제출 시, 필수 질문에 응답하지 않은 경우 400를 반환한다.") + @Test + void submit_RequiredNotReplied() { + // given + Dashboard dashboard = dashboardRepository.save(DashboardFixture.backend()); + processRepository.save(ProcessFixture.applyType(dashboard)); + ApplyForm applyForm = applyFormRepository.save(ApplyFormFixture.backend(dashboard)); + questionRepository.save(QuestionFixture.required(applyForm)); + + ApplyFormSubmitRequest request = new ApplyFormSubmitRequest( + new ApplicantCreateRequest("초코칩", "dev.chocochip@gmail.com", "01000000000"), + List.of(), + true + ); + + // when&then + RestAssured.given(spec).log().all() + .contentType(ContentType.JSON) + .body(request) + .filter(document("applicant/submit-fail/required-not-replied", + pathParameters(parameterWithName("applyFormId").description("지원폼의 id")), + requestFields(APPLICANT_SUBMIT_FIELD_DESCRIPTORS) + )) + .when().post("/v1/applyform/{applyFormId}/submit", applyForm.getId()) + .then().log().all().statusCode(400); + } + @DisplayName("지원서 폼 조회 시, 200을 반환한다.") @Test void read() {