Repository: debate-timer/debate-timer-be
Pull request #141: [REFACTOR] Blank 검증을 DTO에서 일관성있게 수행
Author: login: coli-geonwoo
Labels: name: refactor
description: 리팩토링
Created: 2025-04-02T09:10:22Z | Merged: 2025-04-02T09:35:00Z

# 🚩 연관 이슈
closed #140 

# 🗣️ 리뷰 요구사항 (선택)
- 테스트 필요하다 vs Valid 테스트하는 거므로 필요치 않다

Linked issue #140: [REFACTOR] NotBlank 검증 Dto 단에서 검증
### ✨ Description
- NotBlank 로직을 Dto 단에서 통일성 있게 처리하도록 수정합니다.

### ✨ Time(마감기한)


Diff:
diff --git a/src/main/java/com/debatetimer/domain/DebateTable.java b/src/main/java/com/debatetimer/domain/DebateTable.java
index 79f2de74..41161031 100644
--- a/src/main/java/com/debatetimer/domain/DebateTable.java
+++ b/src/main/java/com/debatetimer/domain/DebateTable.java
@@ -68,7 +68,7 @@ protected final void updateTable(DebateTable renewTable) {
     }
 
     private void validate(String name) {
-        if (name.isBlank() || name.length() > NAME_MAX_LENGTH) {
+        if (name.length() > NAME_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TABLE_NAME_LENGTH);
         }
         if (!name.matches(NAME_REGEX)) {
diff --git a/src/main/java/com/debatetimer/domain/DebateTimeBox.java b/src/main/java/com/debatetimer/domain/DebateTimeBox.java
index c3115f4a..c0409032 100644
--- a/src/main/java/com/debatetimer/domain/DebateTimeBox.java
+++ b/src/main/java/com/debatetimer/domain/DebateTimeBox.java
@@ -34,11 +34,18 @@ protected DebateTimeBox(int sequence, Stance stance, int time, String speaker) {
         this.sequence = sequence;
         this.stance = stance;
         this.time = time;
-        this.speaker = speaker;
+        this.speaker = initializeSpeaker(speaker);
+    }
+
+    private String initializeSpeaker(String speaker) {
+        if (speaker == null || speaker.isBlank()) {
+            return null;
+        }
+        return speaker;
     }
 
     private void validateSpeaker(String speaker) {
-        if (speaker != null && (speaker.isBlank() || speaker.length() > SPEAKER_MAX_LENGTH)) {
+        if (speaker != null && speaker.length() > SPEAKER_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH);
         }
     }
diff --git a/src/main/java/com/debatetimer/domain/customize/CustomizeTable.java b/src/main/java/com/debatetimer/domain/customize/CustomizeTable.java
index 90a868a0..0bc38a83 100644
--- a/src/main/java/com/debatetimer/domain/customize/CustomizeTable.java
+++ b/src/main/java/com/debatetimer/domain/customize/CustomizeTable.java
@@ -55,7 +55,7 @@ public void update(CustomizeTable renewTable) {
     }
 
     private void validateTeamName(String teamName) {
-        if (teamName.isBlank() || teamName.length() > TEAM_NAME_MAX_LENGTH) {
+        if (teamName.length() > TEAM_NAME_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TEAM_NAME_LENGTH);
         }
         if (!teamName.matches(TEAM_NAME_REGEX)) {
diff --git a/src/main/java/com/debatetimer/domain/customize/CustomizeTimeBox.java b/src/main/java/com/debatetimer/domain/customize/CustomizeTimeBox.java
index 065a3377..a64217b8 100644
--- a/src/main/java/com/debatetimer/domain/customize/CustomizeTimeBox.java
+++ b/src/main/java/com/debatetimer/domain/customize/CustomizeTimeBox.java
@@ -120,7 +120,7 @@ private void validateNotTimeBasedType(CustomizeBoxType boxType) {
     }
 
     private void validateSpeechType(String speechType) {
-        if (speechType.isBlank() || speechType.length() > SPEECH_TYPE_MAX_LENGTH) {
+        if (speechType.length() > SPEECH_TYPE_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEECH_TYPE_LENGTH);
         }
     }
diff --git a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java
index 108c840f..da62fb26 100644
--- a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java
@@ -4,13 +4,14 @@
 import com.debatetimer.domain.customize.CustomizeTable;
 import com.debatetimer.domain.customize.CustomizeTimeBox;
 import com.debatetimer.domain.member.Member;
+import jakarta.validation.Valid;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 public record CustomizeTableCreateRequest(
-        CustomizeTableInfoCreateRequest info,
-        List<CustomizeTimeBoxCreateRequest> table
+        @Valid CustomizeTableInfoCreateRequest info,
+        @Valid List<CustomizeTimeBoxCreateRequest> table
 ) {
 
     public CustomizeTable toTable(Member member) {
diff --git a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTimeBoxCreateRequest.java b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTimeBoxCreateRequest.java
index 3ce029ae..a040e47e 100644
--- a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTimeBoxCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTimeBoxCreateRequest.java
@@ -5,15 +5,16 @@
 import com.debatetimer.domain.customize.CustomizeTable;
 import com.debatetimer.domain.customize.CustomizeTimeBox;
 import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 
 public record CustomizeTimeBoxCreateRequest(
-        @NotBlank
+        @NotNull
         Stance stance,
 
         @NotBlank
         String speechType,
 
-        @NotBlank
+        @NotNull
         CustomizeBoxType boxType,
 
         int time,
diff --git a/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTableCreateRequest.java b/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTableCreateRequest.java
index 5c193733..9e86c58a 100644
--- a/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTableCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTableCreateRequest.java
@@ -4,12 +4,15 @@
 import com.debatetimer.domain.member.Member;
 import com.debatetimer.domain.parliamentary.ParliamentaryTable;
 import com.debatetimer.domain.parliamentary.ParliamentaryTimeBox;
+import jakarta.validation.Valid;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-public record ParliamentaryTableCreateRequest(ParliamentaryTableInfoCreateRequest info,
-                                              List<ParliamentaryTimeBoxCreateRequest> table) {
+public record ParliamentaryTableCreateRequest(
+        @Valid ParliamentaryTableInfoCreateRequest info,
+        @Valid List<ParliamentaryTimeBoxCreateRequest> table
+) {
 
     public ParliamentaryTable toTable(Member member) {
         return info.toTable(member);
diff --git a/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTimeBoxCreateRequest.java b/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTimeBoxCreateRequest.java
index 9313ea90..7cf15f01 100644
--- a/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTimeBoxCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/parliamentary/request/ParliamentaryTimeBoxCreateRequest.java
@@ -1,17 +1,17 @@
 package com.debatetimer.dto.parliamentary.request;
 
-import com.debatetimer.domain.parliamentary.ParliamentaryBoxType;
 import com.debatetimer.domain.Stance;
+import com.debatetimer.domain.parliamentary.ParliamentaryBoxType;
 import com.debatetimer.domain.parliamentary.ParliamentaryTable;
 import com.debatetimer.domain.parliamentary.ParliamentaryTimeBox;
-import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Positive;
 
 public record ParliamentaryTimeBoxCreateRequest(
-        @NotBlank
+        @NotNull
         Stance stance,
 
-        @NotBlank
+        @NotNull
         ParliamentaryBoxType type,
 
         @Positive
diff --git a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java
index 3012958a..c051f94c 100644
--- a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java
@@ -4,12 +4,15 @@
 import com.debatetimer.domain.member.Member;
 import com.debatetimer.domain.timebased.TimeBasedTable;
 import com.debatetimer.domain.timebased.TimeBasedTimeBox;
+import jakarta.validation.Valid;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-public record TimeBasedTableCreateRequest(TimeBasedTableInfoCreateRequest info,
-                                          List<TimeBasedTimeBoxCreateRequest> table) {
+public record TimeBasedTableCreateRequest(
+        @Valid TimeBasedTableInfoCreateRequest info,
+        @Valid List<TimeBasedTimeBoxCreateRequest> table
+) {
 
     public TimeBasedTable toTable(Member member) {
         return info.toTable(member);
diff --git a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java
index d9419190..10dea4e1 100644
--- a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java
+++ b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java
@@ -4,13 +4,13 @@
 import com.debatetimer.domain.timebased.TimeBasedBoxType;
 import com.debatetimer.domain.timebased.TimeBasedTable;
 import com.debatetimer.domain.timebased.TimeBasedTimeBox;
-import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
 
 public record TimeBasedTimeBoxCreateRequest(
-        @NotBlank
+        @NotNull
         Stance stance,
 
-        @NotBlank
+        @NotNull
         TimeBasedBoxType type,
 
         int time,
diff --git a/src/test/java/com/debatetimer/domain/DebateTableTest.java b/src/test/java/com/debatetimer/domain/DebateTableTest.java
index 3e35a8d5..3035f0c8 100644
--- a/src/test/java/com/debatetimer/domain/DebateTableTest.java
+++ b/src/test/java/com/debatetimer/domain/DebateTableTest.java
@@ -37,20 +37,12 @@ class Validate {
                     .hasMessage(ClientErrorCode.INVALID_TABLE_NAME_FORM.getMessage());
         }
 
-        @ValueSource(ints = {0, DebateTable.NAME_MAX_LENGTH + 1})
-        @ParameterizedTest
-        void 테이블_이름은_정해진_길이_이내여야_한다(int length) {
+        @Test
+        void 테이블_이름은_정해진_길이_이내여야_한다() {
             Member member = new Member("default@gmail.com");
-            assertThatThrownBy(() -> new DebateTableTestObject(member, "f".repeat(length), "agenda", true, true))
-                    .isInstanceOf(DTClientErrorException.class)
-                    .hasMessage(ClientErrorCode.INVALID_TABLE_NAME_LENGTH.getMessage());
-        }
+            String longTableName = "f".repeat(DebateTable.NAME_MAX_LENGTH + 1);
 
-        @ValueSource(strings = {"", "\t", "\n"})
-        @ParameterizedTest
-        void 테이블_이름은_적어도_한_자_있어야_한다(String name) {
-            Member member = new Member("default@gmail.com");
-            assertThatThrownBy(() -> new DebateTableTestObject(member, name, "agenda", true, true))
+            assertThatThrownBy(() -> new DebateTableTestObject(member, longTableName, "agenda", true, true))
                     .isInstanceOf(DTClientErrorException.class)
                     .hasMessage(ClientErrorCode.INVALID_TABLE_NAME_LENGTH.getMessage());
         }
diff --git a/src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java b/src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java
index f9f694c8..d6ea6af1 100644
--- a/src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java
+++ b/src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java
@@ -1,5 +1,6 @@
 package com.debatetimer.domain;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -8,6 +9,7 @@
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullSource;
 import org.junit.jupiter.params.provider.ValueSource;
 
 class DebateTimeBoxTest {
@@ -42,23 +44,29 @@ class ValidateTime {
     @Nested
     class ValidateSpeaker {
 
-        @ParameterizedTest
-        @ValueSource(ints = {0, DebateTimeBox.SPEAKER_MAX_LENGTH + 1})
-        void 발언자는_일정길이_이내로_허용된다(int length) {
-            String speaker = "k".repeat(length);
+        @Test
+        void 발언자_이름은_일정길이_이내로_허용된다() {
+            String speaker = "k".repeat(DebateTimeBox.SPEAKER_MAX_LENGTH + 1);
 
             assertThatThrownBy(() -> new DebateTimeBoxTestObject(1, Stance.CONS, 60, speaker))
                     .isInstanceOf(DTClientErrorException.class)
                     .hasMessage(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH.getMessage());
         }
 
-        @Test
-        void 발언자는_빈_값이_허용된다() {
-            String speaker = null;
-
+        @NullSource
+        @ParameterizedTest
+        void 발언자는_빈_값이_허용된다(String speaker) {
             assertThatCode(() -> new DebateTimeBoxTestObject(1, Stance.CONS, 60, speaker))
                     .doesNotThrowAnyException();
         }
+
+        @ValueSource(strings = {"   ", " "})
+        @ParameterizedTest
+        void 발언자는_공백이_입력되면_null로_저장된다(String speaker) {
+            DebateTimeBoxTestObject timeBox = new DebateTimeBoxTestObject(1, Stance.CONS, 60, speaker);
+
+            assertThat(timeBox.getSpeaker()).isNull();
+        }
     }
 
     private static class DebateTimeBoxTestObject extends DebateTimeBox {
diff --git a/src/test/java/com/debatetimer/domain/customize/CustomizeTableTest.java b/src/test/java/com/debatetimer/domain/customize/CustomizeTableTest.java
index d47b287d..e2f5d389 100644
--- a/src/test/java/com/debatetimer/domain/customize/CustomizeTableTest.java
+++ b/src/test/java/com/debatetimer/domain/customize/CustomizeTableTest.java
@@ -29,22 +29,24 @@ class GetType {
     @Nested
     class ValidateTeamName {
 
-        @ValueSource(ints = {0, CustomizeTable.TEAM_NAME_MAX_LENGTH + 1})
-        @ParameterizedTest
-        void 찬성_팀_이름은_정해진_길이_이내여야_한다(int length) {
+        @Test
+        void 찬성_팀_이름은_정해진_길이_이내여야_한다() {
             Member member = new Member("default@gmail.com");
+            String longProsTeamName = "f".repeat(CustomizeTable.TEAM_NAME_MAX_LENGTH + 1);
+
             assertThatThrownBy(
-                    () -> new CustomizeTable(member, "name", "agenda", true, true, "f".repeat(length), "cons"))
+                    () -> new CustomizeTable(member, "name", "agenda", true, true, longProsTeamName, "cons"))
                     .isInstanceOf(DTClientErrorException.class)
                     .hasMessage(ClientErrorCode.INVALID_TEAM_NAME_LENGTH.getMessage());
         }
 
-        @ValueSource(ints = {0, CustomizeTable.TEAM_NAME_MAX_LENGTH + 1})
-        @ParameterizedTest
-        void 반대_팀_이름은_정해진_길이_이내여야_한다(int length) {
+        @Test
+        void 반대_팀_이름은_정해진_길이_이내여야_한다() {
             Member member = new Member("default@gmail.com");
+            String longConsTeamName = "f".repeat(CustomizeTable.TEAM_NAME_MAX_LENGTH + 1);
+
             assertThatThrownBy(
-                    () -> new CustomizeTable(member, "name", "agenda", true, true, "pros", "f".repeat(length)))
+                    () -> new CustomizeTable(member, "name", "agenda", true, true, "pros", longConsTeamName))
                     .isInstanceOf(DTClientErrorException.class)
                     .hasMessage(ClientErrorCode.INVALID_TEAM_NAME_LENGTH.getMessage());
         }
diff --git a/src/test/java/com/debatetimer/domain/customize/CustomizeTimeBoxTest.java b/src/test/java/com/debatetimer/domain/customize/CustomizeTimeBoxTest.java
index 911016b1..1b7780f6 100644
--- a/src/test/java/com/debatetimer/domain/customize/CustomizeTimeBoxTest.java
+++ b/src/test/java/com/debatetimer/domain/customize/CustomizeTimeBoxTest.java
@@ -8,8 +8,6 @@
 import com.debatetimer.exception.errorcode.ClientErrorCode;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
 
 class CustomizeTimeBoxTest {
 
@@ -81,11 +79,10 @@ class ValidateCustomizeTime {
                     .hasMessage(ClientErrorCode.INVALID_TIME_BASED_TIME.getMessage());
         }
 
-        @ParameterizedTest
-        @ValueSource(ints = {0, CustomizeTimeBox.SPEECH_TYPE_MAX_LENGTH + 1})
-        void 발언_유형의_길이는_일정_범위_이내여야_한다(int length) {
+        @Test
+        void 발언_유형의_길이는_일정_범위_이내여야_한다() {
             CustomizeTable table = new CustomizeTable();
-            String longSpeechType = "s".repeat(length);
+            String longSpeechType = "s".repeat(CustomizeTimeBox.SPEECH_TYPE_MAX_LENGTH + 1);
 
             assertThatThrownBy(
                     () -> new CustomizeTimeBox(table, 1, Stance.NEUTRAL, longSpeechType, CustomizeBoxType.TIME_BASED,


Reviews:
user: login: unifolio0
body: /noti
@coli-geonwoo 
간단한 리뷰 2개 남겼어요
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T09:15:22Z
user: login: coli-geonwoo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T09:22:02Z
user: login: unifolio0
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T09:23:09Z
user: login: unifolio0
body: LGTM 👍 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-02T09:24:12Z
user: login: leegwichan
body: /noti @coli-geonwoo 
콜리와 비토를 믿겠습니다. Approve!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-02T09:31:50Z

Review comments:
diff_hunk: @@ -34,11 +34,18 @@ protected DebateTimeBox(int sequence, Stance stance, int time, String speaker) {
         this.sequence = sequence;
         this.stance = stance;
         this.time = time;
-        this.speaker = speaker;
+        this.speaker = initializeSpeaker(speaker);
+    }
+
+    private String initializeSpeaker(String speaker) {
+        if (speaker == null || speaker.isBlank()) {
+            return null;
+        }
+        return speaker;
     }
 
     private void validateSpeaker(String speaker) {
-        if (speaker != null && (speaker.isBlank() || speaker.length() > SPEAKER_MAX_LENGTH)) {
+        if (speaker != null && speaker.length() > SPEAKER_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH);
         }
     }
path: src/main/java/com/debatetimer/domain/DebateTimeBox.java
user: login: unifolio0
body: validateSpeaker로 null이면 안되는데 initializeSpeaker에서는 null이면 null을 반환한다...?
심지어 validateSpeaker를 한 다음에 initializeSpeaker를 하네요
created_at: 2025-04-02T09:12:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -42,20 +43,18 @@ class ValidateTime {
     @Nested
     class ValidateSpeaker {
 
-        @ParameterizedTest
-        @ValueSource(ints = {0, DebateTimeBox.SPEAKER_MAX_LENGTH + 1})
-        void 발언자는_일정길이_이내로_허용된다(int length) {
-            String speaker = "k".repeat(length);
+        @Test
+        void 발언자는_일정길이_이내로_허용된다() {
path: src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java
user: login: unifolio0
body: 테스트 이름 좀 더 자연스럽게 지어주세요
created_at: 2025-04-02T09:15:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -42,20 +43,18 @@ class ValidateTime {
     @Nested
     class ValidateSpeaker {
 
-        @ParameterizedTest
-        @ValueSource(ints = {0, DebateTimeBox.SPEAKER_MAX_LENGTH + 1})
-        void 발언자는_일정길이_이내로_허용된다(int length) {
-            String speaker = "k".repeat(length);
+        @Test
+        void 발언자는_일정길이_이내로_허용된다() {
path: src/test/java/com/debatetimer/domain/DebateTimeBoxTest.java
user: login: coli-geonwoo
body: `발언자_이름은_일정길이_이내로_허용된다`로 수정했슴다
created_at: 2025-04-02T09:20:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,11 +34,18 @@ protected DebateTimeBox(int sequence, Stance stance, int time, String speaker) {
         this.sequence = sequence;
         this.stance = stance;
         this.time = time;
-        this.speaker = speaker;
+        this.speaker = initializeSpeaker(speaker);
+    }
+
+    private String initializeSpeaker(String speaker) {
+        if (speaker == null || speaker.isBlank()) {
+            return null;
+        }
+        return speaker;
     }
 
     private void validateSpeaker(String speaker) {
-        if (speaker != null && (speaker.isBlank() || speaker.length() > SPEAKER_MAX_LENGTH)) {
+        if (speaker != null && speaker.length() > SPEAKER_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH);
         }
     }
path: src/main/java/com/debatetimer/domain/DebateTimeBox.java
user: login: coli-geonwoo
body: null이면 됩니다.
created_at: 2025-04-02T09:20:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,11 +34,18 @@ protected DebateTimeBox(int sequence, Stance stance, int time, String speaker) {
         this.sequence = sequence;
         this.stance = stance;
         this.time = time;
-        this.speaker = speaker;
+        this.speaker = initializeSpeaker(speaker);
+    }
+
+    private String initializeSpeaker(String speaker) {
+        if (speaker == null || speaker.isBlank()) {
+            return null;
+        }
+        return speaker;
     }
 
     private void validateSpeaker(String speaker) {
-        if (speaker != null && (speaker.isBlank() || speaker.length() > SPEAKER_MAX_LENGTH)) {
+        if (speaker != null && speaker.length() > SPEAKER_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH);
         }
     }
path: src/main/java/com/debatetimer/domain/DebateTimeBox.java
user: login: coli-geonwoo
body: null이 아니고 + 길이 이상이면 -> 에러 반환하도록 validate 했는데...
created_at: 2025-04-02T09:21:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -34,11 +34,18 @@ protected DebateTimeBox(int sequence, Stance stance, int time, String speaker) {
         this.sequence = sequence;
         this.stance = stance;
         this.time = time;
-        this.speaker = speaker;
+        this.speaker = initializeSpeaker(speaker);
+    }
+
+    private String initializeSpeaker(String speaker) {
+        if (speaker == null || speaker.isBlank()) {
+            return null;
+        }
+        return speaker;
     }
 
     private void validateSpeaker(String speaker) {
-        if (speaker != null && (speaker.isBlank() || speaker.length() > SPEAKER_MAX_LENGTH)) {
+        if (speaker != null && speaker.length() > SPEAKER_MAX_LENGTH) {
             throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER_LENGTH);
         }
     }
path: src/main/java/com/debatetimer/domain/DebateTimeBox.java
user: login: unifolio0
body: 잠은 내가 안잤네
created_at: 2025-04-02T09:23:09Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-02T09:12:30Z
body: ## Test Results
118 files  118 suites   12s ⏱️
259 tests 259 ✅ 0 💤 0 ❌
271 runs  271 ✅ 0 💤 0 ❌

Results for commit 4e4213c5.

[test-results]:data:application/gzip;base64,H4sIAAQC7WcC/12MSw7CIBQAr9KwdtFH+XoZQ/kkxLYYPivj3aWkVnQ5M8k8kfOLTeg6AIjLgFLxuUNToso+bLvAlWvLe8VUfuiWitb/6u4fVY2ncMovP8LGGOJhYtnak8MB57Iz32Pjbti4/+mwrj5XQMQSDJOmBCamhWNCznwUEqg0fDbcAFWEWSvQ6w3HekT+CAEAAA==

:recycle: This comment has been updated with latest results.
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-04-02T09:12:32Z
body: ### 📝 Test Coverage Report
|Overall Project|76.29%|:x:|
|:-|:-|:-:|
|Files changed|100%|:green_apple:|
<br>

|File|Coverage||
|:-|:-|:-:|
|[CustomizeTable.java](https://github.com/debate-timer/debate-timer-be/blob/4e4213c54136c8f689b7089159d7bd7d15a46ee8/src%2Fmain%2Fjava%2Fcom%2Fdebatetimer%2Fdomain%2Fcustomize%2FCustomizeTable.java)|100%|:green_apple:|
|[DebateTable.java](https://github.com/debate-timer/debate-timer-be/blob/4e4213c54136c8f689b7089159d7bd7d15a46ee8/src%2Fmain%2Fjava%2Fcom%2Fdebatetimer%2Fdomain%2FDebateTable.java)|100%|:green_apple:|
|[DebateTimeBox.java](https://github.com/debate-timer/debate-timer-be/blob/4e4213c54136c8f689b7089159d7bd7d15a46ee8/src%2Fmain%2Fjava%2Fcom%2Fdebatetimer%2Fdomain%2FDebateTimeBox.java)|100%|:green_apple:|
|[CustomizeTimeBox.java](https://github.com/debate-timer/debate-timer-be/blob/4e4213c54136c8f689b7089159d7bd7d15a46ee8/src%2Fmain%2Fjava%2Fcom%2Fdebatetimer%2Fdomain%2Fcustomize%2FCustomizeTimeBox.java)|95.9%|:green_apple:|
author_association: NONE
user: login: coli-geonwoo
created_at: 2025-04-02T09:23:51Z
body: /noti

@unifolio0 재검토 해주세유
author_association: CONTRIBUTOR