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
35 changes: 35 additions & 0 deletions src/main/java/org/example/tackit/domain/entity/ColorChip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.example.tackit.domain.entity;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ColorChip {
BLUE("blue"),
GRAY("gray"),
PINK("pink"),
ORANGE("orange"),
GREEN("green");

private final String colorName;

// 프론트엔드 -> 백엔드 역직렬화 용
@JsonCreator
public static ColorChip from(String value) {
for (ColorChip color : ColorChip.values()) {
if (color.getColorName().equalsIgnoreCase(value)) {
return color;
}
}
throw new IllegalArgumentException("지원하지 않는 컬러칩 색상입니다: " + value);
}
Comment on lines +19 to +28

Choose a reason for hiding this comment

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

medium

성능 향상을 위해 from 메서드를 최적화하는 것을 제안합니다. 현재 구현은 from 메서드가 호출될 때마다 ColorChip.values()를 순회하여 O(N)의 시간 복잡도를 가집니다. Enum의 값이 많아지면 성능에 영향을 줄 수 있습니다.
정적 Map을 사용하여 색상 이름을 키로 ColorChip 인스턴스를 저장하면 O(1) 시간 복잡도로 조회가 가능합니다.

아래와 같이 수정할 수 있습니다. 이 변경을 적용하려면 파일 상단에 java.util.Map, java.util.stream.Stream, java.util.stream.Collectors, java.util.function.Function을 임포트해야 합니다.

  private static final Map<String, ColorChip> nameMap = Stream.of(values())
      .collect(Collectors.toMap(color -> color.colorName.toLowerCase(), Function.identity()));

  // 프론트엔드 -> 백엔드 역직렬화 용
  @JsonCreator
  public static ColorChip from(String value) {
    if (value == null) {
      throw new IllegalArgumentException("ColorChip 이름은 null일 수 없습니다.");
    }
    ColorChip result = nameMap.get(value.toLowerCase());
    if (result == null) {
      throw new IllegalArgumentException("지원하지 않는 컬러칩 색상입니다: " + value);
    }
    return result;
  }


// 백엔드 -> 프론트엔드 직렬화 용
@JsonValue
public String getColorName() {
return colorName;
}
}
174 changes: 100 additions & 74 deletions src/main/java/org/example/tackit/domain/entity/Event.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
package org.example.tackit.domain.entity;

import jakarta.persistence.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -9,84 +24,95 @@
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

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

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "event")
public class Event{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "event_id")
private Long id;

@Column(nullable = false)
private String title;

@Column(nullable = false)
private LocalDateTime startsAt;

@Column(nullable = false)
private LocalDateTime endsAt;

@CreatedDate
private LocalDateTime createdAt;

@LastModifiedDate
private LocalDateTime updatedAt;

@Column(columnDefinition = "TEXT")
private String description;

@Column(name = "color_chip", nullable = false)
private String colorChip;

@Enumerated(EnumType.STRING)
@Column(name = "event_scope", nullable = false)
private EventScope eventScope;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "org_id", nullable = false)
private Organization organization;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member creator;

@OneToMany(mappedBy = "event", cascade = CascadeType.ALL, orphanRemoval = true)
private List<EventParticipant> participants = new ArrayList<>();

@Builder
public Event(String title, LocalDateTime startsAt, LocalDateTime endsAt, LocalDateTime createdAt, LocalDateTime updatedAt,
String description, String colorChip, EventScope eventScope,
Organization organization, Member creator) {
this.title = title;
this.startsAt = startsAt;
this.endsAt = endsAt;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.description = description;
this.colorChip = colorChip;
this.eventScope = eventScope;
this.organization = organization;
this.creator = creator;
public class Event {

@OneToMany(mappedBy = "event", cascade = CascadeType.ALL, orphanRemoval = true)
private final List<EventParticipant> participants = new ArrayList<>();

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "event_id")
private Long id;

@Column(nullable = false)
private String title;

@Column(nullable = false)
private LocalDateTime startsAt;

@Column(nullable = false)
private LocalDateTime endsAt;

@CreatedDate
private LocalDateTime createdAt;

@LastModifiedDate
private LocalDateTime updatedAt;

@Column(columnDefinition = "TEXT")
private String description;

@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 10)
private ColorChip colorChip;

@Enumerated(EnumType.STRING)
@Column(name = "event_scope", nullable = false)
private EventScope eventScope;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "org_id", nullable = false)
private Organization organization;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member creator;

