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