From 47aef26ec0c05aa41f599674e6da2bc1b324fe4f Mon Sep 17 00:00:00 2001 From: ownue Date: Mon, 20 Jul 2026 18:00:51 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20=EB=A1=9C=EC=BB=AC=EC=9A=A9=20dock?= =?UTF-8?q?er-compose.local.yml=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.local.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 docker-compose.local.yml diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..f10855c --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,31 @@ +services: + mysql: + image: mysql:8.4 + container_name: todayeng-mysql + restart: unless-stopped + ports: + - "3306:3306" + environment: + MYSQL_DATABASE: today_eng + MYSQL_USER: todayeng + MYSQL_PASSWORD: todayeng1234 + MYSQL_ROOT_PASSWORD: root1234 + TZ: Asia/Seoul + command: + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_0900_ai_ci + volumes: + - todayeng-mysql-data:/var/lib/mysql + healthcheck: + test: + [ + "CMD-SHELL", + "mysqladmin ping -h localhost -uroot -proot1234 --silent" + ] + interval: 10s + timeout: 5s + retries: 10 + start_period: 20s + +volumes: + todayeng-mysql-data: \ No newline at end of file From 4936af4e1c802135095f0dcccfe5ddaecb788ff9 Mon Sep 17 00:00:00 2001 From: ownue Date: Mon, 20 Jul 2026 18:00:55 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=ED=9A=8C=EA=B3=A0=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todayEng/domain/diary/entity/Diary.java | 99 +++++++++++ .../domain/diary/entity/DiaryAnswer.java | 116 ++++++++++++ .../domain/diary/entity/DiaryContext.java | 96 ++++++++++ .../domain/diary/entity/DiaryQuestion.java | 167 ++++++++++++++++++ .../diary/entity/enums/CorrectionStatus.java | 7 + .../diary/entity/enums/DiaryContextType.java | 9 + .../diary/entity/enums/DiaryStatus.java | 6 + .../entity/enums/QuestionGenerationType.java | 6 + .../diary/entity/enums/QuestionType.java | 6 + 9 files changed, 512 insertions(+) create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/Diary.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/enums/CorrectionStatus.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryContextType.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryStatus.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionGenerationType.java create mode 100644 src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionType.java diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java b/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java new file mode 100644 index 0000000..3bfd2e7 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java @@ -0,0 +1,99 @@ +package com.example.todayEng.domain.diary.entity; + +import com.example.todayEng.domain.diary.entity.enums.DiaryStatus; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.time.LocalDate; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +@Getter +@Entity +@Table(name = "diary") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Diary { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "diary_id") + private Long id; + + /* + * User 엔티티 구현 후 수정 + * + * @ManyToOne(fetch = FetchType.LAZY) + * @JoinColumn(name = "user_id", nullable = false) + * private User user; + */ + @Column(name = "user_id", nullable = false) + private Long userId; + + @Column(name = "diary_date", nullable = false) + private LocalDate diaryDate; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false, length = 20) + private DiaryStatus status; + + @Column(name = "memo", length = 500) + private String memo; + + @CreationTimestamp + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @UpdateTimestamp + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; + + @Column(name = "completed_at") + private LocalDateTime completedAt; + + @Builder + private Diary( + Long userId, + LocalDate diaryDate, + String memo + ) { + this.userId = userId; + this.diaryDate = diaryDate; + this.memo = memo; + this.status = DiaryStatus.IN_PROGRESS; + } + + public static Diary create( + Long userId, + LocalDate diaryDate, + String memo + ) { + return Diary.builder() + .userId(userId) + .diaryDate(diaryDate) + .memo(memo) + .build(); + } + + public void updateMemo(String memo) { + this.memo = memo; + } + + public void complete() { + if (this.status == DiaryStatus.COMPLETED) { + return; + } + + this.status = DiaryStatus.COMPLETED; + this.completedAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java new file mode 100644 index 0000000..19439f8 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java @@ -0,0 +1,116 @@ +package com.example.todayEng.domain.diary.entity; + +import com.example.todayEng.domain.diary.entity.enums.CorrectionStatus; +import com.fasterxml.jackson.databind.JsonNode; +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.OneToOne; +import jakarta.persistence.Table; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.annotations.UpdateTimestamp; +import org.hibernate.type.SqlTypes; + +@Getter +@Entity +@Table(name = "diary_answer") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class DiaryAnswer { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "answer_id") + private Long id; + + @OneToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn( + name = "question_id", + nullable = false, + unique = true + ) + private DiaryQuestion question; + + @Column(name = "original_text", nullable = false, columnDefinition = "TEXT") + private String originalText; + + @Column(name = "corrected_text", columnDefinition = "TEXT") + private String correctedText; + + @Column(name = "correction_reason", columnDefinition = "TEXT") + private String correctionReason; + + @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "alternative_expression", columnDefinition = "json") + private JsonNode alternativeExpression; + + @Enumerated(EnumType.STRING) + @Column(name = "correction_status", nullable = false, length = 20) + private CorrectionStatus correctionStatus; + + @CreationTimestamp + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @UpdateTimestamp + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; + + @Builder + private DiaryAnswer( + DiaryQuestion question, + String originalText + ) { + this.question = question; + this.originalText = originalText; + this.correctionStatus = CorrectionStatus.PENDING; + } + + public static DiaryAnswer create( + DiaryQuestion question, + String originalText + ) { + return DiaryAnswer.builder() + .question(question) + .originalText(originalText) + .build(); + } + + public void updateOriginalText(String originalText) { + this.originalText = originalText; + this.correctedText = null; + this.correctionReason = null; + this.alternativeExpression = null; + this.correctionStatus = CorrectionStatus.PENDING; + } + + public void startCorrection() { + this.correctionStatus = CorrectionStatus.PENDING; + } + + public void completeCorrection( + String correctedText, + String correctionReason, + JsonNode alternativeExpression + ) { + this.correctedText = correctedText; + this.correctionReason = correctionReason; + this.alternativeExpression = alternativeExpression; + this.correctionStatus = CorrectionStatus.SUCCEEDED; + } + + public void failCorrection() { + this.correctionStatus = CorrectionStatus.FAILED; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java new file mode 100644 index 0000000..1989cd6 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java @@ -0,0 +1,96 @@ +package com.example.todayEng.domain.diary.entity; + +import com.example.todayEng.domain.diary.entity.enums.DiaryContextType; +import com.fasterxml.jackson.databind.JsonNode; +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.Table; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +@Getter +@Entity +@Table(name = "diary_context") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class DiaryContext { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "context_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "diary_id", nullable = false) + private Diary diary; + + @Enumerated(EnumType.STRING) + @Column(name = "context_type", nullable = false, length = 30) + private DiaryContextType contextType; + + @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "context_data", columnDefinition = "json") + private JsonNode contextData; + + @Column(name = "is_success", nullable = false) + private boolean success; + + @CreationTimestamp + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @Builder + private DiaryContext( + Diary diary, + DiaryContextType contextType, + JsonNode contextData, + boolean success + ) { + this.diary = diary; + this.contextType = contextType; + this.contextData = contextData; + this.success = success; + } + + public static DiaryContext success( + Diary diary, + DiaryContextType contextType, + JsonNode contextData + ) { + return DiaryContext.builder() + .diary(diary) + .contextType(contextType) + .contextData(contextData) + .success(true) + .build(); + } + + public static DiaryContext failure( + Diary diary, + DiaryContextType contextType + ) { + return DiaryContext.builder() + .diary(diary) + .contextType(contextType) + .success(false) + .build(); + } + + public void updateContextData(JsonNode contextData) { + this.contextData = contextData; + this.success = true; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java new file mode 100644 index 0000000..05eba26 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java @@ -0,0 +1,167 @@ +package com.example.todayEng.domain.diary.entity; + +import com.example.todayEng.domain.diary.entity.enums.QuestionGenerationType; +import com.example.todayEng.domain.diary.entity.enums.QuestionType; +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.Table; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.CreationTimestamp; + +@Getter +@Entity +@Table(name = "diary_question") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class DiaryQuestion { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "question_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "diary_id", nullable = false) + private Diary diary; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_question_id") + private DiaryQuestion parentQuestion; + + @Enumerated(EnumType.STRING) + @Column(name = "question_type", nullable = false, length = 20) + private QuestionType questionType; + + @Column(name = "question_order", nullable = false) + private Integer questionOrder; + + @Column(name = "question_text", nullable = false, columnDefinition = "TEXT") + private String questionText; + + @Enumerated(EnumType.STRING) + @Column(name = "generation_type", nullable = false, length = 20) + private QuestionGenerationType generationType; + + @Column( + name = "korean_translation", + nullable = false, + columnDefinition = "TEXT" + ) + private String koreanTranslation; + + @Column(name = "keyword", length = 50) + private String keyword; + + @CreationTimestamp + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @Builder + private DiaryQuestion( + Diary diary, + DiaryQuestion parentQuestion, + QuestionType questionType, + Integer questionOrder, + String questionText, + QuestionGenerationType generationType, + String koreanTranslation, + String keyword + ) { + validateParentQuestion(questionType, parentQuestion); + validateKeyword(questionType, keyword); + + this.diary = diary; + this.parentQuestion = parentQuestion; + this.questionType = questionType; + this.questionOrder = questionOrder; + this.questionText = questionText; + this.generationType = generationType; + this.koreanTranslation = koreanTranslation; + this.keyword = keyword; + } + + public static DiaryQuestion createMainQuestion( + Diary diary, + Integer questionOrder, + String questionText, + QuestionGenerationType generationType, + String koreanTranslation, + String keyword + ) { + return DiaryQuestion.builder() + .diary(diary) + .questionType(QuestionType.MAIN) + .questionOrder(questionOrder) + .questionText(questionText) + .generationType(generationType) + .koreanTranslation(koreanTranslation) + .keyword(keyword) + .build(); + } + + public static DiaryQuestion createFollowUpQuestion( + Diary diary, + DiaryQuestion parentQuestion, + Integer questionOrder, + String questionText, + QuestionGenerationType generationType, + String koreanTranslation + ) { + return DiaryQuestion.builder() + .diary(diary) + .parentQuestion(parentQuestion) + .questionType(QuestionType.FOLLOW_UP) + .questionOrder(questionOrder) + .questionText(questionText) + .generationType(generationType) + .koreanTranslation(koreanTranslation) + .build(); + } + + private static void validateParentQuestion( + QuestionType questionType, + DiaryQuestion parentQuestion + ) { + if (questionType == QuestionType.MAIN && parentQuestion != null) { + throw new IllegalArgumentException( + "메인 질문에는 상위 질문을 지정할 수 없습니다." + ); + } + + if (questionType == QuestionType.FOLLOW_UP + && parentQuestion == null) { + throw new IllegalArgumentException( + "후속 질문에는 메인 질문이 필요합니다." + ); + } + + if (parentQuestion != null + && parentQuestion.questionType != QuestionType.MAIN) { + throw new IllegalArgumentException( + "후속 질문의 상위 질문은 메인 질문이어야 합니다." + ); + } + } + + private static void validateKeyword( + QuestionType questionType, + String keyword + ) { + if (questionType == QuestionType.FOLLOW_UP && keyword != null) { + throw new IllegalArgumentException( + "후속 질문에는 키워드를 지정할 수 없습니다." + ); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/enums/CorrectionStatus.java b/src/main/java/com/example/todayEng/domain/diary/entity/enums/CorrectionStatus.java new file mode 100644 index 0000000..fe56e72 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/enums/CorrectionStatus.java @@ -0,0 +1,7 @@ +package com.example.todayEng.domain.diary.entity.enums; + +public enum CorrectionStatus { + PENDING, + SUCCEEDED, + FAILED +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryContextType.java b/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryContextType.java new file mode 100644 index 0000000..ea77146 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryContextType.java @@ -0,0 +1,9 @@ +package com.example.todayEng.domain.diary.entity.enums; + +public enum DiaryContextType { + CALENDAR, + WEATHER, + PHOTO, + USER_MEMO, + DIARY_MEMORY +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryStatus.java b/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryStatus.java new file mode 100644 index 0000000..ad6d3c1 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/enums/DiaryStatus.java @@ -0,0 +1,6 @@ +package com.example.todayEng.domain.diary.entity.enums; + +public enum DiaryStatus { + IN_PROGRESS, + COMPLETED +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionGenerationType.java b/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionGenerationType.java new file mode 100644 index 0000000..f2478f5 --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionGenerationType.java @@ -0,0 +1,6 @@ +package com.example.todayEng.domain.diary.entity.enums; + +public enum QuestionGenerationType { + AI, + DEFAULT +} \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionType.java b/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionType.java new file mode 100644 index 0000000..0952e5e --- /dev/null +++ b/src/main/java/com/example/todayEng/domain/diary/entity/enums/QuestionType.java @@ -0,0 +1,6 @@ +package com.example.todayEng.domain.diary.entity.enums; + +public enum QuestionType { + MAIN, + FOLLOW_UP +} \ No newline at end of file From e2d04d3e1ab16c4defb97eec844120e7080ee62f Mon Sep 17 00:00:00 2001 From: ownue Date: Tue, 21 Jul 2026 12:17:49 +0900 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20Builder=EC=97=90=20AccessLevel=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=EC=A0=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/example/todayEng/domain/diary/entity/Diary.java | 2 +- .../com/example/todayEng/domain/diary/entity/DiaryAnswer.java | 2 +- .../com/example/todayEng/domain/diary/entity/DiaryContext.java | 2 +- .../com/example/todayEng/domain/diary/entity/DiaryQuestion.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java b/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java index 3bfd2e7..e13102f 100644 --- a/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java +++ b/src/main/java/com/example/todayEng/domain/diary/entity/Diary.java @@ -60,7 +60,7 @@ public class Diary { @Column(name = "completed_at") private LocalDateTime completedAt; - @Builder + @Builder(access = AccessLevel.PRIVATE) private Diary( Long userId, LocalDate diaryDate, diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java index 19439f8..3230296 100644 --- a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryAnswer.java @@ -67,7 +67,7 @@ public class DiaryAnswer { @Column(name = "updated_at", nullable = false) private LocalDateTime updatedAt; - @Builder + @Builder(access = AccessLevel.PRIVATE) private DiaryAnswer( DiaryQuestion question, String originalText diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java index 1989cd6..b251d33 100644 --- a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryContext.java @@ -52,7 +52,7 @@ public class DiaryContext { @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; - @Builder + @Builder(access = AccessLevel.PRIVATE) private DiaryContext( Diary diary, DiaryContextType contextType, diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java index 05eba26..c5aa786 100644 --- a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java @@ -67,7 +67,7 @@ public class DiaryQuestion { @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; - @Builder + @Builder(access = AccessLevel.PRIVATE) private DiaryQuestion( Diary diary, DiaryQuestion parentQuestion, From 41a121f2d4044f9fe20c15f84766b01248a7851c Mon Sep 17 00:00:00 2001 From: ownue Date: Tue, 21 Jul 2026 12:28:14 +0900 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20IllegalException=EC=9D=84=20BaseEx?= =?UTF-8?q?ception=20+=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/entity/DiaryQuestion.java | 18 ++++++------------ .../todayEng/global/error/ErrorCode.java | 10 +++++++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java index c5aa786..c1737e3 100644 --- a/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java +++ b/src/main/java/com/example/todayEng/domain/diary/entity/DiaryQuestion.java @@ -2,6 +2,8 @@ import com.example.todayEng.domain.diary.entity.enums.QuestionGenerationType; import com.example.todayEng.domain.diary.entity.enums.QuestionType; +import com.example.todayEng.global.error.ErrorCode; +import com.example.todayEng.global.error.exception.BaseException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -134,23 +136,17 @@ private static void validateParentQuestion( DiaryQuestion parentQuestion ) { if (questionType == QuestionType.MAIN && parentQuestion != null) { - throw new IllegalArgumentException( - "메인 질문에는 상위 질문을 지정할 수 없습니다." - ); + throw new BaseException(ErrorCode.MAIN_QUESTION_CANNOT_HAVE_PARENT); } if (questionType == QuestionType.FOLLOW_UP && parentQuestion == null) { - throw new IllegalArgumentException( - "후속 질문에는 메인 질문이 필요합니다." - ); + throw new BaseException(ErrorCode.FOLLOW_UP_QUESTION_REQUIRES_PARENT); } if (parentQuestion != null && parentQuestion.questionType != QuestionType.MAIN) { - throw new IllegalArgumentException( - "후속 질문의 상위 질문은 메인 질문이어야 합니다." - ); + throw new BaseException(ErrorCode.FOLLOW_UP_PARENT_MUST_BE_MAIN_QUESTION); } } @@ -159,9 +155,7 @@ private static void validateKeyword( String keyword ) { if (questionType == QuestionType.FOLLOW_UP && keyword != null) { - throw new IllegalArgumentException( - "후속 질문에는 키워드를 지정할 수 없습니다." - ); + throw new BaseException(ErrorCode.FOLLOW_UP_QUESTION_CANNOT_HAVE_KEYWORD); } } } \ No newline at end of file diff --git a/src/main/java/com/example/todayEng/global/error/ErrorCode.java b/src/main/java/com/example/todayEng/global/error/ErrorCode.java index 06891c5..f94cdf0 100644 --- a/src/main/java/com/example/todayEng/global/error/ErrorCode.java +++ b/src/main/java/com/example/todayEng/global/error/ErrorCode.java @@ -43,7 +43,15 @@ public enum ErrorCode { FILE_UPLOAD_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "E001", "S3 파일 업로드에 실패했습니다."), FILE_SIZE_EXCEEDED(HttpStatus.BAD_REQUEST, "E002", "파일 업로드 용량을 초과했습니다."), INVALID_FILE_EXTENSION(HttpStatus.BAD_REQUEST, "E003", "허용되지 않는 파일 확장자입니다."), - EXTERNAL_API_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "E004", "외부 연동 API 호출에 실패했습니다."); + EXTERNAL_API_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "E004", "외부 연동 API 호출에 실패했습니다."), + + // Diary (D) + MAIN_QUESTION_CANNOT_HAVE_PARENT(HttpStatus.BAD_REQUEST, "D001", "메인 질문에는 상위 질문을 지정할 수 없습니다."), + FOLLOW_UP_QUESTION_REQUIRES_PARENT(HttpStatus.BAD_REQUEST, "D002", "후속 질문에는 메인 질문이 필요합니다."), + FOLLOW_UP_PARENT_MUST_BE_MAIN_QUESTION(HttpStatus.BAD_REQUEST,"D003","후속 질문의 상위 질문은 메인 질문이어야 합니다."), + FOLLOW_UP_QUESTION_CANNOT_HAVE_KEYWORD(HttpStatus.BAD_REQUEST, "D004", "후속 질문에는 키워드를 지정할 수 없습니다.") + + ; private final HttpStatus status; private final String code;