diff --git a/README.md b/README.md index 75c9cf8..e557319 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ PinIt 이 추구하는 핵심 목적은 다음 세 가지입니다. 사용자가 실제로 수행하는 “할 일/작업”에 해당합니다. * 일정 타입 (집중 작업, 행정 작업, 짧은 업무 등) -* 중요도 / 긴급도 +* 중요도 / 난이도 * 예상 소요 시간 * 마감 일자 * 현재 상태 (예정, 진행 중, 완료 등) @@ -78,7 +78,7 @@ PinIt 이 추구하는 핵심 목적은 다음 세 가지입니다. * **일정 생성** - * 일정의 기본 정보(제목, 타입, 마감일, 중요도, 긴급도, 예상 소요 시간 등)를 입력받아 생성 + * 일정의 기본 정보(제목, 타입, 마감일, 중요도, 난이도, 예상 소요 시간 등)를 입력받아 생성 * **일정 조회** * 특정 날짜의 일정 목록 조회 diff --git a/src/main/java/me/gg/pinit/pinittask/application/schedule/dto/ScheduleDependencyAdjustCommand.java b/src/main/java/me/gg/pinit/pinittask/application/schedule/dto/ScheduleDependencyAdjustCommand.java index da8efdd..674626b 100644 --- a/src/main/java/me/gg/pinit/pinittask/application/schedule/dto/ScheduleDependencyAdjustCommand.java +++ b/src/main/java/me/gg/pinit/pinittask/application/schedule/dto/ScheduleDependencyAdjustCommand.java @@ -14,34 +14,34 @@ import java.util.Objects; public class ScheduleDependencyAdjustCommand { - private Long scheduleId; + private final Long scheduleId; @Getter - private Long ownerId; + private final Long ownerId; @Getter - private String title; + private final String title; @Getter - private String description; + private final String description; @Getter - private ZonedDateTime deadline; + private final ZonedDateTime deadline; @Getter - private Integer importance; + private final Integer importance; @Getter - private Integer urgency; + private final Integer difficulty; @Getter - private TaskType taskType; + private final TaskType taskType; @Getter - private ZonedDateTime date; - private List removeDependencies; - private List addDependencies; + private final ZonedDateTime date; + private final List removeDependencies; + private final List addDependencies; - public ScheduleDependencyAdjustCommand(Long scheduleId, Long ownerId, String title, String description, ZonedDateTime deadline, Integer importance, Integer urgency, TaskType taskType, ZonedDateTime date, List removeDependencies, List addDependencies) { + public ScheduleDependencyAdjustCommand(Long scheduleId, Long ownerId, String title, String description, ZonedDateTime deadline, Integer importance, Integer difficulty, TaskType taskType, ZonedDateTime date, List removeDependencies, List addDependencies) { this.scheduleId = scheduleId; this.ownerId = ownerId; this.title = title; this.description = description; this.deadline = deadline; this.importance = importance; - this.urgency = urgency; + this.difficulty = difficulty; this.taskType = taskType; this.date = date; this.removeDependencies = removeDependencies; @@ -59,7 +59,7 @@ public Schedule getTemporalSchedule() { description, date, new TemporalConstraint(deadline, Duration.ZERO, taskType), - new ImportanceConstraint(importance, urgency) + new ImportanceConstraint(importance, difficulty) ); } @@ -69,7 +69,7 @@ public SchedulePatch getSchedulePatch() { .setDescription(description) .setDeadline(deadline) .setImportance(importance) - .setUrgency(urgency) + .setDifficulty(difficulty) .setTaskType(taskType) .setDate(date); } diff --git a/src/main/java/me/gg/pinit/pinittask/domain/schedule/model/Schedule.java b/src/main/java/me/gg/pinit/pinittask/domain/schedule/model/Schedule.java index 407723d..4c2dd1d 100644 --- a/src/main/java/me/gg/pinit/pinittask/domain/schedule/model/Schedule.java +++ b/src/main/java/me/gg/pinit/pinittask/domain/schedule/model/Schedule.java @@ -107,7 +107,7 @@ public boolean isSuspended() { public void patch(SchedulePatch patch) { checkStateIsNotCompleted(); patch.importance().ifPresent(this::changeImportance); - patch.urgency().ifPresent(this::changeUrgency); + patch.difficulty().ifPresent(this::changeDifficulty); patch.title().ifPresent(this::setTitle); patch.description().ifPresent(this::setDescription); patch.deadline().ifPresent(this::changeDeadline); @@ -149,8 +149,8 @@ public void changeImportance(int newImportance) { this.importanceConstraint = this.importanceConstraint.changeImportance(newImportance); } - public void changeUrgency(int newUrgency) { - this.importanceConstraint = this.importanceConstraint.changeUrgency(newUrgency); + public void changeDifficulty(int newDifficulty) { + this.importanceConstraint = this.importanceConstraint.changeDifficultyLevel(newDifficulty); } public String getState() { diff --git a/src/main/java/me/gg/pinit/pinittask/domain/schedule/patch/SchedulePatch.java b/src/main/java/me/gg/pinit/pinittask/domain/schedule/patch/SchedulePatch.java index 1164992..3d0c594 100644 --- a/src/main/java/me/gg/pinit/pinittask/domain/schedule/patch/SchedulePatch.java +++ b/src/main/java/me/gg/pinit/pinittask/domain/schedule/patch/SchedulePatch.java @@ -10,7 +10,7 @@ public final class SchedulePatch { private String description; private ZonedDateTime deadline; private Integer importance; - private Integer urgency; + private Integer difficulty; private TaskType taskType; private ZonedDateTime date; @@ -34,8 +34,8 @@ public SchedulePatch setImportance(Integer v) { return this; } - public SchedulePatch setUrgency(Integer v) { - this.urgency = v; + public SchedulePatch setDifficulty(Integer v) { + this.difficulty = v; return this; } @@ -65,8 +65,8 @@ public Optional importance() { return Optional.ofNullable(importance); } - public Optional urgency() { - return Optional.ofNullable(urgency); + public Optional difficulty() { + return Optional.ofNullable(difficulty); } public Optional taskType() { @@ -79,7 +79,7 @@ public Optional date() { public boolean isEmpty() { return title == null && description == null && deadline == null - && importance == null && urgency == null && taskType == null && date == null; + && importance == null && difficulty == null && taskType == null && date == null; } } diff --git a/src/main/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraint.java b/src/main/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraint.java index cda6e28..550109c 100644 --- a/src/main/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraint.java +++ b/src/main/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraint.java @@ -5,48 +5,59 @@ import lombok.Getter; import java.util.Objects; +import java.util.Set; @Getter @Embeddable public class ImportanceConstraint { + private static final Set VALID_DIFFICULTY_LEVELS = Set.of(1, 2, 3, 5, 8, 13, 21); + @Column(name = "importance_level") private int importance; - @Column(name = "urgency_level") - private int urgency; + @Column(name = "difficulty_level") + private int difficulty; protected ImportanceConstraint() {} - public ImportanceConstraint(int importance, int urgency) { + public ImportanceConstraint(int importance, int difficulty) { + validateImportanceLevel(importance); this.importance = importance; - this.urgency = urgency; + validateDifficultyLevel(difficulty); + this.difficulty = difficulty; } public ImportanceConstraint changeImportance(int importance) { - validateLevel(importance); - return new ImportanceConstraint(importance, this.urgency); + validateImportanceLevel(importance); + return new ImportanceConstraint(importance, this.difficulty); } - public ImportanceConstraint changeUrgency(int urgency) { - validateLevel(urgency); - return new ImportanceConstraint(this.importance, urgency); + public ImportanceConstraint changeDifficultyLevel(int difficulty) { + validateDifficultyLevel(difficulty); + return new ImportanceConstraint(this.importance, difficulty); } @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; ImportanceConstraint that = (ImportanceConstraint) o; - return importance == that.importance && urgency == that.urgency; + return importance == that.importance && difficulty == that.difficulty; } @Override public int hashCode() { - return Objects.hash(importance, urgency); + return Objects.hash(importance, difficulty); } - private void validateLevel(int level) { + private void validateImportanceLevel(int level) { if (level < 1 || level > 9) { - throw new IllegalArgumentException("중요도와 긴급도 레벨은 1에서 9 사이여야 합니다."); + throw new IllegalArgumentException("중요도 레벨은 1에서 9 사이여야 합니다."); + } + } + + private void validateDifficultyLevel(int difficulty) { + if (!VALID_DIFFICULTY_LEVELS.contains(difficulty)) { + throw new IllegalArgumentException("난이도 레벨은 1, 2, 3, 5, 8, 13, 21 중 하나여야 합니다."); } } } diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleRequest.java b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleRequest.java index a3b418c..23941e6 100644 --- a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleRequest.java +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleRequest.java @@ -6,8 +6,8 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import me.gg.pinit.pinittask.application.schedule.dto.DependencyDto; import me.gg.pinit.pinittask.application.datetime.DateTimeUtils; +import me.gg.pinit.pinittask.application.schedule.dto.DependencyDto; import me.gg.pinit.pinittask.application.schedule.dto.ScheduleDependencyAdjustCommand; import me.gg.pinit.pinittask.domain.schedule.model.TaskType; @@ -33,9 +33,9 @@ public record ScheduleRequest( Integer importance, @NotNull @Min(1) - @Max(9) - @Schema(description = "긴급도 (1~9)", example = "7") - Integer urgency, + @Max(21) + @Schema(description = "난이도 (21 이하의 피보나치 수)", example = "3") + Integer difficulty, @NotNull @Schema(description = "작업 유형", example = "TASK") TaskType taskType, @@ -58,7 +58,7 @@ public ScheduleDependencyAdjustCommand toCommand(Long scheduleId, Long ownerId, description, dateTimeUtils.toZonedDateTime(deadline.dateTime(), deadline.zoneId()), importance, - urgency, + difficulty, taskType, dateTimeUtils.toZonedDateTime(date.dateTime(), date.zoneId()), remove, diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleResponse.java b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleResponse.java index bfce604..396a675 100644 --- a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleResponse.java +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/ScheduleResponse.java @@ -23,8 +23,8 @@ public record ScheduleResponse( DateTimeWithZone deadline, @Schema(description = "중요도") int importance, - @Schema(description = "긴급도") - int urgency, + @Schema(description = "난이도") + int difficulty, @Schema(description = "누적 작업 시간") Duration duration, @Schema(description = "현재 상태") @@ -42,7 +42,7 @@ public static ScheduleResponse from(Schedule schedule) { DateTimeWithZone.from(schedule.getDesignatedStartTime()), DateTimeWithZone.from(temporal.getDeadline()), importanceConstraint.getImportance(), - importanceConstraint.getUrgency(), + importanceConstraint.getDifficulty(), history.getElapsedTime(), schedule.getState() ); diff --git a/src/test/java/me/gg/pinit/pinittask/application/schedule/service/ScheduleAdjustmentServiceTest.java b/src/test/java/me/gg/pinit/pinittask/application/schedule/service/ScheduleAdjustmentServiceTest.java index a28d432..37e49e2 100644 --- a/src/test/java/me/gg/pinit/pinittask/application/schedule/service/ScheduleAdjustmentServiceTest.java +++ b/src/test/java/me/gg/pinit/pinittask/application/schedule/service/ScheduleAdjustmentServiceTest.java @@ -45,7 +45,7 @@ void createSchedule() { "DESC", now.plusHours(4), 5, - 6, + 5, TaskType.DEEP_WORK, now, Collections.emptyList(), @@ -116,7 +116,7 @@ void adjustSchedule() { assertEquals("NEW_TITLE", patch.title().orElse(null)); assertEquals("NEW_DESC", patch.description().orElse(null)); assertEquals(9, patch.importance().orElse(-1)); - assertEquals(3, patch.urgency().orElse(-1)); + assertEquals(3, patch.difficulty().orElse(-1)); assertEquals(TaskType.QUICK_TASK, patch.taskType().orElse(null)); verify(dependencyService).deleteAll(anyList()); diff --git a/src/test/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraintTest.java b/src/test/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraintTest.java index 2a4d506..4823a53 100644 --- a/src/test/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraintTest.java +++ b/src/test/java/me/gg/pinit/pinittask/domain/schedule/vo/ImportanceConstraintTest.java @@ -2,7 +2,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.mockito.internal.matchers.Equals; import static org.junit.jupiter.api.Assertions.*; @@ -26,4 +25,26 @@ class ImportanceConstraintTest { //then assertNotEquals(constraint, differentConstraint, "ImportanceConstraint 객체가 서로 다른 값으로 생성되었을 때 equals 메서드는 false를 반환해야 합니다."); } -} \ No newline at end of file + + @DisplayName("허용되지 않은 난이도 레벨로 생성 시 예외가 발생해야 한다") + @Test + void DifficultyLevel_허용되지_않은_값이라면_예외_발생() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> new ImportanceConstraint(1, 4), + "허용되지 않은 난이도 레벨로 ImportanceConstraint를 생성하면 IllegalArgumentException이 발생해야 합니다."); + + assertEquals("난이도 레벨은 1, 2, 3, 5, 8, 13, 21 중 하나여야 합니다.", exception.getMessage()); + } + + @DisplayName("허용되지 않은 난이도 레벨로 변경 시 예외가 발생해야 한다") + @Test + void changeDifficultyLevel_허용되지_않은_값이라면_예외_발생() { + ImportanceConstraint constraint = new ImportanceConstraint(1, 3); + + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> constraint.changeDifficultyLevel(0), + "허용되지 않은 난이도 레벨로 변경을 시도하면 IllegalArgumentException이 발생해야 합니다."); + + assertEquals("난이도 레벨은 1, 2, 3, 5, 8, 13, 21 중 하나여야 합니다.", exception.getMessage()); + } +}