From b5aee49dd7215d5be0e8a084047f5683e8403fa6 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:08:09 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=EC=9E=91=EC=97=85=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EC=88=98=EC=A0=95=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interfaces/dto/TaskCreateRequest.java | 76 +++++++++++++++++++ ...askRequest.java => TaskUpdateRequest.java} | 18 ++++- 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequest.java rename src/main/java/me/gg/pinit/pinittask/interfaces/dto/{TaskRequest.java => TaskUpdateRequest.java} (76%) diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequest.java b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequest.java new file mode 100644 index 00000000..cdadfcc1 --- /dev/null +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequest.java @@ -0,0 +1,76 @@ +package me.gg.pinit.pinittask.interfaces.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import me.gg.pinit.pinittask.application.datetime.DateTimeUtils; +import me.gg.pinit.pinittask.application.schedule.dto.DependencyDto; +import me.gg.pinit.pinittask.application.task.dto.TaskDependencyAdjustCommand; +import me.gg.pinit.pinittask.interfaces.utils.FibonacciDifficulty; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public record TaskCreateRequest( + @NotBlank + @Schema(description = "작업 제목", example = "스터디 준비") + String title, + @NotBlank + @Schema(description = "작업 설명", example = "다음 주 발표 자료 정리") + String description, + @NotNull + @Schema(description = "마감 기한", example = "{\"dateTime\":\"2024-03-01T18:00:00\",\"zoneId\":\"Asia/Seoul\"}") + @Valid + DateTimeWithZone dueDate, + @NotNull + @Min(1) + @Max(9) + @Schema(description = "중요도 (1~9)", example = "5") + Integer importance, + @NotNull + @FibonacciDifficulty + @Schema(description = "난이도 (피보나치 수: 1,2,3,5,8,13,21)", example = "5") + Integer difficulty, + @Schema(description = "추가할 의존 관계 목록 (생성 시 각 항목에 fromId 또는 toId 중 하나는 0)") + List<@Valid DependencyRequest> addDependencies +) { + public TaskDependencyAdjustCommand toCommand(Long taskId, Long ownerId, DateTimeUtils dateTimeUtils) { + validateMustContainSelfPlaceholder(addDependencies); + List remove = List.of(); // 생성 시 remove는 허용하지 않음 + List add = toDependencyDtos(addDependencies); + return new TaskDependencyAdjustCommand( + taskId, + ownerId, + title, + description, + dateTimeUtils.toZonedDateTime(dueDate.dateTime(), dueDate.zoneId()), + importance, + difficulty, + remove, + add + ); + } + + private List toDependencyDtos(List requests) { + return Optional.ofNullable(requests) + .orElseGet(ArrayList::new) + .stream() + .map(request -> new DependencyDto(null, request.fromId(), request.toId())) + .toList(); + } + + private void validateMustContainSelfPlaceholder(List dependencies) { + Optional.ofNullable(dependencies) + .orElseGet(ArrayList::new) + .forEach(dep -> { + if (dep.fromId() != 0L && dep.toId() != 0L) { + throw new IllegalArgumentException("작업 생성 시 의존 관계에는 fromId 또는 toId 중 하나가 0이어야 합니다."); + } + }); + } +} + diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskRequest.java b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskUpdateRequest.java similarity index 76% rename from src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskRequest.java rename to src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskUpdateRequest.java index d8e4d56e..72559a5d 100644 --- a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskRequest.java +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/TaskUpdateRequest.java @@ -15,7 +15,7 @@ import java.util.List; import java.util.Optional; -public record TaskRequest( +public record TaskUpdateRequest( @NotBlank @Schema(description = "작업 제목", example = "스터디 준비") String title, @@ -35,12 +35,14 @@ public record TaskRequest( @FibonacciDifficulty @Schema(description = "난이도 (피보나치 수: 1,2,3,5,8,13,21)", example = "5") Integer difficulty, - @Schema(description = "제거할 의존 관계 목록") + @Schema(description = "제거할 의존 관계 목록 (수정 시 0 사용 금지)") List<@Valid DependencyRequest> removeDependencies, - @Schema(description = "추가할 의존 관계 목록") + @Schema(description = "추가할 의존 관계 목록 (수정 시 0 사용 금지)") List<@Valid DependencyRequest> addDependencies ) { public TaskDependencyAdjustCommand toCommand(Long taskId, Long ownerId, DateTimeUtils dateTimeUtils) { + validateNoPlaceholder(removeDependencies); + validateNoPlaceholder(addDependencies); List remove = toDependencyDtos(removeDependencies); List add = toDependencyDtos(addDependencies); return new TaskDependencyAdjustCommand( @@ -56,6 +58,16 @@ public TaskDependencyAdjustCommand toCommand(Long taskId, Long ownerId, DateTime ); } + private void validateNoPlaceholder(List dependencies) { + Optional.ofNullable(dependencies) + .orElseGet(ArrayList::new) + .forEach(dep -> { + if (dep.fromId() == 0L || dep.toId() == 0L) { + throw new IllegalArgumentException("수정 요청에서는 의존 관계 ID에 0을 사용할 수 없습니다."); + } + }); + } + private List toDependencyDtos(List requests) { return Optional.ofNullable(requests) .orElseGet(ArrayList::new) From 7fc59c5215a6c2383d8ec68abfdad95412f788e4 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:08:35 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20updateTask=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=8A=A4=ED=99=80=EB=8D=94=200=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EC=8B=9C=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/service/TaskAdjustmentService.java | 1 + .../service/TaskAdjustmentServiceTest.java | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentService.java b/src/main/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentService.java index 5c135df4..f234d605 100644 --- a/src/main/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentService.java +++ b/src/main/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentService.java @@ -31,6 +31,7 @@ public Task updateTask(Long memberId, TaskDependencyAdjustCommand command) { if (taskId == null) { throw new IllegalArgumentException("taskId는 null일 수 없습니다."); } + command.validateNoPlaceholderForUpdate(); List removedDependencies = command.getRemoveDependencies(taskId); List addedDependencies = command.getAddDependencies(taskId); dependencyService.assertNoCycle(memberId, removedDependencies, addedDependencies); diff --git a/src/test/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentServiceTest.java b/src/test/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentServiceTest.java index 30a96ac1..db24c69b 100644 --- a/src/test/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentServiceTest.java +++ b/src/test/java/me/gg/pinit/pinittask/application/task/service/TaskAdjustmentServiceTest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.when; @@ -168,6 +169,26 @@ void updateTask_checksCycleAndAdjustsDependenciesAroundUpdate() { assertThat(savedDependenciesCaptor.getValue()).isSameAs(addedDependencies); } + @Test + @DisplayName("updateTask에서 0 플레이스홀더 사용 시 예외") + void updateTask_rejectsPlaceholderZero() { + Long memberId = 1L; + Long taskId = 10L; + TaskDependencyAdjustCommand command = new TaskDependencyAdjustCommand( + taskId, + memberId, + "title", + "desc", + ZonedDateTime.now(), + 5, + 5, + List.of(), + List.of(new DependencyDto(null, 0L, 2L)) + ); + + assertThrows(IllegalArgumentException.class, () -> taskAdjustmentService.updateTask(memberId, command)); + } + @SuppressWarnings("unchecked") private ArgumentCaptor> dependencyListCaptor() { return ArgumentCaptor.forClass(List.class); From a8b97710c1c50a5a5401bbb154955012e11eb1c9 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:08:44 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix:=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=EC=97=90=EC=84=9C=200=20=ED=94=8C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=8A=A4=ED=99=80=EB=8D=94=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=EA=B8=88=EC=A7=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/dto/TaskDependencyAdjustCommand.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommand.java b/src/main/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommand.java index d811faa8..c3e85392 100644 --- a/src/main/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommand.java +++ b/src/main/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommand.java @@ -64,6 +64,21 @@ public TaskPatch getTaskPatch() { .setDifficulty(difficulty); } + /** + * 업데이트 요청에서는 0 플레이스홀더 사용을 금지한다. + * (0은 새 Task 생성 시 자기 자신을 의미하므로 create 전용) + */ + public void validateNoPlaceholderForUpdate() { + if (taskId == null) { + return; + } + boolean hasPlaceholder = addDependencies.stream().anyMatch(this::hasPlaceholder) + || removeDependencies.stream().anyMatch(this::hasPlaceholder); + if (hasPlaceholder) { + throw new IllegalArgumentException("수정 요청에서는 fromId/toId에 0을 사용할 수 없습니다."); + } + } + public List getRemoveDependencies(Long selfId) { return removeDependencies.stream() .map(d -> new Dependency(ownerId, resolveId(d.getFromId(), selfId), resolveId(d.getToId(), selfId))) @@ -77,9 +92,14 @@ public List getAddDependencies(Long selfId) { } private Long resolveId(Long rawId, Long selfId) { - if (rawId == null) { + if (rawId == 0L) { return selfId; } return rawId; } + + private boolean hasPlaceholder(DependencyDto dto) { + return dto.getFromId() != null && dto.getFromId() == 0L + || dto.getToId() != null && dto.getToId() == 0L; + } } From b382825c626d0c4ed80f39efa99b72c5122f93fb Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:09:01 +0900 Subject: [PATCH 4/9] =?UTF-8?q?test:=20TaskDependencyAdjustCommand?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/TaskDependencyAdjustCommandTest.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommandTest.java diff --git a/src/test/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommandTest.java b/src/test/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommandTest.java new file mode 100644 index 00000000..f5c6426b --- /dev/null +++ b/src/test/java/me/gg/pinit/pinittask/application/task/dto/TaskDependencyAdjustCommandTest.java @@ -0,0 +1,59 @@ +package me.gg.pinit.pinittask.application.task.dto; + +import me.gg.pinit.pinittask.application.schedule.dto.DependencyDto; +import me.gg.pinit.pinittask.domain.dependency.model.Dependency; +import org.junit.jupiter.api.Test; + +import java.time.ZonedDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class TaskDependencyAdjustCommandTest { + + @Test + void resolvesSelfPlaceholderForZeroIds() { + Long ownerId = 1L; + Long selfId = 99L; + TaskDependencyAdjustCommand command = new TaskDependencyAdjustCommand( + null, + ownerId, + "t", + "d", + ZonedDateTime.now(), + 5, + 3, + List.of(), + List.of( + new DependencyDto(null, 0L, 5L), // fromId=0 -> self + new DependencyDto(null, 4L, 0L) // toId=0 -> self + ) + ); + + List deps = command.getAddDependencies(selfId); + + assertThat(deps) + .extracting(Dependency::getFromId, Dependency::getToId) + .containsExactly( + org.assertj.core.groups.Tuple.tuple(selfId, 5L), + org.assertj.core.groups.Tuple.tuple(4L, selfId) + ); + } + + @Test + void validateNoPlaceholderForUpdate_rejectsZeroIds() { + TaskDependencyAdjustCommand command = new TaskDependencyAdjustCommand( + 10L, + 1L, + "t", + "d", + ZonedDateTime.now(), + 5, + 3, + List.of(), + List.of(new DependencyDto(null, 0L, 2L)) + ); + + org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, command::validateNoPlaceholderForUpdate); + } +} From 378c3f9a27aebf23272c2891f9ac22f4cdf04d5e Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:09:09 +0900 Subject: [PATCH 5/9] =?UTF-8?q?test:=20TaskCreateRequest=EC=9D=98=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=8A=A4=ED=99=80=EB=8D=94=200=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interfaces/dto/TaskCreateRequestTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequestTest.java diff --git a/src/test/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequestTest.java b/src/test/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequestTest.java new file mode 100644 index 00000000..76d436aa --- /dev/null +++ b/src/test/java/me/gg/pinit/pinittask/interfaces/dto/TaskCreateRequestTest.java @@ -0,0 +1,28 @@ +package me.gg.pinit.pinittask.interfaces.dto; + +import me.gg.pinit.pinittask.application.datetime.DateTimeUtils; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class TaskCreateRequestTest { + + @Test + void toCommand_requiresPlaceholderZeroForEachDependency() { + TaskCreateRequest req = new TaskCreateRequest( + "t", + "d", + new DateTimeWithZone(LocalDateTime.now(), ZoneId.of("UTC")), + 5, + 3, + List.of(new DependencyRequest(10L, 20L)) // neither is 0 + ); + + assertThrows(IllegalArgumentException.class, + () -> req.toCommand(null, 1L, new DateTimeUtils())); + } +} From d968073bbfa576a64f6dfa87e4f531d97e26dcd4 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:09:29 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=EC=9E=91=EC=97=85=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EC=88=98=EC=A0=95=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20DTO=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gg/pinit/pinittask/interfaces/web/TaskControllerV1.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1.java b/src/main/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1.java index fae4ffa8..96d44444 100644 --- a/src/main/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1.java +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1.java @@ -47,7 +47,7 @@ public class TaskControllerV1 { @PostMapping @Operation(summary = "작업 생성", description = "새 작업과 의존 관계를 등록합니다.") public ResponseEntity createTask(@Parameter(hidden = true) @MemberId Long memberId, - @Valid @RequestBody TaskRequest request) { + @Valid @RequestBody TaskCreateRequest request) { Task saved = taskAdjustmentService.createTask(memberId, request.toCommand(null, memberId, dateTimeUtils)); return ResponseEntity.status(HttpStatus.CREATED).body(TaskResponse.from(saved)); } @@ -56,7 +56,7 @@ public ResponseEntity createTask(@Parameter(hidden = true) @Member @Operation(summary = "작업 수정", description = "작업 본문과 의존 관계를 함께 수정합니다.") public ResponseEntity updateTask(@Parameter(hidden = true) @MemberId Long memberId, @PathVariable Long taskId, - @Valid @RequestBody TaskRequest request) { + @Valid @RequestBody TaskUpdateRequest request) { Task updated = taskAdjustmentService.updateTask(memberId, request.toCommand(taskId, memberId, dateTimeUtils)); return ResponseEntity.ok(TaskResponse.from(updated)); } From 28b3cae9289f6423eea0f345d4bf6c53f7bd366b Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:09:47 +0900 Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=EC=9D=98=20=EC=9E=91=EC=97=85=20ID=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gg/pinit/pinittask/interfaces/dto/DependencyRequest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/DependencyRequest.java b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/DependencyRequest.java index d1a885d1..817fde7a 100644 --- a/src/main/java/me/gg/pinit/pinittask/interfaces/dto/DependencyRequest.java +++ b/src/main/java/me/gg/pinit/pinittask/interfaces/dto/DependencyRequest.java @@ -5,10 +5,10 @@ public record DependencyRequest( @NotNull - @Schema(description = "선행 일정 ID", example = "1") + @Schema(description = "선행 작업 ID (새 작업 생성 시 자기 자신은 0, 수정 시 0 금지)", example = "1") Long fromId, @NotNull - @Schema(description = "후행 일정 ID", example = "2") + @Schema(description = "후행 작업 ID (새 작업 생성 시 자기 자신은 0, 수정 시 0 금지)", example = "2") Long toId ) { } From 9f255b556748681538d420ca2fce23d9c0d98f18 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:09:55 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EC=9E=91=EC=97=85=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=9A=94=EC=B2=AD=20DTO=EB=A5=BC=20TaskCreateReque?= =?UTF-8?q?st=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interfaces/web/TaskControllerV1IntegrationTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1IntegrationTest.java b/src/test/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1IntegrationTest.java index 7a1e45c2..3d9f9c55 100644 --- a/src/test/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1IntegrationTest.java +++ b/src/test/java/me/gg/pinit/pinittask/interfaces/web/TaskControllerV1IntegrationTest.java @@ -7,7 +7,7 @@ import me.gg.pinit.pinittask.domain.schedule.model.ScheduleType; import me.gg.pinit.pinittask.infrastructure.events.RabbitEventPublisher; import me.gg.pinit.pinittask.interfaces.dto.DateTimeWithZone; -import me.gg.pinit.pinittask.interfaces.dto.TaskRequest; +import me.gg.pinit.pinittask.interfaces.dto.TaskCreateRequest; import me.gg.pinit.pinittask.interfaces.dto.TaskScheduleRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -59,13 +59,12 @@ void setUpMember() { @Test void taskLifecycle_create_retrieve_list_cursor_complete_reopen_delete() throws Exception { - TaskRequest createRequest = new TaskRequest( + TaskCreateRequest createRequest = new TaskCreateRequest( "리포트 작성", "주간 리포트 초안 작성", new DateTimeWithZone(LocalDateTime.of(2024, 4, 1, 18, 0), MEMBER_ZONE), 5, 3, - List.of(), List.of() ); @@ -168,7 +167,6 @@ void createTask_validationErrors_returnDetailedErrors() throws Exception { "dueDate": null, "importance": 0, "difficulty": 4, - "removeDependencies": [], "addDependencies": [] } """; From 9cf4c3a5f4f54e401d2b014c07dbe143bf6c28e1 Mon Sep 17 00:00:00 2001 From: GoGradually Date: Fri, 23 Jan 2026 00:10:02 +0900 Subject: [PATCH 9/9] =?UTF-8?q?docs:=20Task=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EB=A1=9C=EB=93=9C=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c6ace8e6..fa488771 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ Task 간 “선후 관계”를 관리합니다. * `GET /v1/members/now` 현재 진행 중인 일정 ID * `GET /v1/statistics` 주간 통계 조회 * Task 응답에 의존성 메타(`previousTaskIds`,`nextTaskIds`) 포함 + * Task 의존성 페이로드: **생성 시** 각 의존 관계마다 `fromId` 또는 `toId` 중 하나는 반드시 `0`(새로 생성될 자기 자신)이어야 하며, `removeDependencies`는 비워두어야 + 합니다. **수정 시에는 0을 사용할 수 없습니다.** * **작업 → 일정 복사**: `POST /v1/tasks/{taskId}/schedules`로 기존 작업을 지정 시각에 일정으로 등록할 수 있습니다. * **삭제 플래그**: `DELETE /v1/tasks/{taskId}?deleteSchedules=` 혹은 `DELETE /v0|v1/schedules/{scheduleId}?deleteTaskAlso=` 로 연관 삭제 여부를 선택합니다(미설정 시 연관만 해제).