Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PinIt 이 추구하는 핵심 목적은 다음 세 가지입니다.
사용자가 실제로 수행하는 “할 일/작업”에 해당합니다.

* 일정 타입 (집중 작업, 행정 작업, 짧은 업무 등)
* 중요도 / 긴급도
* 중요도 / 난이도
* 예상 소요 시간
* 마감 일자
* 현재 상태 (예정, 진행 중, 완료 등)
Expand Down Expand Up @@ -78,7 +78,7 @@ PinIt 이 추구하는 핵심 목적은 다음 세 가지입니다.

* **일정 생성**

* 일정의 기본 정보(제목, 타입, 마감일, 중요도, 긴급도, 예상 소요 시간 등)를 입력받아 생성
* 일정의 기본 정보(제목, 타입, 마감일, 중요도, 난이도, 예상 소요 시간 등)를 입력받아 생성
* **일정 조회**

* 특정 날짜의 일정 목록 조회
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DependencyDto> removeDependencies;
private List<DependencyDto> addDependencies;
private final ZonedDateTime date;
private final List<DependencyDto> removeDependencies;
private final List<DependencyDto> addDependencies;

public ScheduleDependencyAdjustCommand(Long scheduleId, Long ownerId, String title, String description, ZonedDateTime deadline, Integer importance, Integer urgency, TaskType taskType, ZonedDateTime date, List<DependencyDto> removeDependencies, List<DependencyDto> addDependencies) {
public ScheduleDependencyAdjustCommand(Long scheduleId, Long ownerId, String title, String description, ZonedDateTime deadline, Integer importance, Integer difficulty, TaskType taskType, ZonedDateTime date, List<DependencyDto> removeDependencies, List<DependencyDto> 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;
Expand All @@ -59,7 +59,7 @@ public Schedule getTemporalSchedule() {
description,
date,
new TemporalConstraint(deadline, Duration.ZERO, taskType),
new ImportanceConstraint(importance, urgency)
new ImportanceConstraint(importance, difficulty)
);
}

Expand All @@ -69,7 +69,7 @@ public SchedulePatch getSchedulePatch() {
.setDescription(description)
.setDeadline(deadline)
.setImportance(importance)
.setUrgency(urgency)
.setDifficulty(difficulty)
.setTaskType(taskType)
.setDate(date);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down Expand Up @@ -65,8 +65,8 @@ public Optional<Integer> importance() {
return Optional.ofNullable(importance);
}

public Optional<Integer> urgency() {
return Optional.ofNullable(urgency);
public Optional<Integer> difficulty() {
return Optional.ofNullable(difficulty);
}

public Optional<TaskType> taskType() {
Expand All @@ -79,7 +79,7 @@ public Optional<ZonedDateTime> 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;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,59 @@
import lombok.Getter;

import java.util.Objects;
import java.util.Set;

@Getter
@Embeddable
public class ImportanceConstraint {
private static final Set<Integer> 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 중 하나여야 합니다.");
}
}
Comment on lines +58 to 62
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1) 문제점: 새로운 난이도 검증 로직(validateDifficultyLevel)과 changeDifficultyLevel 메서드에 대한 테스트 커버리지가 없습니다.

(2) 영향: 피보나치 수열 검증이 제대로 작동하는지 확인할 수 없으며, 유효하지 않은 값(예: 4, 6, 7, 9 등)이 입력되었을 때 예외가 올바르게 발생하는지 검증되지 않습니다.

(3) 수정 제안: 다음 테스트 케이스를 추가해야 합니다:

  • 유효한 피보나치 수(1, 2, 3, 5, 8, 13, 21) 입력 시 성공하는 테스트
  • 유효하지 않은 값(4, 6, 7, 9, 10 등) 입력 시 IllegalArgumentException이 발생하는 테스트
  • changeDifficultyLevel 메서드의 정상 동작 테스트

Copilot uses AI. Check for mistakes.
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "현재 상태")
Expand All @@ -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()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void createSchedule() {
"DESC",
now.plusHours(4),
5,
6,
5,
TaskType.DEEP_WORK,
now,
Collections.emptyList(),
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;

Expand All @@ -26,4 +25,26 @@ class ImportanceConstraintTest {
//then
assertNotEquals(constraint, differentConstraint, "ImportanceConstraint 객체가 서로 다른 값으로 생성되었을 때 equals 메서드는 false를 반환해야 합니다.");
}
}

@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());
}
}