From 323115657faf6d9065e162dde2c9f2297bcd452a Mon Sep 17 00:00:00 2001 From: kkw610 Date: Sun, 7 Jun 2026 10:59:30 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=A7=88=EB=AC=B8/=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=8B=A8=EB=8F=85=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EB=B6=88=EA=B0=80=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/question/entity/Question.java | 2 +- .../question/entity/QuestionComment.java | 2 +- .../question/service/QuestionService.java | 24 +++++++++++++++++++ .../V7__alter_question_content_nullable.sql | 3 +++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V7__alter_question_content_nullable.sql diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/entity/Question.java b/backend/src/main/java/com/example/Piroin/project/domain/question/entity/Question.java index a9a4a0d..195f34c 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/entity/Question.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/entity/Question.java @@ -27,7 +27,7 @@ public class Question { @JoinColumn(name = "user_id", nullable = false) private User user; - @Column(nullable = false, columnDefinition = "TEXT") + @Column(columnDefinition = "TEXT") private String content; @Column(name = "image_url", columnDefinition = "TEXT") diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/entity/QuestionComment.java b/backend/src/main/java/com/example/Piroin/project/domain/question/entity/QuestionComment.java index c173dd9..d91606c 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/entity/QuestionComment.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/entity/QuestionComment.java @@ -36,7 +36,7 @@ public class QuestionComment { @JoinColumn(name = "parent_comment_id") private QuestionComment parentComment; - @Column(nullable = false, columnDefinition = "TEXT") + @Column(columnDefinition = "TEXT") private String content; @Column(name = "image_url", columnDefinition = "TEXT") diff --git a/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java b/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java index af58000..f312568 100644 --- a/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java +++ b/backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java @@ -136,6 +136,9 @@ public QuestionResDTO.CommentCreateRes createComment( // 1. 대댓글 여부 확인: parentCommentId가 있으면 부모 댓글 조회 QuestionComment parentComment = resolveParentComment(request.getParentCommentId(), question); + // builder 전에 검증 추가 + validateCommentContent(request.getContent(), request.getImageUrl()); + // 2. 댓글 엔티티 생성 및 저장 LocalDateTime now = LocalDateTime.now(); QuestionComment comment = QuestionComment.builder() @@ -248,6 +251,9 @@ public QuestionResDTO.CreateRes createQuestion(Long sessionId, QuestionReqDTO.Cr User loginUser = findLoginUser(userId); StudySession session = findSession(sessionId); + // builder 전에 검증 추가 + validateQuestionContent(request.getContent(), request.getImageUrl()); + Question question = Question.builder() .session(session) .user(loginUser) @@ -793,4 +799,22 @@ private record QuestionSummaryContext( Set likedQuestionIds ) { } + + // 질문은 내용 또는 이미지 중 하나는 반드시 있어야 함 + private void validateQuestionContent(String content, String imageUrl) { + boolean hasContent = content != null && !content.isBlank(); + boolean hasImage = imageUrl != null && !imageUrl.isBlank(); + if (!hasContent && !hasImage) { + throw new QuestionException(HttpStatus.BAD_REQUEST, "질문 내용 또는 이미지 중 하나는 필수입니다."); + } + } + + // 댓글은 내용 또는 이미지 중 하나는 반드시 있어야 함 + private void validateCommentContent(String content, String imageUrl) { + boolean hasContent = content != null && !content.isBlank(); + boolean hasImage = imageUrl != null && !imageUrl.isBlank(); + if (!hasContent && !hasImage) { + throw new QuestionException(HttpStatus.BAD_REQUEST, "댓글 내용 또는 이미지 중 하나는 필수입니다."); + } + } } diff --git a/backend/src/main/resources/db/migration/V7__alter_question_content_nullable.sql b/backend/src/main/resources/db/migration/V7__alter_question_content_nullable.sql new file mode 100644 index 0000000..86b1f40 --- /dev/null +++ b/backend/src/main/resources/db/migration/V7__alter_question_content_nullable.sql @@ -0,0 +1,3 @@ +-- 이미지만 단독 업로드가 가능하도록 content NOT NULL 제약 해제 +ALTER TABLE question ALTER COLUMN content DROP NOT NULL; +ALTER TABLE question_comment ALTER COLUMN content DROP NOT NULL; \ No newline at end of file