Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] feat: Festival 엔티티 startDate, endDate 필드 FestivalDuration 값 타입 변경 및 thumbnail 필드명 변경 (#880) #881

Merged
merged 4 commits into from
Apr 20, 2024
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 @@ -23,9 +23,9 @@ public Optional<AdminFestivalDetailV1Response> findDetail(Long festivalId) {
festival.name,
school.id,
school.name,
festival.startDate,
festival.endDate,
festival.thumbnail,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
festival.posterImageUrl,
festival.createdAt,
festival.updatedAt
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public Page<AdminFestivalV1Response> findAll(SearchCondition searchCondition) {
festival.id,
festival.name,
school.name,
festival.startDate,
festival.endDate,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
stage.count()
))
.from(festival)
Expand Down Expand Up @@ -88,8 +88,8 @@ private OrderSpecifier<?> getOrderSpecifier(Sort sort) {
case "id" -> OrderSpecifierUtils.of(it.getDirection(), festival.id);
case "name" -> OrderSpecifierUtils.of(it.getDirection(), festival.name);
case "schoolName" -> OrderSpecifierUtils.of(it.getDirection(), school.name);
case "startDate" -> OrderSpecifierUtils.of(it.getDirection(), festival.startDate);
case "endDate" -> OrderSpecifierUtils.of(it.getDirection(), festival.endDate);
case "startDate" -> OrderSpecifierUtils.of(it.getDirection(), festival.festivalDuration.startDate);
case "endDate" -> OrderSpecifierUtils.of(it.getDirection(), festival.festivalDuration.endDate);
default -> OrderSpecifierUtils.NULL;
})
.orElse(OrderSpecifierUtils.NULL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ private JPAQuery<ArtistFestivalDetailV1Response> selectArtistDetailResponse(Long
new QArtistFestivalDetailV1Response(
festival.id,
festival.name,
festival.startDate,
festival.endDate,
festival.thumbnail,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
festival.posterImageUrl,
festivalQueryInfo.artistInfo))
.from(stageArtist)
.innerJoin(stage).on(stageArtist.artistId.eq(artistId).and(stage.id.eq(stageArtist.stageId)))
Expand All @@ -124,26 +124,26 @@ private boolean hasCursor(LocalDate lastStartDate, Long lastFestivalId) {

private BooleanExpression getCursorBasedWhere(boolean isPast, LocalDate lastStartDate, Long lastFestivalId) {
if (isPast) {
return festival.startDate.lt(lastStartDate)
.or(festival.startDate.eq(lastStartDate)
return festival.festivalDuration.startDate.lt(lastStartDate)
.or(festival.festivalDuration.startDate.eq(lastStartDate)
.and(festival.id.gt(lastFestivalId)));
}
return festival.startDate.gt(lastStartDate)
.or(festival.startDate.eq(lastStartDate)
return festival.festivalDuration.startDate.gt(lastStartDate)
.or(festival.festivalDuration.startDate.eq(lastStartDate)
.and(festival.id.gt(lastFestivalId)));
}

private BooleanExpression getDefaultWhere(boolean isPast, LocalDate currentTime) {
if (isPast) {
return festival.endDate.lt(currentTime);
return festival.festivalDuration.endDate.lt(currentTime);
}
return festival.endDate.goe(currentTime);
return festival.festivalDuration.endDate.goe(currentTime);
}

private OrderSpecifier<LocalDate>[] getDynamicOrderBy(Boolean isPast) {
if (isPast) {
return new OrderSpecifier[]{festival.endDate.desc()};
return new OrderSpecifier[]{festival.festivalDuration.endDate.desc()};
}
return new OrderSpecifier[]{festival.startDate.asc(), festival.id.asc()};
return new OrderSpecifier[]{festival.festivalDuration.startDate.asc(), festival.id.asc()};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public List<FestivalBookmarkV1Response> findBookmarkedFestivals(
new QFestivalV1Response(
festival.id,
festival.name,
festival.startDate,
festival.endDate,
festival.thumbnail,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
festival.posterImageUrl,
new QSchoolV1Response(
school.id,
school.name
Expand All @@ -65,7 +65,7 @@ public List<FestivalBookmarkV1Response> findBookmarkedFestivals(
private OrderSpecifier<?> dynamicOrder(FestivalBookmarkOrder festivalBookmarkOrder) {
return switch (festivalBookmarkOrder) {
case BOOKMARK -> bookmark.id.desc();
case FESTIVAL -> festival.startDate.asc();
case FESTIVAL -> festival.festivalDuration.startDate.asc();
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ public class FestivalCreateService {

public Long createFestival(FestivalCreateCommand command) {
School school = schoolRepository.getOrThrow(command.schoolId());
Festival festival = festivalRepository.save(command.toEntity(school));
Festival festival = command.toEntity(school);
validate(festival);
festivalRepository.save(festival);
eventPublisher.publishEvent(new FestivalCreatedEvent(festival.getId()));
return festival.getId();
}

private void validate(Festival festival) {
if (festival.isBeforeStartDate(LocalDate.now(clock))) {
if (festival.isStartDateBeforeTo(LocalDate.now(clock))) {
throw new BadRequestException(ErrorCode.INVALID_FESTIVAL_START_DATE);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.festago.festival.application.command;

import com.festago.festival.domain.Festival;
import com.festago.festival.domain.FestivalDuration;
import com.festago.festival.domain.validator.FestivalUpdateValidator;
import com.festago.festival.dto.command.FestivalUpdateCommand;
import com.festago.festival.repository.FestivalRepository;
Expand All @@ -23,8 +24,8 @@ public class FestivalUpdateService {
public void updateFestival(Long festivalId, FestivalUpdateCommand command) {
Festival festival = festivalRepository.getOrThrow(festivalId);
festival.changeName(command.name());
festival.changeThumbnail(command.posterImageUrl());
festival.changeDate(command.startDate(), command.endDate());
festival.changePosterImageUrl(command.posterImageUrl());
festival.changeFestivalDuration(new FestivalDuration(command.startDate(), command.endDate()));
validators.forEach(validator -> validator.validate(festival));
}
}
96 changes: 42 additions & 54 deletions backend/src/main/java/com/festago/festival/domain/Festival.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.festago.festival.domain;

import com.festago.common.domain.BaseTimeEntity;
import com.festago.common.exception.BadRequestException;
import com.festago.common.exception.ErrorCode;
import com.festago.common.util.Validator;
import com.festago.school.domain.School;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
Expand All @@ -23,9 +21,9 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Festival extends BaseTimeEntity {

private static final String DEFAULT_THUMBNAIL = "https://picsum.photos/536/354";
private static final String DEFAULT_POSTER_IMAGE_URL = "https://picsum.photos/536/354";
private static final int MAX_NAME_LENGTH = 50;
private static final int MAX_THUMBNAIL_LENGTH = 255;
private static final int MAX_POSTER_IMAGE_URL_LENGTH = 255;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -35,88 +33,78 @@ public class Festival extends BaseTimeEntity {
@Size(max = MAX_NAME_LENGTH)
private String name;

@NotNull
private LocalDate startDate;

@NotNull
private LocalDate endDate;
@Embedded
private FestivalDuration festivalDuration;

@NotNull
@Size(max = MAX_THUMBNAIL_LENGTH)
@Column(name = "poster_image_url")
private String thumbnail;
@Size(max = MAX_POSTER_IMAGE_URL_LENGTH)
private String posterImageUrl;

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private School school;

public Festival(String name, LocalDate startDate, LocalDate endDate, School school) {
this(null, name, startDate, endDate, DEFAULT_THUMBNAIL, school);
public Festival(String name, FestivalDuration festivalDuration, School school) {
this(null, name, festivalDuration, DEFAULT_POSTER_IMAGE_URL, school);
}

public Festival(String name, LocalDate startDate, LocalDate endDate, String thumbnail, School school) {
this(null, name, startDate, endDate, thumbnail, school);
public Festival(String name, FestivalDuration festivalDuration, String posterImageUrl, School school) {
this(null, name, festivalDuration, posterImageUrl, school);
}

public Festival(Long id, String name, LocalDate startDate, LocalDate endDate, String thumbnail, School school) {
validate(name, startDate, endDate, thumbnail);
public Festival(Long id, String name, FestivalDuration festivalDuration, String posterImageUrl, School school) {
validateName(name);
validateFestivalDuration(festivalDuration);
validatePosterImageUrl(posterImageUrl);
validateSchool(school);
this.id = id;
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.thumbnail = thumbnail;
this.festivalDuration = festivalDuration;
this.posterImageUrl = posterImageUrl;
this.school = school;
}

private void validate(String name, LocalDate startDate, LocalDate endDate, String thumbnail) {
validateName(name);
validateThumbnail(thumbnail);
validateDate(startDate, endDate);
}

private void validateName(String name) {
String fieldName = "name";
Validator.notBlank(name, fieldName);
Validator.maxLength(name, MAX_NAME_LENGTH, fieldName);
}

private void validateThumbnail(String thumbnail) {
String fieldName = "thumbnail";
Validator.notBlank(thumbnail, fieldName);
Validator.maxLength(thumbnail, MAX_THUMBNAIL_LENGTH, fieldName);
private void validatePosterImageUrl(String posterImageUrl) {
String fieldName = "posterImageUrl";
Validator.notBlank(posterImageUrl, fieldName);
Validator.maxLength(posterImageUrl, MAX_POSTER_IMAGE_URL_LENGTH, fieldName);
}

private void validateFestivalDuration(FestivalDuration festivalDuration) {
Validator.notNull(festivalDuration, "festivalDuration");
}

private void validateDate(LocalDate startDate, LocalDate endDate) {
Validator.notNull(startDate, "startDate");
Validator.notNull(endDate, "endDate");
if (startDate.isAfter(endDate)) {
throw new BadRequestException(ErrorCode.INVALID_FESTIVAL_DURATION);
}
private void validateSchool(School school) {
Validator.notNull(school, "school");
}

public boolean isBeforeStartDate(LocalDate currentDate) {
return startDate.isBefore(currentDate);
public boolean isStartDateBeforeTo(LocalDate date) {
return festivalDuration.isStartDateBeforeTo(date);
}

public boolean isNotInDuration(LocalDateTime time) {
LocalDate date = time.toLocalDate();
return date.isBefore(startDate) || date.isAfter(endDate);
public boolean isNotInDuration(LocalDateTime dateTime) {
return festivalDuration.isNotInDuration(dateTime.toLocalDate());
}

public void changeName(String name) {
validateName(name);
this.name = name;
}

public void changeThumbnail(String thumbnail) {
validateThumbnail(thumbnail);
this.thumbnail = thumbnail;
public void changePosterImageUrl(String posterImageUrl) {
validatePosterImageUrl(posterImageUrl);
this.posterImageUrl = posterImageUrl;
}

public void changeDate(LocalDate startDate, LocalDate endDate) {
validateDate(startDate, endDate);
this.startDate = startDate;
this.endDate = endDate;
public void changeFestivalDuration(FestivalDuration festivalDuration) {
validateFestivalDuration(festivalDuration);
this.festivalDuration = festivalDuration;
}

public Long getId() {
Expand All @@ -128,15 +116,15 @@ public String getName() {
}

public LocalDate getStartDate() {
return startDate;
return festivalDuration.getStartDate();
}

public LocalDate getEndDate() {
return endDate;
return festivalDuration.getEndDate();
}

public String getThumbnail() {
return thumbnail;
public String getPosterImageUrl() {
return posterImageUrl;
}

public School getSchool() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private void validate(LocalDate startDate, LocalDate endDate) {
}
}

public boolean isBeforeStartDate(LocalDate date) {
public boolean isStartDateBeforeTo(LocalDate date) {
return startDate.isBefore(date);
}
Comment on lines -32 to 34
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.festago.festival.dto.command;

import com.festago.festival.domain.Festival;
import com.festago.festival.domain.FestivalDuration;
import com.festago.school.domain.School;
import java.time.LocalDate;

Expand All @@ -13,6 +14,6 @@ public record FestivalCreateCommand(
) {

public Festival toEntity(School school) {
return new Festival(name, startDate, endDate, posterImageUrl, school);
return new Festival(name, new FestivalDuration(startDate, endDate), posterImageUrl, school);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ private List<FestivalSearchV1Response> searchByExpression(BooleanExpression expr
new QFestivalSearchV1Response(
festival.id,
festival.name,
festival.startDate,
festival.endDate,
festival.thumbnail,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
festival.posterImageUrl,
festivalQueryInfo.artistInfo))
.from(artist)
.innerJoin(stageArtist).on(expression.and(stageArtist.artistId.eq(artist.id)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ public Optional<FestivalDetailV1Response> findFestivalDetail(Long festivalId) {
school.id,
school.name
),
festival.startDate,
festival.endDate,
festival.thumbnail,
festival.festivalDuration.startDate,
festival.festivalDuration.endDate,
festival.posterImageUrl,
sortedSet(new QSocialMediaV1Response(
socialMedia.mediaType,
socialMedia.name,
Expand Down
Loading
Loading