@Builder
public Event(String title, LocalDateTime startsAt, LocalDateTime endsAt, LocalDateTime createdAt,
LocalDateTime updatedAt,
String description, ColorChip colorChip, EventScope eventScope,
Organization organization, Member creator) {
this.title = title;
this.startsAt = startsAt;
this.endsAt = endsAt;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.description = description;
this.colorChip = colorChip;
this.eventScope = eventScope;
this.organization = organization;
this.creator = creator;
}

public void update(String title, LocalDateTime startsAt, LocalDateTime endsAt,
String description, ColorChip colorChip, EventScope eventScope) {
if (title != null) {
this.title = title;
}

public void update(String title, LocalDateTime startsAt, LocalDateTime endsAt,
String description, String colorChip, EventScope eventScope) {
if (title != null) this.title = title;
if (startsAt != null) this.startsAt = startsAt;
if (endsAt != null) this.endsAt = endsAt;
if (description != null) this.description = description;
if (colorChip != null) this.colorChip = colorChip;
if (eventScope != null) this.eventScope = eventScope;
if (startsAt != null) {
this.startsAt = startsAt;
}

// 참여자 목록 초기화 (참여자 수정 시 사용)
public void clearParticipants() {
this.participants.clear();
if (endsAt != null) {
this.endsAt = endsAt;
}
if (description != null) {
this.description = description;
}
if (colorChip != null) {
this.colorChip = colorChip;
}
if (eventScope != null) {
this.eventScope = eventScope;
}
}

// 참여자 목록 초기화 (참여자 수정 시 사용)
public void clearParticipants() {
this.participants.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,42 @@

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.example.tackit.domain.entity.EventScope;

import java.time.LocalDateTime;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.tackit.domain.entity.ColorChip;
import org.example.tackit.domain.entity.EventScope;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class EventCreateReqDto {

@NotNull(message = "조직 ID는 필수입니다.")
private Long orgId;
@NotNull(message = "조직 ID는 필수입니다.")
private Long orgId;

@NotBlank(message = "일정 제목은 필수입니다.")
private String title;
@NotBlank(message = "일정 제목은 필수입니다.")
private String title;

@NotNull(message = "시작 시간은 필수입니다.")
private LocalDateTime startsAt;
@NotNull(message = "시작 시간은 필수입니다.")
private LocalDateTime startsAt;

@NotNull(message = "종료 시간은 필수입니다.")
private LocalDateTime endsAt;
@NotNull(message = "종료 시간은 필수입니다.")
private LocalDateTime endsAt;

private String description;
private String description;

@NotNull(message = "참여자 범위(eventScope)는 필수입니다.")
private EventScope eventScope;
@NotNull(message = "참여자 범위(eventScope)는 필수입니다.")
private EventScope eventScope;

@NotNull(message = "참여자 목록 필드는 필수입니다.")
private List<Long> participants;
@NotNull(message = "참여자 목록 필드는 필수입니다.")
private List<Long> participants;

@NotBlank(message = "색상 코드는 필수입니다.")
private String colorChip;
@NotNull(message = "색상 코드는 필수입니다.")
private ColorChip colorChip;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.tackit.domain.entity.ColorChip;
import org.example.tackit.domain.member.dto.SimpleMemberProfileDto;

@Getter
Expand All @@ -19,6 +20,6 @@ public class EventDetailResDto {
private LocalDateTime startsAt;
private LocalDateTime endsAt;
private String description;
private String colorChip;
private ColorChip colorChip;
private List<SimpleMemberProfileDto> participants;
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package org.example.tackit.domain.event.dto;

import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import org.example.tackit.domain.entity.ColorChip;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class EventSimpleResDto {
private Long eventId;
private String title;
private LocalDateTime startsAt;
private LocalDateTime endsAt;
private String colorChip;

private Long eventId;
private String title;
private LocalDateTime startsAt;
private LocalDateTime endsAt;
private ColorChip colorChip;
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
package org.example.tackit.domain.event.dto;

import lombok.*;
import org.example.tackit.domain.entity.EventScope;

import java.time.LocalDateTime;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.tackit.domain.entity.ColorChip;
import org.example.tackit.domain.entity.EventScope;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class EventUpdateReqDto {
private String title;
private LocalDateTime startsAt;
private LocalDateTime endsAt;
private String description;
private EventScope eventScope;
private List<Long> participants;
private String colorChip;

private String title;
private LocalDateTime startsAt;
private LocalDateTime endsAt;
private String description;
private EventScope eventScope;
private List<Long> participants;
private ColorChip colorChip;
}
Loading