diff --git a/backend/src/main/java/moadong/club/entity/Club.java b/backend/src/main/java/moadong/club/entity/Club.java index a53465446..60441a058 100644 --- a/backend/src/main/java/moadong/club/entity/Club.java +++ b/backend/src/main/java/moadong/club/entity/Club.java @@ -46,9 +46,8 @@ public class Club implements Persistable { @Field("recruitmentInformation") private ClubRecruitmentInformation clubRecruitmentInformation; - private String description; - - private List faqs; + @Field("description") + private ClubDescription clubDescription; @Version private Long version; @@ -58,6 +57,7 @@ public Club() { this.division = ""; this.state = ClubState.UNAVAILABLE; this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build(); + this.clubDescription = ClubDescription.builder().build(); } public Club(String userId) { @@ -67,6 +67,7 @@ public Club(String userId) { this.state = ClubState.UNAVAILABLE; this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build(); this.userId = userId; + this.clubDescription = ClubDescription.builder().build(); } public Club(String id, String userId) { @@ -77,6 +78,7 @@ public Club(String id, String userId) { this.state = ClubState.UNAVAILABLE; this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build(); this.userId = userId; + this.clubDescription = ClubDescription.builder().build(); } @Builder @@ -86,6 +88,7 @@ public Club(String name, String category, String division, this.category = category; this.division = division; this.clubRecruitmentInformation = clubRecruitmentInformation; + this.clubDescription = ClubDescription.builder().build(); } public void update(ClubInfoRequest request) { @@ -98,8 +101,7 @@ public void update(ClubInfoRequest request) { this.state = ClubState.AVAILABLE; this.socialLinks = request.socialLinks(); this.clubRecruitmentInformation.update(request); - this.description = request.description(); - this.faqs = request.faqs(); + this.clubDescription = request.description().toEntity(); } private void validateTags(List tags) { diff --git a/backend/src/main/java/moadong/club/entity/ClubAward.java b/backend/src/main/java/moadong/club/entity/ClubAward.java new file mode 100644 index 000000000..99a8c2893 --- /dev/null +++ b/backend/src/main/java/moadong/club/entity/ClubAward.java @@ -0,0 +1,19 @@ +package moadong.club.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ClubAward { + + private String semester; + + private List achievements; +} diff --git a/backend/src/main/java/moadong/club/entity/ClubDescription.java b/backend/src/main/java/moadong/club/entity/ClubDescription.java new file mode 100644 index 000000000..caa22e009 --- /dev/null +++ b/backend/src/main/java/moadong/club/entity/ClubDescription.java @@ -0,0 +1,27 @@ +package moadong.club.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ClubDescription { + + private String introDescription; + + private String activityDescription; + + private List awards; + + private ClubIdealCandidate idealCandidate; + + private String benefits; + + private List faqs; +} diff --git a/backend/src/main/java/moadong/club/entity/ClubIdealCandidate.java b/backend/src/main/java/moadong/club/entity/ClubIdealCandidate.java new file mode 100644 index 000000000..ba3bfcdf5 --- /dev/null +++ b/backend/src/main/java/moadong/club/entity/ClubIdealCandidate.java @@ -0,0 +1,19 @@ +package moadong.club.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ClubIdealCandidate { + + private List tags; + + private String content; +} diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubAwardDto.java b/backend/src/main/java/moadong/club/payload/dto/ClubAwardDto.java new file mode 100644 index 000000000..ef793e595 --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/ClubAwardDto.java @@ -0,0 +1,25 @@ +package moadong.club.payload.dto; + +import jakarta.validation.constraints.Size; +import moadong.club.entity.ClubAward; + +import java.util.List; + +public record ClubAwardDto( + @Size(max = 50) + String semester, + + List<@Size(max = 100) String> achievements +) { + public static ClubAwardDto from(ClubAward clubAward) { + if (clubAward == null) return null; + return new ClubAwardDto(clubAward.getSemester(), clubAward.getAchievements()); + } + + public ClubAward toEntity() { + return ClubAward.builder() + .semester(semester) + .achievements(achievements) + .build(); + } +} diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubDescriptionDto.java b/backend/src/main/java/moadong/club/payload/dto/ClubDescriptionDto.java new file mode 100644 index 000000000..9f1b836b3 --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/ClubDescriptionDto.java @@ -0,0 +1,50 @@ +package moadong.club.payload.dto; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import moadong.club.entity.ClubDescription; + +import java.util.List; + +public record ClubDescriptionDto( + @Size(max = 500) + String introDescription, + + @Size(max = 1000) + String activityDescription, + + @Valid + List awards, + + @Valid + ClubIdealCandidateDto idealCandidate, + + @Size(max = 1000) + String benefits, + + @Valid + List faqs +) { + public static ClubDescriptionDto from(ClubDescription description) { + if (description == null) return null; + return new ClubDescriptionDto( + description.getIntroDescription(), + description.getActivityDescription(), + description.getAwards() == null ? null : description.getAwards().stream().map(ClubAwardDto::from).toList(), + ClubIdealCandidateDto.from(description.getIdealCandidate()), + description.getBenefits(), + description.getFaqs() == null ? null : description.getFaqs().stream().map(FaqDto::from).toList() + ); + } + + public ClubDescription toEntity() { + return ClubDescription.builder() + .introDescription(introDescription) + .activityDescription(activityDescription) + .awards(awards == null ? null : awards.stream().map(ClubAwardDto::toEntity).toList()) + .idealCandidate(idealCandidate == null ? null : idealCandidate.toEntity()) + .benefits(benefits) + .faqs(faqs == null ? null : faqs.stream().map(FaqDto::toEntity).toList()) + .build(); + } +} diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java b/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java index b00d995f4..e46c7e1cf 100644 --- a/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java +++ b/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java @@ -3,7 +3,6 @@ import lombok.Builder; import moadong.club.entity.Club; import moadong.club.entity.ClubRecruitmentInformation; -import moadong.club.entity.Faq; import java.time.format.DateTimeFormatter; import java.util.List; @@ -19,7 +18,7 @@ public record ClubDetailedResult( String state, List feeds, String introduction, - String description, + ClubDescriptionDto description, String presidentName, String presidentPhoneNumber, String recruitmentStart, @@ -30,7 +29,6 @@ public record ClubDetailedResult( Map socialLinks, String category, String division, - List faqs, String lastModifiedDate ) { @@ -66,8 +64,7 @@ public static ClubDetailedResult of(Club club) { .division(club.getDivision() == null ? "" : club.getDivision()) .introduction(clubRecruitmentInformation.getIntroduction() == null ? "" : clubRecruitmentInformation.getIntroduction()) - .description(club.getDescription() == null ? "" - : club.getDescription()) + .description(ClubDescriptionDto.from(club.getClubDescription())) .presidentName(clubRecruitmentInformation.getPresidentName() == null ? "" : clubRecruitmentInformation.getPresidentName()) .presidentPhoneNumber( @@ -83,8 +80,6 @@ public static ClubDetailedResult of(Club club) { club.getClubRecruitmentInformation().getExternalApplicationUrl()) .socialLinks(club.getSocialLinks() == null ? Map.of() : club.getSocialLinks()) - .faqs(club.getFaqs() == null ? List.of() - : club.getFaqs()) .lastModifiedDate(lastModifiedDate) .build(); } diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubIdealCandidateDto.java b/backend/src/main/java/moadong/club/payload/dto/ClubIdealCandidateDto.java new file mode 100644 index 000000000..87e00d6ce --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/ClubIdealCandidateDto.java @@ -0,0 +1,25 @@ +package moadong.club.payload.dto; + +import jakarta.validation.constraints.Size; +import moadong.club.entity.ClubIdealCandidate; + +import java.util.List; + +public record ClubIdealCandidateDto( + List<@Size(max = 10) String> tags, + + @Size(max = 700) + String content +) { + public static ClubIdealCandidateDto from(ClubIdealCandidate candidate) { + if (candidate == null) return null; + return new ClubIdealCandidateDto(candidate.getTags(), candidate.getContent()); + } + + public ClubIdealCandidate toEntity() { + return ClubIdealCandidate.builder() + .tags(tags) + .content(content) + .build(); + } +} diff --git a/backend/src/main/java/moadong/club/payload/dto/FaqDto.java b/backend/src/main/java/moadong/club/payload/dto/FaqDto.java new file mode 100644 index 000000000..9bec92497 --- /dev/null +++ b/backend/src/main/java/moadong/club/payload/dto/FaqDto.java @@ -0,0 +1,21 @@ +package moadong.club.payload.dto; + +import jakarta.validation.constraints.Size; +import moadong.club.entity.Faq; + +public record FaqDto( + @Size(max = 100) + String question, + + @Size(max = 500) + String answer +) { + public static FaqDto from(Faq faq) { + if (faq == null) return null; + return new FaqDto(faq.getQuestion(), faq.getAnswer()); + } + + public Faq toEntity() { + return new Faq(question, answer); + } +} diff --git a/backend/src/main/java/moadong/club/payload/request/ClubInfoRequest.java b/backend/src/main/java/moadong/club/payload/request/ClubInfoRequest.java index 4659311f1..24e481886 100644 --- a/backend/src/main/java/moadong/club/payload/request/ClubInfoRequest.java +++ b/backend/src/main/java/moadong/club/payload/request/ClubInfoRequest.java @@ -1,14 +1,14 @@ package moadong.club.payload.request; import jakarta.validation.constraints.NotBlank; -import java.util.List; -import java.util.Map; - -import moadong.club.entity.Faq; +import moadong.club.payload.dto.ClubDescriptionDto; import moadong.club.enums.ClubCategory; import moadong.club.enums.ClubDivision; import moadong.global.annotation.PhoneNumber; +import java.util.List; +import java.util.Map; + public record ClubInfoRequest( @NotBlank String name, @@ -17,8 +17,7 @@ public record ClubInfoRequest( List tags, String introduction, String presidentName, - String description, - List faqs, + ClubDescriptionDto description, @PhoneNumber String presidentPhoneNumber, Map socialLinks diff --git a/backend/src/test/java/moadong/fixture/ClubFixture.java b/backend/src/test/java/moadong/fixture/ClubFixture.java index d071b24fd..0049a3bba 100644 --- a/backend/src/test/java/moadong/fixture/ClubFixture.java +++ b/backend/src/test/java/moadong/fixture/ClubFixture.java @@ -23,7 +23,6 @@ public static ClubRecruitmentInformation createRecruitmentInfo( String id, String logo, String introduction, - String description, String presidentName, String presidentTelephoneNumber, LocalDateTime recruitmentStart, @@ -34,7 +33,6 @@ public static ClubRecruitmentInformation createRecruitmentInfo( when(clubRecruitmentInfo.getId()).thenReturn(id); when(clubRecruitmentInfo.getLogo()).thenReturn(logo); when(clubRecruitmentInfo.getIntroduction()).thenReturn(introduction); - when(clubRecruitmentInfo.getDescription()).thenReturn(description); when(clubRecruitmentInfo.getPresidentName()).thenReturn(presidentName); when(clubRecruitmentInfo.getPresidentTelephoneNumber()).thenReturn(presidentTelephoneNumber); when(clubRecruitmentInfo.getRecruitmentStart()).thenReturn(ZonedDateTime.from(recruitmentStart)); diff --git a/backend/src/test/java/moadong/fixture/ClubRequestFixture.java b/backend/src/test/java/moadong/fixture/ClubRequestFixture.java index 7d830f384..2761d8866 100644 --- a/backend/src/test/java/moadong/fixture/ClubRequestFixture.java +++ b/backend/src/test/java/moadong/fixture/ClubRequestFixture.java @@ -1,12 +1,13 @@ package moadong.fixture; +import moadong.club.entity.ClubDescription; import moadong.club.enums.ClubCategory; import moadong.club.enums.ClubDivision; +import moadong.club.payload.dto.ClubDescriptionDto; import moadong.club.payload.request.ClubInfoRequest; import moadong.club.payload.request.ClubRecruitmentInfoUpdateRequest; import java.time.Instant; -import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Map; @@ -20,6 +21,7 @@ public static ClubInfoRequest createValidClubInfoRequest() { List.of("개발", "스터디"), "동아리 소개입니다.", "홍길동", + ClubDescriptionDto.from(ClubDescription.builder().build()), "010-1234-5678", Map.of("insta", "https://test") ); @@ -31,9 +33,7 @@ public static ClubRecruitmentInfoUpdateRequest defaultRequest() { Instant.now(), Instant.now().plus(7, ChronoUnit.DAYS), "테스트 대상", - "테스트 설명", - "https://fake-url.com", - List.of() + "https://fake-url.com" ); } //ToDo: 시간 계산법을 LocalDateTime에서 Instant로 변경 후에 활성화할 것