From 57d02d9735563d679d9f0efc953ea6ccb7e199c2 Mon Sep 17 00:00:00 2001 From: KoSeonJe <127813439+KoSeonJe@users.noreply.github.com> Date: Tue, 4 Feb 2025 04:15:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat=20:=20=EB=8F=99=EC=95=84=EB=A6=AC=20?= =?UTF-8?q?=EC=A7=80=EC=9B=90=20=ED=8F=BC=EC=A7=80=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/{TimeParser.java => TimeUtils.java} | 9 +++++- .../command/CreateActivityReportCommand.java | 6 ++-- .../command/UpdateActivityReportCommand.java | 6 ++-- .../domain/form/api/CentralFormApi.java | 18 +++++++++++ .../controller/CentralFormController.java | 12 +++++++ .../dto/response/FormListResponse.java | 31 +++++++++++++++++++ .../form/repository/FormRepository.java | 3 ++ .../service/FacadeCentralFormService.java | 4 +++ .../service/FacadeCentralFormServiceImpl.java | 19 +++++++++++- .../domain/form/service/FormService.java | 4 +++ .../form/service/GeneralFormService.java | 7 +++++ .../form/service/dto/query/FormListQuery.java | 26 ++++++++++++++++ 12 files changed, 137 insertions(+), 8 deletions(-) rename src/main/java/ddingdong/ddingdongBE/common/utils/{TimeParser.java => TimeUtils.java} (68%) create mode 100644 src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormListResponse.java create mode 100644 src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormListQuery.java diff --git a/src/main/java/ddingdong/ddingdongBE/common/utils/TimeParser.java b/src/main/java/ddingdong/ddingdongBE/common/utils/TimeUtils.java similarity index 68% rename from src/main/java/ddingdong/ddingdongBE/common/utils/TimeParser.java rename to src/main/java/ddingdong/ddingdongBE/common/utils/TimeUtils.java index 5925449e..b5e3b57e 100644 --- a/src/main/java/ddingdong/ddingdongBE/common/utils/TimeParser.java +++ b/src/main/java/ddingdong/ddingdongBE/common/utils/TimeUtils.java @@ -1,9 +1,10 @@ package ddingdong.ddingdongBE.common.utils; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -public class TimeParser { +public class TimeUtils { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm"; @@ -26,4 +27,10 @@ public static LocalDateTime processDate(String dateString, LocalDateTime current return parseToLocalDateTime(dateString); } + + public static boolean isDateInRange(LocalDate nowDate, LocalDate startDate, LocalDate endDate) { + if (nowDate == null || startDate == null || endDate == null) { + return false; + } + return !nowDate.isBefore(startDate) && !nowDate.isAfter(endDate); } } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/CreateActivityReportCommand.java b/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/CreateActivityReportCommand.java index 30db903a..0d419fa2 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/CreateActivityReportCommand.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/CreateActivityReportCommand.java @@ -1,6 +1,6 @@ package ddingdong.ddingdongBE.domain.activityreport.service.dto.command; -import ddingdong.ddingdongBE.common.utils.TimeParser; +import ddingdong.ddingdongBE.common.utils.TimeUtils; import ddingdong.ddingdongBE.domain.activityreport.domain.ActivityReport; import ddingdong.ddingdongBE.domain.activityreport.domain.Participant; import ddingdong.ddingdongBE.domain.club.entity.Club; @@ -23,8 +23,8 @@ public ActivityReport toEntity(Club club) { .term(term) .content(content) .place(place) - .startDate(TimeParser.parseToLocalDateTime(startDate)) - .endDate(TimeParser.parseToLocalDateTime(endDate)) + .startDate(TimeUtils.parseToLocalDateTime(startDate)) + .endDate(TimeUtils.parseToLocalDateTime(endDate)) .participants(participants) .club(club) .build(); diff --git a/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/UpdateActivityReportCommand.java b/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/UpdateActivityReportCommand.java index 436e3896..a7f65186 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/UpdateActivityReportCommand.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/activityreport/service/dto/command/UpdateActivityReportCommand.java @@ -1,6 +1,6 @@ package ddingdong.ddingdongBE.domain.activityreport.service.dto.command; -import ddingdong.ddingdongBE.common.utils.TimeParser; +import ddingdong.ddingdongBE.common.utils.TimeUtils; import ddingdong.ddingdongBE.domain.activityreport.domain.ActivityReport; import ddingdong.ddingdongBE.domain.activityreport.domain.Participant; import java.time.LocalDateTime; @@ -22,8 +22,8 @@ public ActivityReport toEntity() { return ActivityReport.builder() .content(content) .place(place) - .startDate(TimeParser.processDate(startDate, LocalDateTime.now())) - .endDate(TimeParser.processDate(endDate, LocalDateTime.now())) + .startDate(TimeUtils.processDate(startDate, LocalDateTime.now())) + .endDate(TimeUtils.processDate(endDate, LocalDateTime.now())) .participants(participants) .build(); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/api/CentralFormApi.java b/src/main/java/ddingdong/ddingdongBE/domain/form/api/CentralFormApi.java index b1f96759..e159299a 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/api/CentralFormApi.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/api/CentralFormApi.java @@ -3,14 +3,20 @@ import ddingdong.ddingdongBE.auth.PrincipalDetails; import ddingdong.ddingdongBE.domain.form.controller.dto.request.CreateFormRequest; import ddingdong.ddingdongBE.domain.form.controller.dto.request.UpdateFormRequest; +import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormListResponse; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import java.util.List; import org.springframework.http.HttpStatus; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -52,4 +58,16 @@ void deleteForm( @PathVariable("formId") Long formId, @AuthenticationPrincipal PrincipalDetails principalDetails ); + + @Operation(summary = "동아리 지원 폼지 전체조회 API") + @ApiResponse(responseCode = "200", description = "동아리 지원 폼지 전체조회 성공", + content = @Content( + array = @ArraySchema(schema = @Schema(implementation = FormListResponse.class)) + )) + @ResponseStatus(HttpStatus.OK) + @SecurityRequirement(name = "AccessToken") + @GetMapping("/my/forms") + List getAllMyForm( + @AuthenticationPrincipal PrincipalDetails principalDetails + ); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/controller/CentralFormController.java b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/CentralFormController.java index 1d092019..fb66d53d 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/controller/CentralFormController.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/CentralFormController.java @@ -4,8 +4,11 @@ import ddingdong.ddingdongBE.domain.form.api.CentralFormApi; import ddingdong.ddingdongBE.domain.form.controller.dto.request.CreateFormRequest; import ddingdong.ddingdongBE.domain.form.controller.dto.request.UpdateFormRequest; +import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormListResponse; import ddingdong.ddingdongBE.domain.form.service.FacadeCentralFormService; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; import ddingdong.ddingdongBE.domain.user.entity.User; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.RestController; @@ -38,4 +41,13 @@ public void deleteForm(Long formId, PrincipalDetails principalDetails) { User user = principalDetails.getUser(); facadeCentralFormService.deleteForm(formId, user); } + + @Override + public List getAllMyForm(PrincipalDetails principalDetails) { + User user = principalDetails.getUser(); + List queries = facadeCentralFormService.getAllMyForm(user); + return queries.stream() + .map(FormListResponse::from) + .toList(); + } } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormListResponse.java b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormListResponse.java new file mode 100644 index 00000000..21efac08 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/FormListResponse.java @@ -0,0 +1,31 @@ +package ddingdong.ddingdongBE.domain.form.controller.dto.response; + +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDate; +import lombok.Builder; + +@Builder +public record FormListResponse( + @Schema(description = "지원 폼지 ID", example = "1") + Long formId, + @Schema(description = "지원 폼지 제목", example = "폼지 제목입니다.") + String title, + @Schema(description = "지원 폼지 시작일", example = "2001-01-01") + LocalDate startDate, + @Schema(description = "지원 폼지 종료일", example = "2001-01-02") + LocalDate endData, + @Schema(description = "활성화 여부", example = "true") + boolean isActive +) { + + public static FormListResponse from(FormListQuery query) { + return FormListResponse.builder() + .formId(query.formId()) + .title(query.title()) + .startDate(query.startDate()) + .endData(query.endData()) + .isActive(query.isActive()) + .build(); + } +} diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/repository/FormRepository.java b/src/main/java/ddingdong/ddingdongBE/domain/form/repository/FormRepository.java index 8ea4bdf5..908d4eb2 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/repository/FormRepository.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/repository/FormRepository.java @@ -1,8 +1,11 @@ package ddingdong.ddingdongBE.domain.form.repository; +import ddingdong.ddingdongBE.domain.club.entity.Club; import ddingdong.ddingdongBE.domain.form.entity.Form; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface FormRepository extends JpaRepository { + List
findAllByClub(Club club); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormService.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormService.java index c03fe600..af59fa8d 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormService.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormService.java @@ -2,7 +2,9 @@ import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand; import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; import ddingdong.ddingdongBE.domain.user.entity.User; +import java.util.List; public interface FacadeCentralFormService { @@ -11,4 +13,6 @@ public interface FacadeCentralFormService { void updateForm(UpdateFormCommand command); void deleteForm(Long formId, User user); + + List getAllMyForm(User user); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java index 3b05f7d7..3e9b72ec 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java @@ -1,6 +1,7 @@ package ddingdong.ddingdongBE.domain.form.service; 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.form.entity.Form; @@ -9,7 +10,9 @@ import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand.CreateFormFieldCommand; import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand; import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand.UpdateFormFieldCommand; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; import ddingdong.ddingdongBE.domain.user.entity.User; +import java.time.LocalDate; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -19,7 +22,7 @@ @Service @RequiredArgsConstructor @Transactional(readOnly = true) -public class FacadeCentralFormServiceImpl implements FacadeCentralFormService{ +public class FacadeCentralFormServiceImpl implements FacadeCentralFormService { private final FormService formService; private final FormFieldService formFieldService; @@ -59,6 +62,20 @@ public void deleteForm(Long formId, User user) { formService.delete(form); //테이블 생성 시 외래 키에 cascade 설정하여 formField 삭제도 자동으로 됨. } + @Override + public List getAllMyForm(User user) { + Club club = clubService.getByUserId(user.getId()); + List forms = formService.getAllByClub(club); + return forms.stream() + .map(this::buildFormListQuery) + .toList(); + } + + private FormListQuery buildFormListQuery(Form form) { + boolean isActive = TimeUtils.isDateInRange(LocalDate.now(), form.getStartDate(), form.getEndDate()); + return FormListQuery.from(form, isActive); + } + private void validateEqualsClub(Club club, Form form) { if (!Objects.equals(club.getId(), form.getClub().getId())) { throw new NonHaveAuthority(); diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormService.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormService.java index 246b577b..96ca4ace 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormService.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/FormService.java @@ -1,6 +1,8 @@ package ddingdong.ddingdongBE.domain.form.service; +import ddingdong.ddingdongBE.domain.club.entity.Club; import ddingdong.ddingdongBE.domain.form.entity.Form; +import java.util.List; public interface FormService { @@ -9,4 +11,6 @@ public interface FormService { Form getById(Long formId); void delete(Form form); + + List getAllByClub(Club club); } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormService.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormService.java index fd30c51f..9f4e52ef 100644 --- a/src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormService.java +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/GeneralFormService.java @@ -1,8 +1,10 @@ package ddingdong.ddingdongBE.domain.form.service; import ddingdong.ddingdongBE.common.exception.PersistenceException.ResourceNotFound; +import ddingdong.ddingdongBE.domain.club.entity.Club; import ddingdong.ddingdongBE.domain.form.entity.Form; import ddingdong.ddingdongBE.domain.form.repository.FormRepository; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,4 +33,9 @@ public Form getById(Long formId) { public void delete(Form form) { formRepository.delete(form); } + + @Override + public List getAllByClub(Club club) { + return formRepository.findAllByClub(club); + } } diff --git a/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormListQuery.java b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormListQuery.java new file mode 100644 index 00000000..750b4f82 --- /dev/null +++ b/src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/FormListQuery.java @@ -0,0 +1,26 @@ +package ddingdong.ddingdongBE.domain.form.service.dto.query; + +import ddingdong.ddingdongBE.domain.form.entity.Form; +import java.time.LocalDate; +import lombok.Builder; + +@Builder +public record FormListQuery( + Long formId, + String title, + LocalDate startDate, + LocalDate endData, + boolean isActive +) { + + public static FormListQuery from(Form form, boolean isActive) { + return FormListQuery.builder() + .formId(form.getId()) + .title(form.getTitle()) + .startDate(form.getStartDate()) + .endData(form.getEndDate()) + .isActive(isActive) + .build(); + } + +} From 880958e7d3ef05e2c22c76619840af0136151d1e Mon Sep 17 00:00:00 2001 From: KoSeonJe <127813439+KoSeonJe@users.noreply.github.com> Date: Tue, 4 Feb 2025 04:34:38 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test=20:=20=EB=8F=99=EC=95=84=EB=A6=AC=20?= =?UTF-8?q?=EC=A7=80=EC=9B=90=20=ED=8F=BC=EC=A7=80=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/utils/TimeUtilsTest.java | 22 ++++++++++ .../FacadeCentralFormServiceImplTest.java | 40 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/test/java/ddingdong/ddingdongBE/common/utils/TimeUtilsTest.java diff --git a/src/test/java/ddingdong/ddingdongBE/common/utils/TimeUtilsTest.java b/src/test/java/ddingdong/ddingdongBE/common/utils/TimeUtilsTest.java new file mode 100644 index 00000000..2ba709bc --- /dev/null +++ b/src/test/java/ddingdong/ddingdongBE/common/utils/TimeUtilsTest.java @@ -0,0 +1,22 @@ +package ddingdong.ddingdongBE.common.utils; + +import java.time.LocalDate; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class TimeUtilsTest { + + @DisplayName("현재 날짜가 기간 내 포함된다면 true를 반환한다.") + @Test + void isDateInRange() { + // given + LocalDate now = LocalDate.now(); + LocalDate startDate = now.minusDays(1); + LocalDate endDate = now.plusDays(1); + // when + boolean isActive = TimeUtils.isDateInRange(now, startDate, endDate); + // then + Assertions.assertThat(isActive).isTrue(); + } +} diff --git a/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImplTest.java b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImplTest.java index 52c5f8ff..71635db4 100644 --- a/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImplTest.java +++ b/src/test/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImplTest.java @@ -16,6 +16,7 @@ import ddingdong.ddingdongBE.domain.form.service.dto.command.CreateFormCommand; import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand; import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand.UpdateFormFieldCommand; +import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery; import ddingdong.ddingdongBE.domain.user.entity.Role; import ddingdong.ddingdongBE.domain.user.entity.User; import ddingdong.ddingdongBE.domain.user.repository.UserRepository; @@ -207,4 +208,43 @@ void validateEqualsClub() { facadeCentralFormService.deleteForm(savedForm.getId(), user2); }); } + + @DisplayName("동아리는 자신의 폼지를 전부 조회할 수 있다.") + @Test + void getAllMyForm() { + // given + User user = fixtureMonkey.giveMeBuilder(User.class) + .set("id", 1L) + .set("Role", Role.CLUB) + .set("deletedAt", null) + .sample(); + User savedUser = userRepository.save(user); + Club club = fixtureMonkey.giveMeBuilder(Club.class) + .set("id", 1L) + .set("user", savedUser) + .set("score", null) + .set("clubMembers", null) + .set("deletedAt", null) + .sample(); + clubRepository.save(club); + Form form = fixtureMonkey.giveMeBuilder(Form.class) + .set("title", "제목1") + .set("club", club) + .sample(); + Form form2 = fixtureMonkey.giveMeBuilder(Form.class) + .set("title", "제목2") + .set("club", club) + .sample(); + formService.create(form); + formService.create(form2); + + // when + List queries = facadeCentralFormService.getAllMyForm(savedUser); + // then + assertThat(queries).isNotEmpty(); + assertThat(queries.size()).isEqualTo(2); + assertThat(queries.get(0).title()).isEqualTo("제목1"); + assertThat(queries.get(1).title()).isEqualTo("제목2"); + + } }