From 30499834da9dd44ff0122d112b8b06a6d3d18c9f Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sat, 10 Jan 2026 14:33:40 +0900 Subject: [PATCH 01/12] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EA=B7=BC=EB=AC=B4=EC=8B=9C=EA=B0=84=20Entity=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 --- .../entity/WorkspaceWorkerSchedule.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java new file mode 100644 index 00000000..0beb591e --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -0,0 +1,63 @@ +package com.dreamteam.alter.domain.workspace.entity; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; +import java.time.LocalTime; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "workspace_worker_schedules") +@Builder(access = AccessLevel.PRIVATE) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@EntityListeners(AuditingEntityListener.class) +public class WorkspaceWorkerSchedule { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "workspace_worker_id", nullable = false) + private WorkspaceWorker workspaceWorker; + + @Enumerated(EnumType.STRING) + @Column(name = "day_of_week", nullable = false) + private DayOfWeek dayOfWeek; + + @Column(name = "start_time", nullable = false) + private LocalTime startTime; + + @Column(name = "end_time", nullable = false) + private LocalTime endTime; + + @CreatedDate + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; +} From 047c9ee685931d1ce178abf19a3d301bd17e9710 Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sat, 10 Jan 2026 19:35:57 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EA=B7=BC=EB=AC=B4=EC=8B=9C=EA=B0=84=20=EC=83=9D=EC=84=B1=20API?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagerWorkerScheduleController.java | 45 +++++++++++++++ .../ManagerWorkerScheduleControllerSpec.java | 56 +++++++++++++++++++ .../dto/CreateWorkerScheduleRequestDto.java | 29 ++++++++++ .../persistence/WorkspaceJpaRepository.java | 12 ++++ .../persistence/WorkspaceRepositoryImpl.java | 23 ++++++++ .../WorkspaceWorkerScheduleJapRepository.java | 8 +++ ...WorkspaceWorkerScheduleRepositoryImpl.java | 22 ++++++++ .../usecase/ManagerCreateWorkerSchedule.java | 51 +++++++++++++++++ .../alter/common/exception/ErrorCode.java | 2 + .../entity/WorkspaceWorkerSchedule.java | 25 +++++++++ .../ManagerCreateWorkerScheduleUseCase.java | 10 ++++ .../port/outbound/WorkspaceRepository.java | 10 ++++ .../WorkspaceWorkerScheduleRepository.java | 9 +++ 13 files changed, 302 insertions(+) create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java create mode 100644 src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java new file mode 100644 index 00000000..9089a83a --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java @@ -0,0 +1,45 @@ +package com.dreamteam.alter.adapter.inbound.manager.schedule.controller; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.dreamteam.alter.adapter.inbound.common.dto.CommonApiResponse; +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; +import com.dreamteam.alter.application.aop.ManagerActionContext; +import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateWorkerScheduleUseCase; + +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@PreAuthorize("hasAnyRole('MANAGER')") +@RequiredArgsConstructor +@Validated +@RequestMapping("/manager/workspaces/{workspaceId}") +public class ManagerWorkerScheduleController implements ManagerWorkerScheduleControllerSpec{ + + @Resource(name = "managerCreateWorkerSchedule") + private final ManagerCreateWorkerScheduleUseCase managerCreateWorkerScheduleUseCase; + + @Override + @PostMapping("/workers/{workerId}/schedules") + public ResponseEntity> createWorkerSchedule( + @PathVariable Long workspaceId, + @PathVariable Long workerId, + @RequestBody @Valid List request + ) { + ManagerActor actor = ManagerActionContext.getInstance().getActor(); + managerCreateWorkerScheduleUseCase.execute(actor, workspaceId, workerId, request); + return ResponseEntity.ok(CommonApiResponse.empty()); + } +} diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java new file mode 100644 index 00000000..76689af7 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java @@ -0,0 +1,56 @@ +package com.dreamteam.alter.adapter.inbound.manager.schedule.controller; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; + +import com.dreamteam.alter.adapter.inbound.common.dto.CommonApiResponse; +import com.dreamteam.alter.adapter.inbound.common.dto.ErrorResponse; +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; + +@Tag(name = "MANAGER - 근무자 스케줄 관리 API") +public interface ManagerWorkerScheduleControllerSpec { + + @Operation(summary = "매니저 - 근무자 고정 스케줄 등록", description = "근무자의 요일별 고정 근무 시간을 등록합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "고정 스케줄 등록 성공"), + @ApiResponse(responseCode = "400", description = "실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B008\"}" + ), + @ExampleObject( + name = "존재하지 않는 근무자", + value = "{\"code\" : \"B011\"}" + ), + @ExampleObject( + name = "해당업장에 근무하는 근무자가 아닙니다.", + value = "{\"code\" : \"B022\"}" + ), + @ExampleObject( + name = "시작시간은 종료 시간보다 늦을 수 없습니다.", + value = "{\"code\" : \"B023\"}" + ) + })), + }) + ResponseEntity> createWorkerSchedule( + @PathVariable Long workspaceId, + @PathVariable Long workerId, + @Valid @RequestBody List requests + ); +} diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java new file mode 100644 index 00000000..de1184d0 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java @@ -0,0 +1,29 @@ +package com.dreamteam.alter.adapter.inbound.manager.workspace.dto; + +import java.time.DayOfWeek; +import java.time.LocalTime; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "매니저 - 근무자 고정 스케줄 등록 DTO") +public class CreateWorkerScheduleRequestDto { + + @NotNull(message = "요일은 필수입니다") + @Schema(description = "요일", example = "MONDAY") + private DayOfWeek dayOfWeek; + + @NotNull(message = "시작 시간은 필수입니다") + @Schema(description = "시작 시간", example = "09:00:00") + private LocalTime startTime; + + @NotNull(message = "종료 시간은 필수입니다") + @Schema(description = "종료 시간", example = "18:00:00") + private LocalTime endTime; +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java new file mode 100644 index 00000000..8dba0549 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java @@ -0,0 +1,12 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.dreamteam.alter.domain.user.entity.ManagerUser; +import com.dreamteam.alter.domain.workspace.entity.Workspace; + +public interface WorkspaceJpaRepository extends JpaRepository { + Optional findByIdAndManagerUser(Long id, ManagerUser managerUser); +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java new file mode 100644 index 00000000..72f10a38 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java @@ -0,0 +1,23 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import java.util.Optional; + +import org.springframework.stereotype.Repository; + +import com.dreamteam.alter.domain.user.entity.ManagerUser; +import com.dreamteam.alter.domain.workspace.entity.Workspace; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class WorkspaceRepositoryImpl implements WorkspaceRepository { + + private final WorkspaceJpaRepository workspaceJpaRepository; + + @Override + public Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { + return workspaceJpaRepository.findByIdAndManagerUser(workspaceId, managerUser); + } +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java new file mode 100644 index 00000000..4fdca1ab --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java @@ -0,0 +1,8 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; + +public interface WorkspaceWorkerScheduleJapRepository extends JpaRepository { +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java new file mode 100644 index 00000000..72689fab --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -0,0 +1,22 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class WorkspaceWorkerScheduleRepositoryImpl implements WorkspaceWorkerScheduleRepository { + + private final WorkspaceWorkerScheduleJapRepository workspaceWorkerScheduleJapRepository; + + @Override + public void saveAll(List workspaceWorkerSchedules) { + workspaceWorkerScheduleJapRepository.saveAll(workspaceWorkerSchedules); + } +} diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java new file mode 100644 index 00000000..133012ff --- /dev/null +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java @@ -0,0 +1,51 @@ +package com.dreamteam.alter.application.workspace.usecase; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; +import com.dreamteam.alter.common.exception.CustomException; +import com.dreamteam.alter.common.exception.ErrorCode; +import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.user.entity.User; +import com.dreamteam.alter.domain.user.port.outbound.UserQueryRepository; +import com.dreamteam.alter.domain.workspace.entity.Workspace; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerQueryRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; + +import lombok.RequiredArgsConstructor; + +@Service("managerCreateWorkerSchedule") +@RequiredArgsConstructor +@Transactional +public class ManagerCreateWorkerSchedule implements ManagerCreateWorkerScheduleUseCase { + + private final WorkspaceRepository workspaceRepository; + private final UserQueryRepository userQueryRepository; + private final WorkspaceWorkerQueryRepository workspaceWorkerQueryRepository; + private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + + @Override + public void execute(ManagerActor actor, Long workspaceId, Long workerId, List request) { + Workspace workspace = workspaceRepository.getByIdAndManagerUser(workspaceId, actor.getManagerUser()) + .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND)); + + User user = userQueryRepository.findById(workerId) + .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + + WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findActiveWorkerByWorkspaceAndUser(workspace, user) + .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_WORKER_NOT_FOUNT)); + + workspaceWorkerScheduleRepository.saveAll(request.stream() + .map(r -> WorkspaceWorkerSchedule.create(workspaceWorker, r.getDayOfWeek(), r.getStartTime(), r.getEndTime())) + .toList()); + + // send FCM + } +} diff --git a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java index b81c5d6d..f60913b7 100644 --- a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java +++ b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java @@ -44,6 +44,8 @@ public enum ErrorCode { CONFLICT(409, "B020", "변경할 수 없는 상태입니다."), SCHEDULE_NOT_FOUND_FOR_DELETE(400, "B021", "삭제할 스케줄을 찾을 수 없습니다"), SCHEDULE_NOT_FOUND_FOR_UPDATE(400, "B022", "수정할 스케줄을 찾을 수 없습니다"), + WORKSPACE_WORKER_NOT_FOUNT(400, "B023", "해당 업장에 근무하는 사용자가 아닙니다."), + START_TIME_AFTER_END_TIME(400, "B024", "시작 시간은 종료 시간보다 늦을 수 없습니다."), INTERNAL_SERVER_ERROR(400, "C001", "서버 내부 오류입니다."), EXTERNAL_API_ERROR(502, "C002", "외부 API 연동에 실패했습니다."), diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index 0beb591e..31a621f0 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -8,6 +8,9 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import com.dreamteam.alter.common.exception.CustomException; +import com.dreamteam.alter.common.exception.ErrorCode; + import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; @@ -60,4 +63,26 @@ public class WorkspaceWorkerSchedule { @LastModifiedDate @Column(name = "updated_at", nullable = false) private LocalDateTime updatedAt; + + public static WorkspaceWorkerSchedule create( + WorkspaceWorker workspaceWorker, + DayOfWeek dayOfWeek, + LocalTime startTime, + LocalTime endTime + ) { + WorkspaceWorkerSchedule workspaceWorkerSchedule = WorkspaceWorkerSchedule.builder() + .workspaceWorker(workspaceWorker) + .dayOfWeek(dayOfWeek) + .startTime(startTime) + .endTime(endTime) + .build(); + + workspaceWorkerSchedule.validTime(); + return workspaceWorkerSchedule; + } + + public void validTime() { + if (startTime.isAfter(endTime)) + throw new CustomException(ErrorCode.START_TIME_AFTER_END_TIME); + } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java new file mode 100644 index 00000000..930b0d43 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java @@ -0,0 +1,10 @@ +package com.dreamteam.alter.domain.workspace.port.inbound; + +import java.util.List; + +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; +import com.dreamteam.alter.domain.user.context.ManagerActor; + +public interface ManagerCreateWorkerScheduleUseCase { + void execute(ManagerActor actor, Long workspaceId, Long workerId, List request); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java new file mode 100644 index 00000000..173ce8c5 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java @@ -0,0 +1,10 @@ +package com.dreamteam.alter.domain.workspace.port.outbound; + +import java.util.Optional; + +import com.dreamteam.alter.domain.user.entity.ManagerUser; +import com.dreamteam.alter.domain.workspace.entity.Workspace; + +public interface WorkspaceRepository { + Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java new file mode 100644 index 00000000..46c5dd6e --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -0,0 +1,9 @@ +package com.dreamteam.alter.domain.workspace.port.outbound; + +import java.util.List; + +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; + +public interface WorkspaceWorkerScheduleRepository { + void saveAll(List workspaceWorkerSchedules); +} From 9a56a854c2ad4f68ff92ba8c07a32fdde9f0294c Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sun, 11 Jan 2026 01:09:39 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EA=B7=BC=EB=AC=B4=20=EC=8A=A4=EC=BC=80=EC=A4=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=EC=82=AD=EC=A0=9C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagerWorkerScheduleController.java | 43 ++++++++--- .../ManagerWorkerScheduleControllerSpec.java | 71 +++++++++++++++++-- .../dto/UpdateWorkerScheduleRequestDto.java | 28 ++++++++ .../dto/CreateWorkerScheduleRequestDto.java | 35 ++++++--- .../persistence/WorkspaceJpaRepository.java | 2 + .../persistence/WorkspaceRepositoryImpl.java | 7 +- .../WorkspaceWorkerScheduleJapRepository.java | 6 ++ ...WorkspaceWorkerScheduleRepositoryImpl.java | 28 ++++++++ .../usecase/ManagerCreateWorkerSchedule.java | 26 ++++--- .../usecase/ManagerDeleteWorkerSchedule.java | 35 +++++++++ .../usecase/ManagerUpdateWorkerSchedule.java | 41 +++++++++++ .../alter/common/exception/ErrorCode.java | 1 + .../entity/WorkspaceWorkerSchedule.java | 10 ++- .../ManagerCreateWorkerScheduleUseCase.java | 4 +- .../ManagerDeleteWorkerScheduleUseCase.java | 7 ++ .../ManagerUpdateWorkerScheduleUseCase.java | 8 +++ .../port/outbound/WorkspaceRepository.java | 3 +- .../WorkspaceWorkerScheduleRepository.java | 11 +++ 18 files changed, 327 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java create mode 100644 src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java create mode 100644 src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java index 9089a83a..2724b64f 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java @@ -1,23 +1,25 @@ package com.dreamteam.alter.adapter.inbound.manager.schedule.controller; -import java.util.List; - import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.dreamteam.alter.adapter.inbound.common.dto.CommonApiResponse; +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import com.dreamteam.alter.application.aop.ManagerActionContext; import com.dreamteam.alter.domain.user.context.ManagerActor; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkerScheduleUseCase; -import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -25,21 +27,44 @@ @PreAuthorize("hasAnyRole('MANAGER')") @RequiredArgsConstructor @Validated -@RequestMapping("/manager/workspaces/{workspaceId}") +@RequestMapping("/manager/workspace/{workspaceId}/worker-schedules") public class ManagerWorkerScheduleController implements ManagerWorkerScheduleControllerSpec{ - @Resource(name = "managerCreateWorkerSchedule") private final ManagerCreateWorkerScheduleUseCase managerCreateWorkerScheduleUseCase; + private final ManagerUpdateWorkerScheduleUseCase managerUpdateWorkerScheduleUseCase; + private final ManagerDeleteWorkerScheduleUseCase managerDeleteWorkerScheduleUseCase; @Override - @PostMapping("/workers/{workerId}/schedules") + @PostMapping public ResponseEntity> createWorkerSchedule( @PathVariable Long workspaceId, - @PathVariable Long workerId, - @RequestBody @Valid List request + @RequestBody @Valid CreateWorkerScheduleRequestDto request + ) { + ManagerActor actor = ManagerActionContext.getInstance().getActor(); + managerCreateWorkerScheduleUseCase.execute(actor, workspaceId, request); + return ResponseEntity.ok(CommonApiResponse.empty()); + } + + @Override + @PutMapping("/{workerScheduleId}") + public ResponseEntity> updateWorkerSchedule( + @PathVariable Long workspaceId, + @PathVariable Long workerScheduleId, + @RequestBody @Valid UpdateWorkerScheduleRequestDto request + ) { + ManagerActor actor = ManagerActionContext.getInstance().getActor(); + managerUpdateWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId, request); + return ResponseEntity.ok(CommonApiResponse.empty()); + } + + @Override + @DeleteMapping("/{workerScheduleId}") + public ResponseEntity> deleteWorkerSchedule( + @PathVariable Long workspaceId, + @PathVariable Long workerScheduleId ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerCreateWorkerScheduleUseCase.execute(actor, workspaceId, workerId, request); + managerDeleteWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId); return ResponseEntity.ok(CommonApiResponse.empty()); } } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java index 76689af7..cd0dd1a4 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java @@ -1,13 +1,12 @@ package com.dreamteam.alter.adapter.inbound.manager.schedule.controller; -import java.util.List; - import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import com.dreamteam.alter.adapter.inbound.common.dto.CommonApiResponse; import com.dreamteam.alter.adapter.inbound.common.dto.ErrorResponse; +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import io.swagger.v3.oas.annotations.Operation; @@ -35,22 +34,80 @@ public interface ManagerWorkerScheduleControllerSpec { value = "{\"code\" : \"B008\"}" ), @ExampleObject( - name = "존재하지 않는 근무자", + name = "존재하지 않는 근무자입니다.", value = "{\"code\" : \"B011\"}" ), @ExampleObject( name = "해당업장에 근무하는 근무자가 아닙니다.", + value = "{\"code\" : \"B023\"}" + ), + @ExampleObject( + name = "시작시간은 종료 시간보다 늦을 수 없습니다.", + value = "{\"code\" : \"B024\"}" + ), + @ExampleObject( + name = "이미 해당 요일에 근무 스케줄이 등록되어있습니다.", + value = "{\"code\" : \"B025\"}" + ), + })), + }) + ResponseEntity> createWorkerSchedule( + @PathVariable Long workspaceId, + @RequestBody @Valid CreateWorkerScheduleRequestDto requests + ); + + @Operation(summary = "매니저 - 근무자 고정 스케줄 수정", description = "근무자의 요일별 고정 근무 시간을 수정합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "고정 스케줄 수정 성공"), + @ApiResponse(responseCode = "400", description = "실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B008\"}" + ), + @ExampleObject( + name = "수정할 스케줄을 찾을 수 없습니다.", value = "{\"code\" : \"B022\"}" ), @ExampleObject( name = "시작시간은 종료 시간보다 늦을 수 없습니다.", value = "{\"code\" : \"B023\"}" - ) + ), + @ExampleObject( + name = "이미 해당 요일에 근무 스케줄이 등록되어있습니다.", + value = "{\"code\" : \"B025\"}" + ), })), }) - ResponseEntity> createWorkerSchedule( + ResponseEntity> updateWorkerSchedule( + @PathVariable Long workspaceId, + @PathVariable Long workerScheduleId, + @RequestBody @Valid UpdateWorkerScheduleRequestDto request + ); + + @Operation(summary = "매니저 - 근무자 고정 스케줄 삭제", description = "근무자의 요일별 고정 근무 시간을 삭제합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "고정 스케줄 삭제 성공"), + @ApiResponse(responseCode = "400", description = "실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B008\"}" + ), + @ExampleObject( + name = "삭제할 스케줄을 찾을 수 없습니다.", + value = "{\"code\" : \"B021\"}" + ), + })), + }) + ResponseEntity> deleteWorkerSchedule( @PathVariable Long workspaceId, - @PathVariable Long workerId, - @Valid @RequestBody List requests + @PathVariable Long workerScheduleId ); } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java new file mode 100644 index 00000000..40b9c253 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java @@ -0,0 +1,28 @@ +package com.dreamteam.alter.adapter.inbound.manager.schedule.dto; + +import java.time.DayOfWeek; +import java.time.LocalTime; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "매니저 - 근무자 고정 스케줄 수정 DTO") +public class UpdateWorkerScheduleRequestDto { + @NotNull(message = "요일은 필수입니다") + @Schema(description = "요일", example = "MONDAY") + private DayOfWeek dayOfWeek; + + @NotNull(message = "시작 시간은 필수입니다") + @Schema(description = "시작 시간", example = "09:00:00") + private LocalTime startTime; + + @NotNull(message = "종료 시간은 필수입니다") + @Schema(description = "종료 시간", example = "18:00:00") + private LocalTime endTime; +} diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java index de1184d0..ca4e084e 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java @@ -2,8 +2,11 @@ import java.time.DayOfWeek; import java.time.LocalTime; +import java.util.List; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; @@ -15,15 +18,29 @@ @Schema(description = "매니저 - 근무자 고정 스케줄 등록 DTO") public class CreateWorkerScheduleRequestDto { - @NotNull(message = "요일은 필수입니다") - @Schema(description = "요일", example = "MONDAY") - private DayOfWeek dayOfWeek; + @NotNull(message = "근무자 ID는 필수입니다.") + @Schema(description = "근무자 ID", example = "1") + private Long workerId; - @NotNull(message = "시작 시간은 필수입니다") - @Schema(description = "시작 시간", example = "09:00:00") - private LocalTime startTime; + @NotEmpty(message = "스케줄 목록은 필수입니다.") + @Valid + private List schedules; - @NotNull(message = "종료 시간은 필수입니다") - @Schema(description = "종료 시간", example = "18:00:00") - private LocalTime endTime; + @Getter + @NoArgsConstructor + @AllArgsConstructor + @Schema(description = "근무자 스케줄 정보") + public static class WorkerScheduleDto { + @NotNull(message = "요일은 필수입니다") + @Schema(description = "요일", example = "MONDAY") + private DayOfWeek dayOfWeek; + + @NotNull(message = "시작 시간은 필수입니다") + @Schema(description = "시작 시간", example = "09:00:00") + private LocalTime startTime; + + @NotNull(message = "종료 시간은 필수입니다") + @Schema(description = "종료 시간", example = "18:00:00") + private LocalTime endTime; + } } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java index 8dba0549..7afcb2a2 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java @@ -9,4 +9,6 @@ public interface WorkspaceJpaRepository extends JpaRepository { Optional findByIdAndManagerUser(Long id, ManagerUser managerUser); + + boolean existsByIdAndManagerUser(Long id, ManagerUser managerUser); } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java index 72f10a38..817957bc 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java @@ -17,7 +17,12 @@ public class WorkspaceRepositoryImpl implements WorkspaceRepository { private final WorkspaceJpaRepository workspaceJpaRepository; @Override - public Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { + public Optional findByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { return workspaceJpaRepository.findByIdAndManagerUser(workspaceId, managerUser); } + + @Override + public boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { + return workspaceJpaRepository.existsByIdAndManagerUser(workspaceId, managerUser); + } } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java index 4fdca1ab..678a20c8 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java @@ -1,8 +1,14 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; +import java.time.DayOfWeek; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleJapRepository extends JpaRepository { + boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek); + boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index 72689fab..73e6e4e4 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -1,9 +1,12 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; +import java.time.DayOfWeek; import java.util.List; +import java.util.Optional; import org.springframework.stereotype.Repository; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; @@ -19,4 +22,29 @@ public class WorkspaceWorkerScheduleRepositoryImpl implements WorkspaceWorkerSch public void saveAll(List workspaceWorkerSchedules) { workspaceWorkerScheduleJapRepository.saveAll(workspaceWorkerSchedules); } + + @Override + public boolean existsById(Long workerScheduleId) { + return workspaceWorkerScheduleJapRepository.existsById(workerScheduleId); + } + + @Override + public boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek) { + return workspaceWorkerScheduleJapRepository.existsByWorkspaceWorkerAndDayOfWeek(workspaceWorker, dayOfWeek); + } + + @Override + public boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { + return workspaceWorkerScheduleJapRepository.existsByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); + } + + @Override + public Optional findById(Long workerScheduleId) { + return workspaceWorkerScheduleJapRepository.findById(workerScheduleId); + } + + @Override + public void deleteById(Long workerScheduleId) { + workspaceWorkerScheduleJapRepository.deleteById(workerScheduleId); + } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java index 133012ff..addc45d4 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java @@ -1,5 +1,6 @@ package com.dreamteam.alter.application.workspace.usecase; +import java.time.DayOfWeek; import java.util.List; import org.springframework.stereotype.Service; @@ -21,7 +22,7 @@ import lombok.RequiredArgsConstructor; -@Service("managerCreateWorkerSchedule") +@Service @RequiredArgsConstructor @Transactional public class ManagerCreateWorkerSchedule implements ManagerCreateWorkerScheduleUseCase { @@ -32,20 +33,29 @@ public class ManagerCreateWorkerSchedule implements ManagerCreateWorkerScheduleU private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; @Override - public void execute(ManagerActor actor, Long workspaceId, Long workerId, List request) { - Workspace workspace = workspaceRepository.getByIdAndManagerUser(workspaceId, actor.getManagerUser()) + public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request) { + Workspace workspace = workspaceRepository.findByIdAndManagerUser(workspaceId, actor.getManagerUser()) .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND)); - User user = userQueryRepository.findById(workerId) + User user = userQueryRepository.findById(request.getWorkerId()) .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findActiveWorkerByWorkspaceAndUser(workspace, user) .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_WORKER_NOT_FOUNT)); - workspaceWorkerScheduleRepository.saveAll(request.stream() - .map(r -> WorkspaceWorkerSchedule.create(workspaceWorker, r.getDayOfWeek(), r.getStartTime(), r.getEndTime())) - .toList()); + List dayOfWeeks = request.getSchedules().stream() + .map(CreateWorkerScheduleRequestDto.WorkerScheduleDto::getDayOfWeek) + .toList(); - // send FCM + if (workspaceWorkerScheduleRepository.existsByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks)) + throw new CustomException(ErrorCode.ALREADY_HAS_SCHEDULE_DAY); + + workspaceWorkerScheduleRepository.saveAll( + request.getSchedules().stream() + .map(r -> WorkspaceWorkerSchedule.create(workspaceWorker, r.getDayOfWeek(), r.getStartTime(), r.getEndTime())) + .toList() + ); + + // TODO Send FCM } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java new file mode 100644 index 00000000..9117212c --- /dev/null +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java @@ -0,0 +1,35 @@ +package com.dreamteam.alter.application.workspace.usecase; + +import org.springframework.stereotype.Service; + +import com.dreamteam.alter.common.exception.CustomException; +import com.dreamteam.alter.common.exception.ErrorCode; +import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional +public class ManagerDeleteWorkerSchedule implements ManagerDeleteWorkerScheduleUseCase { + + private final WorkspaceRepository workspaceRepository; + private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + + @Override + public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId) { + if (!workspaceRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); + + if (!workspaceWorkerScheduleRepository.existsById(workerScheduleId)) + throw new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_DELETE); + + workspaceWorkerScheduleRepository.deleteById(workerScheduleId); + + // TODO Send FCM + } +} diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java new file mode 100644 index 00000000..412eef8d --- /dev/null +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java @@ -0,0 +1,41 @@ +package com.dreamteam.alter.application.workspace.usecase; + +import org.springframework.stereotype.Service; + +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; +import com.dreamteam.alter.common.exception.CustomException; +import com.dreamteam.alter.common.exception.ErrorCode; +import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional +public class ManagerUpdateWorkerSchedule implements ManagerUpdateWorkerScheduleUseCase { + + private final WorkspaceRepository workspaceRepository; + private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + + @Override + public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, UpdateWorkerScheduleRequestDto request) { + if (!workspaceRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); + + WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findById(workerScheduleId) + .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); + + // 같은 요일 중복 등록 검증 + if (workspaceWorkerScheduleRepository.existsByWorkspaceWorkerAndDayOfWeek(workspaceWorkerSchedule.getWorkspaceWorker(), request.getDayOfWeek())) + throw new CustomException(ErrorCode.ALREADY_HAS_SCHEDULE_DAY); + + workspaceWorkerSchedule.update(request.getDayOfWeek(), request.getStartTime(), request.getEndTime()); + + // TODO Send FCM + } +} diff --git a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java index f60913b7..b1a58253 100644 --- a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java +++ b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java @@ -46,6 +46,7 @@ public enum ErrorCode { SCHEDULE_NOT_FOUND_FOR_UPDATE(400, "B022", "수정할 스케줄을 찾을 수 없습니다"), WORKSPACE_WORKER_NOT_FOUNT(400, "B023", "해당 업장에 근무하는 사용자가 아닙니다."), START_TIME_AFTER_END_TIME(400, "B024", "시작 시간은 종료 시간보다 늦을 수 없습니다."), + ALREADY_HAS_SCHEDULE_DAY(400, "B025", "이미 해당 요일의 근무 스케줄이 등록되어있습니다."), INTERNAL_SERVER_ERROR(400, "C001", "서버 내부 오류입니다."), EXTERNAL_API_ERROR(502, "C002", "외부 API 연동에 실패했습니다."), diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index 31a621f0..f229976f 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -81,8 +81,16 @@ public static WorkspaceWorkerSchedule create( return workspaceWorkerSchedule; } + public void update(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) { + this.dayOfWeek = dayOfWeek; + this.startTime = startTime; + this.endTime = endTime; + + validTime(); + } + public void validTime() { - if (startTime.isAfter(endTime)) + if (this.startTime.isAfter(this.endTime)) throw new CustomException(ErrorCode.START_TIME_AFTER_END_TIME); } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java index 930b0d43..8e505c7e 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java @@ -1,10 +1,8 @@ package com.dreamteam.alter.domain.workspace.port.inbound; -import java.util.List; - import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import com.dreamteam.alter.domain.user.context.ManagerActor; public interface ManagerCreateWorkerScheduleUseCase { - void execute(ManagerActor actor, Long workspaceId, Long workerId, List request); + void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java new file mode 100644 index 00000000..51b8189f --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java @@ -0,0 +1,7 @@ +package com.dreamteam.alter.domain.workspace.port.inbound; + +import com.dreamteam.alter.domain.user.context.ManagerActor; + +public interface ManagerDeleteWorkerScheduleUseCase { + void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java new file mode 100644 index 00000000..3dd5423a --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java @@ -0,0 +1,8 @@ +package com.dreamteam.alter.domain.workspace.port.inbound; + +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; +import com.dreamteam.alter.domain.user.context.ManagerActor; + +public interface ManagerUpdateWorkerScheduleUseCase { + void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, UpdateWorkerScheduleRequestDto request); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java index 173ce8c5..d68bb5f6 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java @@ -6,5 +6,6 @@ import com.dreamteam.alter.domain.workspace.entity.Workspace; public interface WorkspaceRepository { - Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); + Optional findByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); + boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java index 46c5dd6e..3924d3d8 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -1,9 +1,20 @@ package com.dreamteam.alter.domain.workspace.port.outbound; +import java.time.DayOfWeek; import java.util.List; +import java.util.Optional; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleRepository { void saveAll(List workspaceWorkerSchedules); + + Optional findById(Long workerScheduleId); + + boolean existsById(Long workerScheduleId); + boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek); + boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); + + void deleteById(Long workerScheduleId); } From abffd0b96b0c57010df175ee7a2ba1846ec7c28a Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sun, 11 Jan 2026 01:13:22 +0900 Subject: [PATCH 04/12] =?UTF-8?q?fix:=20=EA=B7=BC=EB=AC=B4=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=80=EC=A4=84=20=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=B2=B4=ED=81=AC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 시간만 수정 가능 --- .../controller/ManagerWorkerScheduleControllerSpec.java | 4 ---- .../schedule/dto/UpdateWorkerScheduleRequestDto.java | 4 ---- .../persistence/WorkspaceWorkerScheduleRepositoryImpl.java | 5 ----- .../workspace/usecase/ManagerUpdateWorkerSchedule.java | 6 +----- .../domain/workspace/entity/WorkspaceWorkerSchedule.java | 3 +-- .../port/outbound/WorkspaceWorkerScheduleRepository.java | 1 - 6 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java index cd0dd1a4..f711679d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java @@ -76,10 +76,6 @@ ResponseEntity> createWorkerSchedule( name = "시작시간은 종료 시간보다 늦을 수 없습니다.", value = "{\"code\" : \"B023\"}" ), - @ExampleObject( - name = "이미 해당 요일에 근무 스케줄이 등록되어있습니다.", - value = "{\"code\" : \"B025\"}" - ), })), }) ResponseEntity> updateWorkerSchedule( diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java index 40b9c253..9b88290c 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java @@ -1,6 +1,5 @@ package com.dreamteam.alter.adapter.inbound.manager.schedule.dto; -import java.time.DayOfWeek; import java.time.LocalTime; import io.swagger.v3.oas.annotations.media.Schema; @@ -14,9 +13,6 @@ @AllArgsConstructor @Schema(description = "매니저 - 근무자 고정 스케줄 수정 DTO") public class UpdateWorkerScheduleRequestDto { - @NotNull(message = "요일은 필수입니다") - @Schema(description = "요일", example = "MONDAY") - private DayOfWeek dayOfWeek; @NotNull(message = "시작 시간은 필수입니다") @Schema(description = "시작 시간", example = "09:00:00") diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index 73e6e4e4..bd1d9ead 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -28,11 +28,6 @@ public boolean existsById(Long workerScheduleId) { return workspaceWorkerScheduleJapRepository.existsById(workerScheduleId); } - @Override - public boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek) { - return workspaceWorkerScheduleJapRepository.existsByWorkspaceWorkerAndDayOfWeek(workspaceWorker, dayOfWeek); - } - @Override public boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { return workspaceWorkerScheduleJapRepository.existsByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java index 412eef8d..6fe3dd3e 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java @@ -30,11 +30,7 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findById(workerScheduleId) .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); - // 같은 요일 중복 등록 검증 - if (workspaceWorkerScheduleRepository.existsByWorkspaceWorkerAndDayOfWeek(workspaceWorkerSchedule.getWorkspaceWorker(), request.getDayOfWeek())) - throw new CustomException(ErrorCode.ALREADY_HAS_SCHEDULE_DAY); - - workspaceWorkerSchedule.update(request.getDayOfWeek(), request.getStartTime(), request.getEndTime()); + workspaceWorkerSchedule.update(request.getStartTime(), request.getEndTime()); // TODO Send FCM } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index f229976f..e30b8486 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -81,8 +81,7 @@ public static WorkspaceWorkerSchedule create( return workspaceWorkerSchedule; } - public void update(DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) { - this.dayOfWeek = dayOfWeek; + public void update(LocalTime startTime, LocalTime endTime) { this.startTime = startTime; this.endTime = endTime; diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java index 3924d3d8..a7d4e1e7 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -13,7 +13,6 @@ public interface WorkspaceWorkerScheduleRepository { Optional findById(Long workerScheduleId); boolean existsById(Long workerScheduleId); - boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek); boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); void deleteById(Long workerScheduleId); From 2827197f55e3ff4680b73930b76240aee7358c6a Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sun, 11 Jan 2026 11:48:11 +0900 Subject: [PATCH 05/12] =?UTF-8?q?fix:=20=EA=B7=BC=EB=AC=B4=20=EC=9A=94?= =?UTF-8?q?=EC=9D=BC=20=EC=A4=91=EB=B3=B5=20=EC=B2=B4=ED=81=AC=20->=20?= =?UTF-8?q?=EA=B7=BC=EB=AC=B4=20=EC=8B=9C=EA=B0=84=20=EA=B3=82=EC=B9=A8=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagerWorkerScheduleController.java | 4 +-- .../ManagerWorkerScheduleControllerSpec.java | 6 ++++- .../WorkspaceWorkerScheduleJapRepository.java | 3 +-- ...WorkspaceWorkerScheduleRepositoryImpl.java | 4 +-- .../usecase/ManagerCreateWorkerSchedule.java | 26 ++++++++++++++----- .../usecase/ManagerUpdateWorkerSchedule.java | 17 ++++++++++++ .../alter/common/exception/ErrorCode.java | 2 +- .../entity/WorkspaceWorkerSchedule.java | 5 ++++ .../WorkspaceWorkerScheduleRepository.java | 2 +- 9 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java index 2724b64f..2020881a 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java @@ -4,9 +4,9 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -46,7 +46,7 @@ public ResponseEntity> createWorkerSchedule( } @Override - @PutMapping("/{workerScheduleId}") + @PatchMapping("/{workerScheduleId}") public ResponseEntity> updateWorkerSchedule( @PathVariable Long workspaceId, @PathVariable Long workerScheduleId, diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java index f711679d..880facc1 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java @@ -46,7 +46,7 @@ public interface ManagerWorkerScheduleControllerSpec { value = "{\"code\" : \"B024\"}" ), @ExampleObject( - name = "이미 해당 요일에 근무 스케줄이 등록되어있습니다.", + name = "같은 요일에 겹치는 근무 시간이 존재합니다.", value = "{\"code\" : \"B025\"}" ), })), @@ -76,6 +76,10 @@ ResponseEntity> createWorkerSchedule( name = "시작시간은 종료 시간보다 늦을 수 없습니다.", value = "{\"code\" : \"B023\"}" ), + @ExampleObject( + name = "같은 요일에 겹치는 근무 시간이 존재합니다.", + value = "{\"code\" : \"B025\"}" + ), })), }) ResponseEntity> updateWorkerSchedule( diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java index 678a20c8..5d200f40 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java @@ -9,6 +9,5 @@ import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleJapRepository extends JpaRepository { - boolean existsByWorkspaceWorkerAndDayOfWeek(WorkspaceWorker workspaceWorker, DayOfWeek dayOfWeek); - boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); + List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index bd1d9ead..623fa577 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -29,8 +29,8 @@ public boolean existsById(Long workerScheduleId) { } @Override - public boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { - return workspaceWorkerScheduleJapRepository.existsByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); + public List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { + return workspaceWorkerScheduleJapRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); } @Override diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java index addc45d4..b604da14 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java @@ -43,12 +43,7 @@ public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRe WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findActiveWorkerByWorkspaceAndUser(workspace, user) .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_WORKER_NOT_FOUNT)); - List dayOfWeeks = request.getSchedules().stream() - .map(CreateWorkerScheduleRequestDto.WorkerScheduleDto::getDayOfWeek) - .toList(); - - if (workspaceWorkerScheduleRepository.existsByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks)) - throw new CustomException(ErrorCode.ALREADY_HAS_SCHEDULE_DAY); + validOverlappingTime(workspaceWorker, request); workspaceWorkerScheduleRepository.saveAll( request.getSchedules().stream() @@ -58,4 +53,23 @@ public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRe // TODO Send FCM } + + /** + * 같은 요일 곂치는 시간 검증 + * @param workspaceWorker 해당 근무자 + * @param request 요청 정보 + */ + private void validOverlappingTime(WorkspaceWorker workspaceWorker, CreateWorkerScheduleRequestDto request) { + List dayOfWeeks = request.getSchedules().stream() + .map(CreateWorkerScheduleRequestDto.WorkerScheduleDto::getDayOfWeek) + .toList(); + + List workspaceWorkerSchedules = workspaceWorkerScheduleRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); + + for (WorkspaceWorkerSchedule existingSchedule : workspaceWorkerSchedules) { + request.getSchedules().stream() + .filter(newSchedule -> newSchedule.getDayOfWeek().equals(existingSchedule.getDayOfWeek())) + .forEach(newSchedule -> existingSchedule.validOverlappingTime(newSchedule.getStartTime(), newSchedule.getEndTime())); + } + } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java index 6fe3dd3e..4ad23c59 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java @@ -1,5 +1,7 @@ package com.dreamteam.alter.application.workspace.usecase; +import java.util.List; + import org.springframework.stereotype.Service; import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; @@ -30,8 +32,23 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findById(workerScheduleId) .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); + validOverlappingTime(workspaceWorkerSchedule, request); + workspaceWorkerSchedule.update(request.getStartTime(), request.getEndTime()); // TODO Send FCM } + + /** + * 같은 요일 곂치는 시간 검증 (자기 자신 제외) + * @param workspaceWorkerSchedule 수정 중인 스케줄 + * @param request 요청 정보 + */ + private void validOverlappingTime(WorkspaceWorkerSchedule workspaceWorkerSchedule, UpdateWorkerScheduleRequestDto request) { + List existingSchedules = workspaceWorkerScheduleRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorkerSchedule.getWorkspaceWorker(), List.of(workspaceWorkerSchedule.getDayOfWeek())); + + existingSchedules.stream() + .filter(schedule -> !schedule.getId().equals(workspaceWorkerSchedule.getId())) + .forEach(schedule -> schedule.validOverlappingTime(request.getStartTime(), request.getEndTime())); + } } diff --git a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java index b1a58253..ac83aaab 100644 --- a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java +++ b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java @@ -46,7 +46,7 @@ public enum ErrorCode { SCHEDULE_NOT_FOUND_FOR_UPDATE(400, "B022", "수정할 스케줄을 찾을 수 없습니다"), WORKSPACE_WORKER_NOT_FOUNT(400, "B023", "해당 업장에 근무하는 사용자가 아닙니다."), START_TIME_AFTER_END_TIME(400, "B024", "시작 시간은 종료 시간보다 늦을 수 없습니다."), - ALREADY_HAS_SCHEDULE_DAY(400, "B025", "이미 해당 요일의 근무 스케줄이 등록되어있습니다."), + SCHEDULE_TIME_OVERLAPPING(400, "B025", "같은 요일에 겹치는 근무 시간이 존재합니다."), INTERNAL_SERVER_ERROR(400, "C001", "서버 내부 오류입니다."), EXTERNAL_API_ERROR(502, "C002", "외부 API 연동에 실패했습니다."), diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index e30b8486..46e9f2b5 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -92,4 +92,9 @@ public void validTime() { if (this.startTime.isAfter(this.endTime)) throw new CustomException(ErrorCode.START_TIME_AFTER_END_TIME); } + + public void validOverlappingTime(LocalTime newStart, LocalTime newEnd) { + if (newStart.isBefore(this.endTime) && newEnd.isAfter(this.startTime)) + throw new CustomException(ErrorCode.SCHEDULE_TIME_OVERLAPPING); + } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java index a7d4e1e7..7108d363 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -11,9 +11,9 @@ public interface WorkspaceWorkerScheduleRepository { void saveAll(List workspaceWorkerSchedules); Optional findById(Long workerScheduleId); + List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); boolean existsById(Long workerScheduleId); - boolean existsByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); void deleteById(Long workerScheduleId); } From 39bd04662b8a3f4cb3e018ad61b623dbf6fdc72e Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sun, 11 Jan 2026 11:57:11 +0900 Subject: [PATCH 06/12] =?UTF-8?q?fix:=20N+1=20=EB=AC=B8=EC=A0=9C=20fatch?= =?UTF-8?q?=20join=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/WorkspaceWorkerScheduleJapRepository.java | 6 ++++++ .../persistence/WorkspaceWorkerScheduleRepositoryImpl.java | 4 ++-- .../workspace/usecase/ManagerUpdateWorkerSchedule.java | 2 +- .../port/outbound/WorkspaceWorkerScheduleRepository.java | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java index 5d200f40..58ba6017 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java @@ -2,12 +2,18 @@ import java.time.DayOfWeek; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleJapRepository extends JpaRepository { List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); + + @Query("SELECT wws FROM WorkspaceWorkerSchedule wws JOIN FETCH wws.workspaceWorker WHERE wws.id = :id") + Optional findByIdWithWorkspaceWorker(@Param("id") Long id); } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index 623fa577..a7b17681 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -34,8 +34,8 @@ public List findByWorkspaceWorkerAndDayOfWeekIn(Workspa } @Override - public Optional findById(Long workerScheduleId) { - return workspaceWorkerScheduleJapRepository.findById(workerScheduleId); + public Optional findByIdWithWorkspaceWorker(Long workerScheduleId) { + return workspaceWorkerScheduleJapRepository.findByIdWithWorkspaceWorker(workerScheduleId); } @Override diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java index 4ad23c59..7045eb37 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java @@ -29,7 +29,7 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, if (!workspaceRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findById(workerScheduleId) + WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findByIdWithWorkspaceWorker(workerScheduleId) .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); validOverlappingTime(workspaceWorkerSchedule, request); diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java index 7108d363..de9f4d5f 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -10,7 +10,7 @@ public interface WorkspaceWorkerScheduleRepository { void saveAll(List workspaceWorkerSchedules); - Optional findById(Long workerScheduleId); + Optional findByIdWithWorkspaceWorker(Long workerScheduleId); List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); boolean existsById(Long workerScheduleId); From 9e4bcd707b60ce36352edefbf57bb2809995b410 Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Mon, 12 Jan 2026 20:13:24 +0900 Subject: [PATCH 07/12] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagerWorkerScheduleController.java | 18 ++-- .../schedule/dto/WorkerScheduleDto.java | 28 +++++++ .../dto/CreateWorkerScheduleRequestDto.java | 22 +---- .../WorkspaceQueryRepositoryImpl.java | 56 ++++++++++--- .../persistence/WorkspaceRepositoryImpl.java | 28 ------- ...paceWorkerScheduleQueryRepositoryImpl.java | 82 +++++++++++++++++++ ...WorkspaceWorkerScheduleRepositoryImpl.java | 23 ------ ... => ManagerCreateFixedWorkerSchedule.java} | 19 +++-- ... => ManagerDeleteFixedWorkerSchedule.java} | 18 ++-- ... => ManagerUpdateFixedWorkerSchedule.java} | 18 ++-- .../entity/WorkspaceWorkerSchedule.java | 6 ++ ...agerCreateFixedWorkerScheduleUseCase.java} | 2 +- ...agerDeleteFixedWorkerScheduleUseCase.java} | 2 +- ...agerUpdateFixedWorkerScheduleUseCase.java} | 2 +- .../outbound/WorkspaceQueryRepository.java | 3 + .../port/outbound/WorkspaceRepository.java | 11 --- ...orkspaceWorkerScheduleQueryRepository.java | 17 ++++ .../WorkspaceWorkerScheduleRepository.java | 10 --- .../type/WorkspaceWorkerScheduleStatus.java | 6 ++ 19 files changed, 231 insertions(+), 140 deletions(-) create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java delete mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java rename src/main/java/com/dreamteam/alter/application/workspace/usecase/{ManagerCreateWorkerSchedule.java => ManagerCreateFixedWorkerSchedule.java} (79%) rename src/main/java/com/dreamteam/alter/application/workspace/usecase/{ManagerDeleteWorkerSchedule.java => ManagerDeleteFixedWorkerSchedule.java} (59%) rename src/main/java/com/dreamteam/alter/application/workspace/usecase/{ManagerUpdateWorkerSchedule.java => ManagerUpdateFixedWorkerSchedule.java} (73%) rename src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/{ManagerCreateWorkerScheduleUseCase.java => ManagerCreateFixedWorkerScheduleUseCase.java} (84%) rename src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/{ManagerDeleteWorkerScheduleUseCase.java => ManagerDeleteFixedWorkerScheduleUseCase.java} (77%) rename src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/{ManagerUpdateWorkerScheduleUseCase.java => ManagerUpdateFixedWorkerScheduleUseCase.java} (85%) delete mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java index 2020881a..d6756186 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java @@ -16,9 +16,9 @@ import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import com.dreamteam.alter.application.aop.ManagerActionContext; import com.dreamteam.alter.domain.user.context.ManagerActor; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateWorkerScheduleUseCase; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteWorkerScheduleUseCase; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateFixedWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteFixedWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateFixedWorkerScheduleUseCase; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -27,12 +27,12 @@ @PreAuthorize("hasAnyRole('MANAGER')") @RequiredArgsConstructor @Validated -@RequestMapping("/manager/workspace/{workspaceId}/worker-schedules") +@RequestMapping("/manager/workspaces/{workspaceId}/worker-schedules") public class ManagerWorkerScheduleController implements ManagerWorkerScheduleControllerSpec{ - private final ManagerCreateWorkerScheduleUseCase managerCreateWorkerScheduleUseCase; - private final ManagerUpdateWorkerScheduleUseCase managerUpdateWorkerScheduleUseCase; - private final ManagerDeleteWorkerScheduleUseCase managerDeleteWorkerScheduleUseCase; + private final ManagerCreateFixedWorkerScheduleUseCase managerCreateFixedWorkerScheduleUseCase; + private final ManagerUpdateFixedWorkerScheduleUseCase managerUpdateWorkerScheduleUseCase; + private final ManagerDeleteFixedWorkerScheduleUseCase managerDeleteFixedWorkerScheduleUseCase; @Override @PostMapping @@ -41,7 +41,7 @@ public ResponseEntity> createWorkerSchedule( @RequestBody @Valid CreateWorkerScheduleRequestDto request ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerCreateWorkerScheduleUseCase.execute(actor, workspaceId, request); + managerCreateFixedWorkerScheduleUseCase.execute(actor, workspaceId, request); return ResponseEntity.ok(CommonApiResponse.empty()); } @@ -64,7 +64,7 @@ public ResponseEntity> deleteWorkerSchedule( @PathVariable Long workerScheduleId ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerDeleteWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId); + managerDeleteFixedWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId); return ResponseEntity.ok(CommonApiResponse.empty()); } } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java new file mode 100644 index 00000000..16ab505f --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java @@ -0,0 +1,28 @@ +package com.dreamteam.alter.adapter.inbound.manager.schedule.dto; + +import java.time.DayOfWeek; +import java.time.LocalTime; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "근무자 스케줄 정보") +public class WorkerScheduleDto { + @NotNull(message = "요일은 필수입니다") + @Schema(description = "요일", example = "MONDAY") + private DayOfWeek dayOfWeek; + + @NotNull(message = "시작 시간은 필수입니다") + @Schema(description = "시작 시간", example = "09:00:00") + private LocalTime startTime; + + @NotNull(message = "종료 시간은 필수입니다") + @Schema(description = "종료 시간", example = "18:00:00") + private LocalTime endTime; +} \ No newline at end of file diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java index ca4e084e..7bda7494 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java @@ -1,9 +1,9 @@ package com.dreamteam.alter.adapter.inbound.manager.workspace.dto; -import java.time.DayOfWeek; -import java.time.LocalTime; import java.util.List; +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.WorkerScheduleDto; + import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; @@ -25,22 +25,4 @@ public class CreateWorkerScheduleRequestDto { @NotEmpty(message = "스케줄 목록은 필수입니다.") @Valid private List schedules; - - @Getter - @NoArgsConstructor - @AllArgsConstructor - @Schema(description = "근무자 스케줄 정보") - public static class WorkerScheduleDto { - @NotNull(message = "요일은 필수입니다") - @Schema(description = "요일", example = "MONDAY") - private DayOfWeek dayOfWeek; - - @NotNull(message = "시작 시간은 필수입니다") - @Schema(description = "시작 시간", example = "09:00:00") - private LocalTime startTime; - - @NotNull(message = "종료 시간은 필수입니다") - @Schema(description = "종료 시간", example = "18:00:00") - private LocalTime endTime; - } } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java index 4f9958ca..4cc2b38e 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java @@ -1,16 +1,24 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Repository; + import com.dreamteam.alter.adapter.inbound.common.dto.CursorDto; import com.dreamteam.alter.adapter.inbound.common.dto.CursorPageRequest; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.ManagerWorkspaceWorkerListFilterDto; import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.ManagerWorkspaceListResponse; +import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.ManagerWorkspaceManagerListResponse; import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.ManagerWorkspaceResponse; import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.ManagerWorkspaceWorkerListResponse; -import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.UserWorkspaceWorkerListResponse; import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.UserWorkspaceManagerListResponse; -import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.ManagerWorkspaceManagerListResponse; -import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.WorkspaceWorkerResponse; +import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.UserWorkspaceWorkerListResponse; import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.UserWorkspaceWorkerResponse; +import com.dreamteam.alter.adapter.outbound.workspace.persistence.readonly.WorkspaceWorkerResponse; import com.dreamteam.alter.domain.reputation.entity.QReputationSummary; import com.dreamteam.alter.domain.reputation.type.ReputationType; import com.dreamteam.alter.domain.user.entity.ManagerUser; @@ -24,20 +32,15 @@ import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; import com.dreamteam.alter.domain.workspace.type.WorkerPositionType; import com.dreamteam.alter.domain.workspace.type.WorkspaceShiftStatus; +import com.dreamteam.alter.domain.workspace.type.WorkspaceStatus; import com.dreamteam.alter.domain.workspace.type.WorkspaceWorkerStatus; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.ObjectUtils; -import org.springframework.stereotype.Repository; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; +import lombok.RequiredArgsConstructor; @Repository @RequiredArgsConstructor @@ -544,6 +547,39 @@ public List getManagerWorkspaceManagerListW .fetch(); } + @Override + public Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { + QWorkspace qWorkspace = QWorkspace.workspace; + + return Optional.ofNullable( + queryFactory + .selectFrom(qWorkspace) + .where( + qWorkspace.id.eq(workspaceId), + qWorkspace.managerUser.eq(managerUser), + qWorkspace.status.eq(WorkspaceStatus.ACTIVATED) + ) + .fetchOne() + ); + } + + @Override + public boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { + QWorkspace qWorkspace = QWorkspace.workspace; + + Integer result = queryFactory + .selectOne() + .from(qWorkspace) + .where( + qWorkspace.id.eq(workspaceId), + qWorkspace.managerUser.eq(managerUser), + qWorkspace.status.eq(WorkspaceStatus.ACTIVATED) + ) + .fetchFirst(); + + return result != null; + } + private BooleanExpression eqWorkerStatus(QWorkspaceWorker qWorkspaceWorker, WorkspaceWorkerStatus status) { return status != null ? qWorkspaceWorker.status.eq(status) : null; } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java deleted file mode 100644 index 817957bc..00000000 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceRepositoryImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.dreamteam.alter.adapter.outbound.workspace.persistence; - -import java.util.Optional; - -import org.springframework.stereotype.Repository; - -import com.dreamteam.alter.domain.user.entity.ManagerUser; -import com.dreamteam.alter.domain.workspace.entity.Workspace; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; - -import lombok.RequiredArgsConstructor; - -@Repository -@RequiredArgsConstructor -public class WorkspaceRepositoryImpl implements WorkspaceRepository { - - private final WorkspaceJpaRepository workspaceJpaRepository; - - @Override - public Optional findByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { - return workspaceJpaRepository.findByIdAndManagerUser(workspaceId, managerUser); - } - - @Override - public boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { - return workspaceJpaRepository.existsByIdAndManagerUser(workspaceId, managerUser); - } -} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java new file mode 100644 index 00000000..310c55a4 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java @@ -0,0 +1,82 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import java.time.DayOfWeek; +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Repository; + +import com.dreamteam.alter.domain.workspace.entity.QWorkspaceWorker; +import com.dreamteam.alter.domain.workspace.entity.QWorkspaceWorkerSchedule; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; +import com.dreamteam.alter.domain.workspace.type.WorkspaceWorkerScheduleStatus; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; +import com.querydsl.jpa.impl.JPAQueryFactory; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class WorkspaceWorkerScheduleQueryRepositoryImpl implements WorkspaceWorkerScheduleQueryRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public Optional getByIdWithWorkspaceWorker(Long workerScheduleId) { + QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; + QWorkspaceWorker qWorkspaceWorker = QWorkspaceWorker.workspaceWorker; + + return Optional.ofNullable( + queryFactory + .selectFrom(qWorkspaceWorkerSchedule) + .join(qWorkspaceWorkerSchedule.workspaceWorker, qWorkspaceWorker).fetchJoin() + .where( + qWorkspaceWorkerSchedule.id.eq(workerScheduleId), + qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) + ) + .fetchOne() + ); + } + + @Override + public List getByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { + QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; + + return queryFactory + .selectFrom(qWorkspaceWorkerSchedule) + .where( + qWorkspaceWorkerSchedule.workspaceWorker.eq(workspaceWorker), + qWorkspaceWorkerSchedule.dayOfWeek.in(dayOfWeeks), + qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) + ) + .fetch(); + } + + @Override + public boolean existsById(Long workerScheduleId) { + QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; + + Integer find = queryFactory + .selectOne() + .from(qWorkspaceWorkerSchedule) + .where( + qWorkspaceWorkerSchedule.id.eq(workerScheduleId), + qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) + ) + .fetchFirst(); + + return find != null; + } + + @Override + public void deleteById(Long workerScheduleId) { + QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; + + queryFactory + .update(qWorkspaceWorkerSchedule) + .set(qWorkspaceWorkerSchedule.status, WorkspaceWorkerScheduleStatus.DELETED) + .where(qWorkspaceWorkerSchedule.id.eq(workerScheduleId)) + .execute(); + } +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index a7b17681..72689fab 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -1,12 +1,9 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; -import java.time.DayOfWeek; import java.util.List; -import java.util.Optional; import org.springframework.stereotype.Repository; -import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; @@ -22,24 +19,4 @@ public class WorkspaceWorkerScheduleRepositoryImpl implements WorkspaceWorkerSch public void saveAll(List workspaceWorkerSchedules) { workspaceWorkerScheduleJapRepository.saveAll(workspaceWorkerSchedules); } - - @Override - public boolean existsById(Long workerScheduleId) { - return workspaceWorkerScheduleJapRepository.existsById(workerScheduleId); - } - - @Override - public List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { - return workspaceWorkerScheduleJapRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); - } - - @Override - public Optional findByIdWithWorkspaceWorker(Long workerScheduleId) { - return workspaceWorkerScheduleJapRepository.findByIdWithWorkspaceWorker(workerScheduleId); - } - - @Override - public void deleteById(Long workerScheduleId) { - workspaceWorkerScheduleJapRepository.deleteById(workerScheduleId); - } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java similarity index 79% rename from src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java rename to src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java index b604da14..fee10dc5 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.WorkerScheduleDto; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import com.dreamteam.alter.common.exception.CustomException; import com.dreamteam.alter.common.exception.ErrorCode; @@ -15,9 +16,10 @@ import com.dreamteam.alter.domain.workspace.entity.Workspace; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateWorkerScheduleUseCase; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateFixedWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerQueryRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; import lombok.RequiredArgsConstructor; @@ -25,16 +27,17 @@ @Service @RequiredArgsConstructor @Transactional -public class ManagerCreateWorkerSchedule implements ManagerCreateWorkerScheduleUseCase { +public class ManagerCreateFixedWorkerSchedule implements ManagerCreateFixedWorkerScheduleUseCase { - private final WorkspaceRepository workspaceRepository; + private final WorkspaceQueryRepository workspaceQueryRepository; private final UserQueryRepository userQueryRepository; private final WorkspaceWorkerQueryRepository workspaceWorkerQueryRepository; private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + private final WorkspaceWorkerScheduleQueryRepository workspaceWorkerScheduleQueryRepository; @Override public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request) { - Workspace workspace = workspaceRepository.findByIdAndManagerUser(workspaceId, actor.getManagerUser()) + Workspace workspace = workspaceQueryRepository.getByIdAndManagerUser(workspaceId, actor.getManagerUser()) .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND)); User user = userQueryRepository.findById(request.getWorkerId()) @@ -55,16 +58,16 @@ public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRe } /** - * 같은 요일 곂치는 시간 검증 + * 곂치는 시간 검증 * @param workspaceWorker 해당 근무자 * @param request 요청 정보 */ private void validOverlappingTime(WorkspaceWorker workspaceWorker, CreateWorkerScheduleRequestDto request) { List dayOfWeeks = request.getSchedules().stream() - .map(CreateWorkerScheduleRequestDto.WorkerScheduleDto::getDayOfWeek) + .map(WorkerScheduleDto::getDayOfWeek) .toList(); - List workspaceWorkerSchedules = workspaceWorkerScheduleRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); + List workspaceWorkerSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); for (WorkspaceWorkerSchedule existingSchedule : workspaceWorkerSchedules) { request.getSchedules().stream() diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java similarity index 59% rename from src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java rename to src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java index 9117212c..eff62b16 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java @@ -5,9 +5,9 @@ import com.dreamteam.alter.common.exception.CustomException; import com.dreamteam.alter.common.exception.ErrorCode; import com.dreamteam.alter.domain.user.context.ManagerActor; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteWorkerScheduleUseCase; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteFixedWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; @@ -15,20 +15,20 @@ @Service @RequiredArgsConstructor @Transactional -public class ManagerDeleteWorkerSchedule implements ManagerDeleteWorkerScheduleUseCase { +public class ManagerDeleteFixedWorkerSchedule implements ManagerDeleteFixedWorkerScheduleUseCase { - private final WorkspaceRepository workspaceRepository; - private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + private final WorkspaceQueryRepository workspaceQueryRepository; + private final WorkspaceWorkerScheduleQueryRepository workspaceWorkerScheduleQueryRepository; @Override public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId) { - if (!workspaceRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - if (!workspaceWorkerScheduleRepository.existsById(workerScheduleId)) + if (!workspaceWorkerScheduleQueryRepository.existsById(workerScheduleId)) throw new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_DELETE); - workspaceWorkerScheduleRepository.deleteById(workerScheduleId); + workspaceWorkerScheduleQueryRepository.deleteById(workerScheduleId); // TODO Send FCM } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java similarity index 73% rename from src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java rename to src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java index 7045eb37..3dbb4945 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java @@ -9,9 +9,9 @@ import com.dreamteam.alter.common.exception.ErrorCode; import com.dreamteam.alter.domain.user.context.ManagerActor; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; -import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkerScheduleUseCase; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceRepository; -import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleRepository; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateFixedWorkerScheduleUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; @@ -19,17 +19,17 @@ @Service @RequiredArgsConstructor @Transactional -public class ManagerUpdateWorkerSchedule implements ManagerUpdateWorkerScheduleUseCase { +public class ManagerUpdateFixedWorkerSchedule implements ManagerUpdateFixedWorkerScheduleUseCase { - private final WorkspaceRepository workspaceRepository; - private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; + private final WorkspaceQueryRepository workspaceQueryRepository; + private final WorkspaceWorkerScheduleQueryRepository workspaceWorkerScheduleQueryRepository; @Override public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, UpdateWorkerScheduleRequestDto request) { - if (!workspaceRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleRepository.findByIdWithWorkspaceWorker(workerScheduleId) + WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleQueryRepository.getByIdWithWorkspaceWorker(workerScheduleId) .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); validOverlappingTime(workspaceWorkerSchedule, request); @@ -45,7 +45,7 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, * @param request 요청 정보 */ private void validOverlappingTime(WorkspaceWorkerSchedule workspaceWorkerSchedule, UpdateWorkerScheduleRequestDto request) { - List existingSchedules = workspaceWorkerScheduleRepository.findByWorkspaceWorkerAndDayOfWeekIn(workspaceWorkerSchedule.getWorkspaceWorker(), List.of(workspaceWorkerSchedule.getDayOfWeek())); + List existingSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorkerAndDayOfWeekIn(workspaceWorkerSchedule.getWorkspaceWorker(), List.of(workspaceWorkerSchedule.getDayOfWeek())); existingSchedules.stream() .filter(schedule -> !schedule.getId().equals(workspaceWorkerSchedule.getId())) diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index 46e9f2b5..ff4d2e9f 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -10,6 +10,7 @@ import com.dreamteam.alter.common.exception.CustomException; import com.dreamteam.alter.common.exception.ErrorCode; +import com.dreamteam.alter.domain.workspace.type.WorkspaceWorkerScheduleStatus; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -56,6 +57,10 @@ public class WorkspaceWorkerSchedule { @Column(name = "end_time", nullable = false) private LocalTime endTime; + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private WorkspaceWorkerScheduleStatus status; + @CreatedDate @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; @@ -75,6 +80,7 @@ public static WorkspaceWorkerSchedule create( .dayOfWeek(dayOfWeek) .startTime(startTime) .endTime(endTime) + .status(WorkspaceWorkerScheduleStatus.ACTIVE) .build(); workspaceWorkerSchedule.validTime(); diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateFixedWorkerScheduleUseCase.java similarity index 84% rename from src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java rename to src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateFixedWorkerScheduleUseCase.java index 8e505c7e..4e495469 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateWorkerScheduleUseCase.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerCreateFixedWorkerScheduleUseCase.java @@ -3,6 +3,6 @@ import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.CreateWorkerScheduleRequestDto; import com.dreamteam.alter.domain.user.context.ManagerActor; -public interface ManagerCreateWorkerScheduleUseCase { +public interface ManagerCreateFixedWorkerScheduleUseCase { void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteFixedWorkerScheduleUseCase.java similarity index 77% rename from src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java rename to src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteFixedWorkerScheduleUseCase.java index 51b8189f..68592416 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteWorkerScheduleUseCase.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerDeleteFixedWorkerScheduleUseCase.java @@ -2,6 +2,6 @@ import com.dreamteam.alter.domain.user.context.ManagerActor; -public interface ManagerDeleteWorkerScheduleUseCase { +public interface ManagerDeleteFixedWorkerScheduleUseCase { void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateFixedWorkerScheduleUseCase.java similarity index 85% rename from src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java rename to src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateFixedWorkerScheduleUseCase.java index 3dd5423a..ca431e55 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkerScheduleUseCase.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateFixedWorkerScheduleUseCase.java @@ -3,6 +3,6 @@ import com.dreamteam.alter.adapter.inbound.manager.schedule.dto.UpdateWorkerScheduleRequestDto; import com.dreamteam.alter.domain.user.context.ManagerActor; -public interface ManagerUpdateWorkerScheduleUseCase { +public interface ManagerUpdateFixedWorkerScheduleUseCase { void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, UpdateWorkerScheduleRequestDto request); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java index bd0073bd..aae6986c 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java @@ -71,4 +71,7 @@ List getManagerWorkspaceManagerListWithCurs Long workspaceId, CursorPageRequest pageRequest ); + + Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); + boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java deleted file mode 100644 index d68bb5f6..00000000 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.dreamteam.alter.domain.workspace.port.outbound; - -import java.util.Optional; - -import com.dreamteam.alter.domain.user.entity.ManagerUser; -import com.dreamteam.alter.domain.workspace.entity.Workspace; - -public interface WorkspaceRepository { - Optional findByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); - boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); -} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java new file mode 100644 index 00000000..a2038796 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java @@ -0,0 +1,17 @@ +package com.dreamteam.alter.domain.workspace.port.outbound; + +import java.time.DayOfWeek; +import java.util.List; +import java.util.Optional; + +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; + +public interface WorkspaceWorkerScheduleQueryRepository { + Optional getByIdWithWorkspaceWorker(Long workerScheduleId); + List getByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); + + boolean existsById(Long workerScheduleId); + + void deleteById(Long workerScheduleId); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java index de9f4d5f..46c5dd6e 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleRepository.java @@ -1,19 +1,9 @@ package com.dreamteam.alter.domain.workspace.port.outbound; -import java.time.DayOfWeek; import java.util.List; -import java.util.Optional; -import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleRepository { void saveAll(List workspaceWorkerSchedules); - - Optional findByIdWithWorkspaceWorker(Long workerScheduleId); - List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); - - boolean existsById(Long workerScheduleId); - - void deleteById(Long workerScheduleId); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java b/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java new file mode 100644 index 00000000..6ae370ae --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java @@ -0,0 +1,6 @@ +package com.dreamteam.alter.domain.workspace.type; + +public enum WorkspaceWorkerScheduleStatus { + ACTIVE, + DELETED +} From e8d63c8815d7e5d1c768789b48ac2d40b5ab484a Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Mon, 12 Jan 2026 20:45:17 +0900 Subject: [PATCH 08/12] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workspace/persistence/WorkspaceJpaRepository.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java index 7afcb2a2..70dbf57f 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceJpaRepository.java @@ -1,14 +1,8 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; -import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; -import com.dreamteam.alter.domain.user.entity.ManagerUser; import com.dreamteam.alter.domain.workspace.entity.Workspace; public interface WorkspaceJpaRepository extends JpaRepository { - Optional findByIdAndManagerUser(Long id, ManagerUser managerUser); - - boolean existsByIdAndManagerUser(Long id, ManagerUser managerUser); } From 78818732ff73de6cfd092c57d96ef23f1d80b0af Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Mon, 12 Jan 2026 22:26:02 +0900 Subject: [PATCH 09/12] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ManagerPostingControllerSpec.java | 12 +++- .../ManagerWorkerScheduleController.java | 12 ++-- .../ManagerWorkerScheduleControllerSpec.java | 64 ++++++++++++------- .../WorkspaceQueryRepositoryImpl.java | 16 ----- .../WorkspaceWorkerScheduleJapRepository.java | 19 ------ .../WorkspaceWorkerScheduleJpaRepository.java | 8 +++ ...paceWorkerScheduleQueryRepositoryImpl.java | 44 +++++-------- ...WorkspaceWorkerScheduleRepositoryImpl.java | 4 +- .../ManagerCreateFixedWorkerSchedule.java | 17 ++--- .../ManagerDeleteFixedWorkerSchedule.java | 9 ++- .../ManagerUpdateFixedWorkerSchedule.java | 4 +- .../alter/common/exception/ErrorCode.java | 6 -- .../alter/domain/posting/entity/Posting.java | 4 +- .../entity/WorkspaceWorkerSchedule.java | 10 ++- .../outbound/WorkspaceQueryRepository.java | 1 - ...orkspaceWorkerScheduleQueryRepository.java | 5 +- .../type/WorkspaceWorkerScheduleStatus.java | 2 +- 17 files changed, 103 insertions(+), 134 deletions(-) delete mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java create mode 100644 src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJpaRepository.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/posting/controller/ManagerPostingControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/posting/controller/ManagerPostingControllerSpec.java index 18a52e29..d599de3f 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/posting/controller/ManagerPostingControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/posting/controller/ManagerPostingControllerSpec.java @@ -192,15 +192,21 @@ ResponseEntity> updatePostingStatus( name = "요청에 키워드가 포함되지 않은 경우", value = "{\"code\" : \"B001\"}" ), + })), + @ApiResponse(responseCode = "404", description = "404 Error 실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { @ExampleObject( name = "삭제할 스케줄이 존재하지 않는 경우", - value = "{\"code\" : \"B021\", \"message\" : \"해당 Schedule ID\"}" + value = "{\"code\" : \"B019\"}" ), @ExampleObject( name = "수정할 스케줄이 존재하지 않는 경우", - value = "{\"code\" : \"B022\", \"message\" : \"해당 Schedule ID\"}" + value = "{\"code\" : \"B019\"}" ), - })) + })), }) ResponseEntity> updatePosting( @PathVariable Long postingId, diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java index d6756186..11893f72 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java @@ -30,9 +30,9 @@ @RequestMapping("/manager/workspaces/{workspaceId}/worker-schedules") public class ManagerWorkerScheduleController implements ManagerWorkerScheduleControllerSpec{ - private final ManagerCreateFixedWorkerScheduleUseCase managerCreateFixedWorkerScheduleUseCase; - private final ManagerUpdateFixedWorkerScheduleUseCase managerUpdateWorkerScheduleUseCase; - private final ManagerDeleteFixedWorkerScheduleUseCase managerDeleteFixedWorkerScheduleUseCase; + private final ManagerCreateFixedWorkerScheduleUseCase managerCreateFixedWorkerSchedule; + private final ManagerUpdateFixedWorkerScheduleUseCase managerUpdateWorkerSchedule; + private final ManagerDeleteFixedWorkerScheduleUseCase managerDeleteFixedWorkerSchedule; @Override @PostMapping @@ -41,7 +41,7 @@ public ResponseEntity> createWorkerSchedule( @RequestBody @Valid CreateWorkerScheduleRequestDto request ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerCreateFixedWorkerScheduleUseCase.execute(actor, workspaceId, request); + managerCreateFixedWorkerSchedule.execute(actor, workspaceId, request); return ResponseEntity.ok(CommonApiResponse.empty()); } @@ -53,7 +53,7 @@ public ResponseEntity> updateWorkerSchedule( @RequestBody @Valid UpdateWorkerScheduleRequestDto request ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerUpdateWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId, request); + managerUpdateWorkerSchedule.execute(actor, workspaceId, workerScheduleId, request); return ResponseEntity.ok(CommonApiResponse.empty()); } @@ -64,7 +64,7 @@ public ResponseEntity> deleteWorkerSchedule( @PathVariable Long workerScheduleId ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerDeleteFixedWorkerScheduleUseCase.execute(actor, workspaceId, workerScheduleId); + managerDeleteFixedWorkerSchedule.execute(actor, workspaceId, workerScheduleId); return ResponseEntity.ok(CommonApiResponse.empty()); } } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java index 880facc1..f5a0de7d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java @@ -24,30 +24,38 @@ public interface ManagerWorkerScheduleControllerSpec { @Operation(summary = "매니저 - 근무자 고정 스케줄 등록", description = "근무자의 요일별 고정 근무 시간을 등록합니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "고정 스케줄 등록 성공"), - @ApiResponse(responseCode = "400", description = "실패 케이스", + @ApiResponse(responseCode = "400", description = "400 Error 실패 케이스", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class), examples = { @ExampleObject( - name = "존재하지 않는 업장입니다.", - value = "{\"code\" : \"B008\"}" + name = "시작시간은 종료 시간보다 늦을 수 없습니다.", + value = "{\"code\" : \"B001\"}" ), + })), + @ApiResponse(responseCode = "404", description = "404 Error 실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { @ExampleObject( - name = "존재하지 않는 근무자입니다.", - value = "{\"code\" : \"B011\"}" + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B019\"}" ), @ExampleObject( name = "해당업장에 근무하는 근무자가 아닙니다.", - value = "{\"code\" : \"B023\"}" - ), - @ExampleObject( - name = "시작시간은 종료 시간보다 늦을 수 없습니다.", - value = "{\"code\" : \"B024\"}" + value = "{\"code\" : \"B019\"}" ), + })), + @ApiResponse(responseCode = "409", description = "409 Error 실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { @ExampleObject( name = "같은 요일에 겹치는 근무 시간이 존재합니다.", - value = "{\"code\" : \"B025\"}" + value = "{\"code\" : \"B020\"}" ), })), }) @@ -59,26 +67,38 @@ ResponseEntity> createWorkerSchedule( @Operation(summary = "매니저 - 근무자 고정 스케줄 수정", description = "근무자의 요일별 고정 근무 시간을 수정합니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "고정 스케줄 수정 성공"), - @ApiResponse(responseCode = "400", description = "실패 케이스", + @ApiResponse(responseCode = "400", description = "400 Error 실패 케이스", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class), examples = { @ExampleObject( - name = "존재하지 않는 업장입니다.", - value = "{\"code\" : \"B008\"}" + name = "시작시간은 종료 시간보다 늦을 수 없습니다.", + value = "{\"code\" : \"B001\"}" ), + })), + @ApiResponse(responseCode = "404", description = "404 Error 실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { @ExampleObject( - name = "수정할 스케줄을 찾을 수 없습니다.", - value = "{\"code\" : \"B022\"}" + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B019\"}" ), @ExampleObject( - name = "시작시간은 종료 시간보다 늦을 수 없습니다.", - value = "{\"code\" : \"B023\"}" + name = "수정할 스케줄을 찾을 수 없습니다.", + value = "{\"code\" : \"B019\"}" ), + })), + @ApiResponse(responseCode = "409", description = "409 Error 실패 케이스", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { @ExampleObject( name = "같은 요일에 겹치는 근무 시간이 존재합니다.", - value = "{\"code\" : \"B025\"}" + value = "{\"code\" : \"B020\"}" ), })), }) @@ -91,18 +111,18 @@ ResponseEntity> updateWorkerSchedule( @Operation(summary = "매니저 - 근무자 고정 스케줄 삭제", description = "근무자의 요일별 고정 근무 시간을 삭제합니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "고정 스케줄 삭제 성공"), - @ApiResponse(responseCode = "400", description = "실패 케이스", + @ApiResponse(responseCode = "404", description = "404 Error 실패 케이스", content = @Content( mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class), examples = { @ExampleObject( name = "존재하지 않는 업장입니다.", - value = "{\"code\" : \"B008\"}" + value = "{\"code\" : \"B019\"}" ), @ExampleObject( name = "삭제할 스케줄을 찾을 수 없습니다.", - value = "{\"code\" : \"B021\"}" + value = "{\"code\" : \"B019\"}" ), })), }) diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java index 4cc2b38e..6187de3b 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.java @@ -547,22 +547,6 @@ public List getManagerWorkspaceManagerListW .fetch(); } - @Override - public Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { - QWorkspace qWorkspace = QWorkspace.workspace; - - return Optional.ofNullable( - queryFactory - .selectFrom(qWorkspace) - .where( - qWorkspace.id.eq(workspaceId), - qWorkspace.managerUser.eq(managerUser), - qWorkspace.status.eq(WorkspaceStatus.ACTIVATED) - ) - .fetchOne() - ); - } - @Override public boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser) { QWorkspace qWorkspace = QWorkspace.workspace; diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java deleted file mode 100644 index 58ba6017..00000000 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJapRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.dreamteam.alter.adapter.outbound.workspace.persistence; - -import java.time.DayOfWeek; -import java.util.List; -import java.util.Optional; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; -import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; - -public interface WorkspaceWorkerScheduleJapRepository extends JpaRepository { - List findByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); - - @Query("SELECT wws FROM WorkspaceWorkerSchedule wws JOIN FETCH wws.workspaceWorker WHERE wws.id = :id") - Optional findByIdWithWorkspaceWorker(@Param("id") Long id); -} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJpaRepository.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJpaRepository.java new file mode 100644 index 00000000..014811e4 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleJpaRepository.java @@ -0,0 +1,8 @@ +package com.dreamteam.alter.adapter.outbound.workspace.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; + +public interface WorkspaceWorkerScheduleJpaRepository extends JpaRepository { +} diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java index 310c55a4..7374d72d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java @@ -10,8 +10,8 @@ import com.dreamteam.alter.domain.workspace.entity.QWorkspaceWorkerSchedule; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; -import com.dreamteam.alter.domain.workspace.type.WorkspaceWorkerScheduleStatus; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; +import com.dreamteam.alter.domain.workspace.type.WorkspaceWorkerScheduleStatus; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -22,6 +22,21 @@ public class WorkspaceWorkerScheduleQueryRepositoryImpl implements WorkspaceWork private final JPAQueryFactory queryFactory; + @Override + public Optional findById(Long workerScheduleId) { + QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; + + return Optional.ofNullable( + queryFactory + .selectFrom(qWorkspaceWorkerSchedule) + .where( + qWorkspaceWorkerSchedule.id.eq(workerScheduleId), + qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) + ) + .fetchOne() + ); + } + @Override public Optional getByIdWithWorkspaceWorker(Long workerScheduleId) { QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; @@ -52,31 +67,4 @@ public List getByWorkspaceWorkerAndDayOfWeekIn(Workspac ) .fetch(); } - - @Override - public boolean existsById(Long workerScheduleId) { - QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; - - Integer find = queryFactory - .selectOne() - .from(qWorkspaceWorkerSchedule) - .where( - qWorkspaceWorkerSchedule.id.eq(workerScheduleId), - qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) - ) - .fetchFirst(); - - return find != null; - } - - @Override - public void deleteById(Long workerScheduleId) { - QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; - - queryFactory - .update(qWorkspaceWorkerSchedule) - .set(qWorkspaceWorkerSchedule.status, WorkspaceWorkerScheduleStatus.DELETED) - .where(qWorkspaceWorkerSchedule.id.eq(workerScheduleId)) - .execute(); - } } diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java index 72689fab..0a279ac0 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleRepositoryImpl.java @@ -13,10 +13,10 @@ @RequiredArgsConstructor public class WorkspaceWorkerScheduleRepositoryImpl implements WorkspaceWorkerScheduleRepository { - private final WorkspaceWorkerScheduleJapRepository workspaceWorkerScheduleJapRepository; + private final WorkspaceWorkerScheduleJpaRepository workspaceWorkerScheduleJpaRepository; @Override public void saveAll(List workspaceWorkerSchedules) { - workspaceWorkerScheduleJapRepository.saveAll(workspaceWorkerSchedules); + workspaceWorkerScheduleJpaRepository.saveAll(workspaceWorkerSchedules); } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java index fee10dc5..2582e12b 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java @@ -11,9 +11,6 @@ import com.dreamteam.alter.common.exception.CustomException; import com.dreamteam.alter.common.exception.ErrorCode; import com.dreamteam.alter.domain.user.context.ManagerActor; -import com.dreamteam.alter.domain.user.entity.User; -import com.dreamteam.alter.domain.user.port.outbound.UserQueryRepository; -import com.dreamteam.alter.domain.workspace.entity.Workspace; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerCreateFixedWorkerScheduleUseCase; @@ -30,21 +27,17 @@ public class ManagerCreateFixedWorkerSchedule implements ManagerCreateFixedWorkerScheduleUseCase { private final WorkspaceQueryRepository workspaceQueryRepository; - private final UserQueryRepository userQueryRepository; private final WorkspaceWorkerQueryRepository workspaceWorkerQueryRepository; private final WorkspaceWorkerScheduleRepository workspaceWorkerScheduleRepository; private final WorkspaceWorkerScheduleQueryRepository workspaceWorkerScheduleQueryRepository; @Override public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request) { - Workspace workspace = workspaceQueryRepository.getByIdAndManagerUser(workspaceId, actor.getManagerUser()) - .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_NOT_FOUND)); + if (workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - User user = userQueryRepository.findById(request.getWorkerId()) - .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); - - WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findActiveWorkerByWorkspaceAndUser(workspace, user) - .orElseThrow(() -> new CustomException(ErrorCode.WORKSPACE_WORKER_NOT_FOUNT)); + WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findById(request.getWorkerId()) + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "해당 업장에 근무하는 사용자가 아닙니다.")); validOverlappingTime(workspaceWorker, request); @@ -53,8 +46,6 @@ public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRe .map(r -> WorkspaceWorkerSchedule.create(workspaceWorker, r.getDayOfWeek(), r.getStartTime(), r.getEndTime())) .toList() ); - - // TODO Send FCM } /** diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java index eff62b16..0cd2c37d 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerDeleteFixedWorkerSchedule.java @@ -5,6 +5,7 @@ import com.dreamteam.alter.common.exception.CustomException; import com.dreamteam.alter.common.exception.ErrorCode; import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerDeleteFixedWorkerScheduleUseCase; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerScheduleQueryRepository; @@ -25,11 +26,9 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId) if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - if (!workspaceWorkerScheduleQueryRepository.existsById(workerScheduleId)) - throw new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_DELETE); + WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleQueryRepository.findById(workerScheduleId) + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "삭제할 스케줄을 찾지 못하였습니다.")); - workspaceWorkerScheduleQueryRepository.deleteById(workerScheduleId); - - // TODO Send FCM + workspaceWorkerSchedule.delete(); } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java index 3dbb4945..00dc9b37 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java @@ -30,13 +30,11 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); WorkspaceWorkerSchedule workspaceWorkerSchedule = workspaceWorkerScheduleQueryRepository.getByIdWithWorkspaceWorker(workerScheduleId) - .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE)); + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "수정할 스케줄을 찾을 수 없습니다.")); validOverlappingTime(workspaceWorkerSchedule, request); workspaceWorkerSchedule.update(request.getStartTime(), request.getEndTime()); - - // TODO Send FCM } /** diff --git a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java index ac83aaab..4d37eccc 100644 --- a/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java +++ b/src/main/java/com/dreamteam/alter/common/exception/ErrorCode.java @@ -42,12 +42,6 @@ public enum ErrorCode { WORKSPACE_WORKER_ALREADY_EXISTS(400, "B018", "이미 근무중인 사용자입니다."), NOT_FOUND(404, "B019", "요청한 리소스를 찾을 수 없습니다."), CONFLICT(409, "B020", "변경할 수 없는 상태입니다."), - SCHEDULE_NOT_FOUND_FOR_DELETE(400, "B021", "삭제할 스케줄을 찾을 수 없습니다"), - SCHEDULE_NOT_FOUND_FOR_UPDATE(400, "B022", "수정할 스케줄을 찾을 수 없습니다"), - WORKSPACE_WORKER_NOT_FOUNT(400, "B023", "해당 업장에 근무하는 사용자가 아닙니다."), - START_TIME_AFTER_END_TIME(400, "B024", "시작 시간은 종료 시간보다 늦을 수 없습니다."), - SCHEDULE_TIME_OVERLAPPING(400, "B025", "같은 요일에 겹치는 근무 시간이 존재합니다."), - INTERNAL_SERVER_ERROR(400, "C001", "서버 내부 오류입니다."), EXTERNAL_API_ERROR(502, "C002", "외부 API 연동에 실패했습니다."), ; diff --git a/src/main/java/com/dreamteam/alter/domain/posting/entity/Posting.java b/src/main/java/com/dreamteam/alter/domain/posting/entity/Posting.java index 919b9abb..0f2bc054 100644 --- a/src/main/java/com/dreamteam/alter/domain/posting/entity/Posting.java +++ b/src/main/java/com/dreamteam/alter/domain/posting/entity/Posting.java @@ -177,7 +177,7 @@ public void updateSchedules(List updateSchedules) { PostingSchedule existingSchedule = this.schedules.stream() .filter(schedule -> schedule.getId().equals(updateDto.getId())) .findFirst() - .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_UPDATE, updateDto.getId().toString())); + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "수정할 스케줄을 찾을 수 없습니다.")); existingSchedule.update( updateDto.getWorkingDays().stream() @@ -200,7 +200,7 @@ public void deleteSchedules(List deleteScheduleIds) { PostingSchedule existingSchedule = this.schedules.stream() .filter(schedule -> schedule.getId().equals(scheduleId)) .findFirst() - .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND_FOR_DELETE, scheduleId.toString())); + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "삭제할 스케줄을 찾을 수 없습니다.")); existingSchedule.updateStatus(PostingStatus.DELETED); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index ff4d2e9f..dac755c6 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -80,7 +80,7 @@ public static WorkspaceWorkerSchedule create( .dayOfWeek(dayOfWeek) .startTime(startTime) .endTime(endTime) - .status(WorkspaceWorkerScheduleStatus.ACTIVE) + .status(WorkspaceWorkerScheduleStatus.ACTIVATED) .build(); workspaceWorkerSchedule.validTime(); @@ -96,11 +96,15 @@ public void update(LocalTime startTime, LocalTime endTime) { public void validTime() { if (this.startTime.isAfter(this.endTime)) - throw new CustomException(ErrorCode.START_TIME_AFTER_END_TIME); + throw new CustomException(ErrorCode.ILLEGAL_ARGUMENT, "시작 시간은 종료 시간보다 늦을 수 없습니다."); } public void validOverlappingTime(LocalTime newStart, LocalTime newEnd) { if (newStart.isBefore(this.endTime) && newEnd.isAfter(this.startTime)) - throw new CustomException(ErrorCode.SCHEDULE_TIME_OVERLAPPING); + throw new CustomException(ErrorCode.CONFLICT, "같은 요일에 겹치는 근무 시간이 존재합니다."); + } + + public void delete() { + this.status = WorkspaceWorkerScheduleStatus.DELETED; } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java index aae6986c..b2e3f53e 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceQueryRepository.java @@ -72,6 +72,5 @@ List getManagerWorkspaceManagerListWithCurs CursorPageRequest pageRequest ); - Optional getByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); boolean existsByIdAndManagerUser(Long workspaceId, ManagerUser managerUser); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java index a2038796..91826741 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java @@ -8,10 +8,7 @@ import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorkerSchedule; public interface WorkspaceWorkerScheduleQueryRepository { + Optional findById(Long workerScheduleId); Optional getByIdWithWorkspaceWorker(Long workerScheduleId); List getByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); - - boolean existsById(Long workerScheduleId); - - void deleteById(Long workerScheduleId); } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java b/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java index 6ae370ae..df43ef5f 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/type/WorkspaceWorkerScheduleStatus.java @@ -1,6 +1,6 @@ package com.dreamteam.alter.domain.workspace.type; public enum WorkspaceWorkerScheduleStatus { - ACTIVE, + ACTIVATED, DELETED } From d204460902d8739bca24cb8b38bf625c48985953 Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sat, 17 Jan 2026 16:39:18 +0900 Subject: [PATCH 10/12] =?UTF-8?q?fix:=20=EB=81=9D=EC=9A=94=EC=9D=BC=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 --- ...ManagerFixedWorkerScheduleController.java} | 2 +- ...gerFixedWorkerScheduleControllerSpec.java} | 4 +- .../dto/UpdateWorkerScheduleRequestDto.java | 13 ++++++- .../schedule/dto/WorkerScheduleDto.java | 14 ++++--- ...paceWorkerScheduleQueryRepositoryImpl.java | 4 +- .../ManagerCreateFixedWorkerSchedule.java | 38 ++++++++++-------- .../ManagerUpdateFixedWorkerSchedule.java | 18 +++++++-- .../entity/WorkspaceWorkerSchedule.java | 39 ++++++++++++++----- ...orkspaceWorkerScheduleQueryRepository.java | 3 +- 9 files changed, 91 insertions(+), 44 deletions(-) rename src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/{ManagerWorkerScheduleController.java => ManagerFixedWorkerScheduleController.java} (96%) rename src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/{ManagerWorkerScheduleControllerSpec.java => ManagerFixedWorkerScheduleControllerSpec.java} (97%) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java similarity index 96% rename from src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java rename to src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java index 11893f72..16d55b4f 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java @@ -28,7 +28,7 @@ @RequiredArgsConstructor @Validated @RequestMapping("/manager/workspaces/{workspaceId}/worker-schedules") -public class ManagerWorkerScheduleController implements ManagerWorkerScheduleControllerSpec{ +public class ManagerFixedWorkerScheduleController implements ManagerFixedWorkerScheduleControllerSpec { private final ManagerCreateFixedWorkerScheduleUseCase managerCreateFixedWorkerSchedule; private final ManagerUpdateFixedWorkerScheduleUseCase managerUpdateWorkerSchedule; diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleControllerSpec.java similarity index 97% rename from src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java rename to src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleControllerSpec.java index f5a0de7d..d9dcf424 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerWorkerScheduleControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleControllerSpec.java @@ -18,8 +18,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -@Tag(name = "MANAGER - 근무자 스케줄 관리 API") -public interface ManagerWorkerScheduleControllerSpec { +@Tag(name = "MANAGER - 근무자 고정 스케줄 관리 API") +public interface ManagerFixedWorkerScheduleControllerSpec { @Operation(summary = "매니저 - 근무자 고정 스케줄 등록", description = "근무자의 요일별 고정 근무 시간을 등록합니다.") @ApiResponses(value = { diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java index 9b88290c..a351f7dd 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/UpdateWorkerScheduleRequestDto.java @@ -1,5 +1,6 @@ package com.dreamteam.alter.adapter.inbound.manager.schedule.dto; +import java.time.DayOfWeek; import java.time.LocalTime; import io.swagger.v3.oas.annotations.media.Schema; @@ -14,11 +15,19 @@ @Schema(description = "매니저 - 근무자 고정 스케줄 수정 DTO") public class UpdateWorkerScheduleRequestDto { + @NotNull(message = "시작 요일은 필수입니다") + @Schema(description = "시작 요일", example = "MONDAY") + private DayOfWeek startDayOfWeek; + @NotNull(message = "시작 시간은 필수입니다") - @Schema(description = "시작 시간", example = "09:00:00") + @Schema(description = "시작 시간", example = "22:00:00") private LocalTime startTime; + @NotNull(message = "종료 요일은 필수입니다") + @Schema(description = "종료 요일", example = "TUESDAY") + private DayOfWeek endDayOfWeek; + @NotNull(message = "종료 시간은 필수입니다") - @Schema(description = "종료 시간", example = "18:00:00") + @Schema(description = "종료 시간", example = "04:00:00") private LocalTime endTime; } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java index 16ab505f..57cd0f65 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/dto/WorkerScheduleDto.java @@ -14,15 +14,19 @@ @AllArgsConstructor @Schema(description = "근무자 스케줄 정보") public class WorkerScheduleDto { - @NotNull(message = "요일은 필수입니다") - @Schema(description = "요일", example = "MONDAY") - private DayOfWeek dayOfWeek; + @NotNull(message = "시작 요일은 필수입니다") + @Schema(description = "시작 요일", example = "MONDAY") + private DayOfWeek startDayOfWeek; @NotNull(message = "시작 시간은 필수입니다") - @Schema(description = "시작 시간", example = "09:00:00") + @Schema(description = "시작 시간", example = "22:00:00") private LocalTime startTime; + @NotNull(message = "종료 요일은 필수입니다") + @Schema(description = "종료 요일", example = "TUESDAY") + private DayOfWeek endDayOfWeek; + @NotNull(message = "종료 시간은 필수입니다") - @Schema(description = "종료 시간", example = "18:00:00") + @Schema(description = "종료 시간", example = "04:00:00") private LocalTime endTime; } \ No newline at end of file diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java index 7374d72d..cae549a4 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerScheduleQueryRepositoryImpl.java @@ -1,6 +1,5 @@ package com.dreamteam.alter.adapter.outbound.workspace.persistence; -import java.time.DayOfWeek; import java.util.List; import java.util.Optional; @@ -55,14 +54,13 @@ public Optional getByIdWithWorkspaceWorker(Long workerS } @Override - public List getByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks) { + public List getByWorkspaceWorker(WorkspaceWorker workspaceWorker) { QWorkspaceWorkerSchedule qWorkspaceWorkerSchedule = QWorkspaceWorkerSchedule.workspaceWorkerSchedule; return queryFactory .selectFrom(qWorkspaceWorkerSchedule) .where( qWorkspaceWorkerSchedule.workspaceWorker.eq(workspaceWorker), - qWorkspaceWorkerSchedule.dayOfWeek.in(dayOfWeeks), qWorkspaceWorkerSchedule.status.ne(WorkspaceWorkerScheduleStatus.DELETED) ) .fetch(); diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java index 2582e12b..55f460c7 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java @@ -1,6 +1,5 @@ package com.dreamteam.alter.application.workspace.usecase; -import java.time.DayOfWeek; import java.util.List; import org.springframework.stereotype.Service; @@ -33,37 +32,44 @@ public class ManagerCreateFixedWorkerSchedule implements ManagerCreateFixedWorke @Override public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRequestDto request) { - if (workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) + if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findById(request.getWorkerId()) .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "해당 업장에 근무하는 사용자가 아닙니다.")); - validOverlappingTime(workspaceWorker, request); + validOverlappingTime(workspaceWorker, request.getSchedules()); workspaceWorkerScheduleRepository.saveAll( request.getSchedules().stream() - .map(r -> WorkspaceWorkerSchedule.create(workspaceWorker, r.getDayOfWeek(), r.getStartTime(), r.getEndTime())) + .map(r -> WorkspaceWorkerSchedule.create( + workspaceWorker, + r.getStartDayOfWeek(), + r.getStartTime(), + r.getEndDayOfWeek(), + r.getEndTime() + )) .toList() ); } /** - * 곂치는 시간 검증 + * 겹치는 시간 검증 * @param workspaceWorker 해당 근무자 - * @param request 요청 정보 + * @param newSchedules 새로 생성할 스케줄 목록 */ - private void validOverlappingTime(WorkspaceWorker workspaceWorker, CreateWorkerScheduleRequestDto request) { - List dayOfWeeks = request.getSchedules().stream() - .map(WorkerScheduleDto::getDayOfWeek) - .toList(); + private void validOverlappingTime(WorkspaceWorker workspaceWorker, List newSchedules) { + List existingSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorker(workspaceWorker); - List workspaceWorkerSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorkerAndDayOfWeekIn(workspaceWorker, dayOfWeeks); - - for (WorkspaceWorkerSchedule existingSchedule : workspaceWorkerSchedules) { - request.getSchedules().stream() - .filter(newSchedule -> newSchedule.getDayOfWeek().equals(existingSchedule.getDayOfWeek())) - .forEach(newSchedule -> existingSchedule.validOverlappingTime(newSchedule.getStartTime(), newSchedule.getEndTime())); + for (WorkspaceWorkerSchedule existingSchedule : existingSchedules) { + for (WorkerScheduleDto newSchedule : newSchedules) { + existingSchedule.validOverlappingTime( + newSchedule.getStartDayOfWeek(), + newSchedule.getStartTime(), + newSchedule.getEndDayOfWeek(), + newSchedule.getEndTime() + ); + } } } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java index 00dc9b37..f9fb8b63 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateFixedWorkerSchedule.java @@ -34,19 +34,29 @@ public void execute(ManagerActor actor, Long workspaceId, Long workerScheduleId, validOverlappingTime(workspaceWorkerSchedule, request); - workspaceWorkerSchedule.update(request.getStartTime(), request.getEndTime()); + workspaceWorkerSchedule.update( + request.getStartDayOfWeek(), + request.getStartTime(), + request.getEndDayOfWeek(), + request.getEndTime() + ); } /** - * 같은 요일 곂치는 시간 검증 (자기 자신 제외) + * 겹치는 시간 검증 (자기 자신 제외) * @param workspaceWorkerSchedule 수정 중인 스케줄 * @param request 요청 정보 */ private void validOverlappingTime(WorkspaceWorkerSchedule workspaceWorkerSchedule, UpdateWorkerScheduleRequestDto request) { - List existingSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorkerAndDayOfWeekIn(workspaceWorkerSchedule.getWorkspaceWorker(), List.of(workspaceWorkerSchedule.getDayOfWeek())); + List existingSchedules = workspaceWorkerScheduleQueryRepository.getByWorkspaceWorker(workspaceWorkerSchedule.getWorkspaceWorker()); existingSchedules.stream() .filter(schedule -> !schedule.getId().equals(workspaceWorkerSchedule.getId())) - .forEach(schedule -> schedule.validOverlappingTime(request.getStartTime(), request.getEndTime())); + .forEach(schedule -> schedule.validOverlappingTime( + request.getStartDayOfWeek(), + request.getStartTime(), + request.getEndDayOfWeek(), + request.getEndTime() + )); } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java index dac755c6..574b76c5 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorkerSchedule.java @@ -48,12 +48,16 @@ public class WorkspaceWorkerSchedule { private WorkspaceWorker workspaceWorker; @Enumerated(EnumType.STRING) - @Column(name = "day_of_week", nullable = false) - private DayOfWeek dayOfWeek; + @Column(name = "start_day_of_week", nullable = false) + private DayOfWeek startDayOfWeek; @Column(name = "start_time", nullable = false) private LocalTime startTime; + @Enumerated(EnumType.STRING) + @Column(name = "end_day_of_week", nullable = false) + private DayOfWeek endDayOfWeek; + @Column(name = "end_time", nullable = false) private LocalTime endTime; @@ -71,14 +75,16 @@ public class WorkspaceWorkerSchedule { public static WorkspaceWorkerSchedule create( WorkspaceWorker workspaceWorker, - DayOfWeek dayOfWeek, + DayOfWeek startDayOfWeek, LocalTime startTime, + DayOfWeek endDayOfWeek, LocalTime endTime ) { WorkspaceWorkerSchedule workspaceWorkerSchedule = WorkspaceWorkerSchedule.builder() .workspaceWorker(workspaceWorker) - .dayOfWeek(dayOfWeek) + .startDayOfWeek(startDayOfWeek) .startTime(startTime) + .endDayOfWeek(endDayOfWeek) .endTime(endTime) .status(WorkspaceWorkerScheduleStatus.ACTIVATED) .build(); @@ -87,21 +93,36 @@ public static WorkspaceWorkerSchedule create( return workspaceWorkerSchedule; } - public void update(LocalTime startTime, LocalTime endTime) { + public void update(DayOfWeek startDayOfWeek, LocalTime startTime, DayOfWeek endDayOfWeek, LocalTime endTime) { + this.startDayOfWeek = startDayOfWeek; this.startTime = startTime; + this.endDayOfWeek = endDayOfWeek; this.endTime = endTime; validTime(); } public void validTime() { - if (this.startTime.isAfter(this.endTime)) + if (toWeekMinutes(this.startDayOfWeek, this.startTime) >= toWeekMinutes(this.endDayOfWeek, this.endTime)) throw new CustomException(ErrorCode.ILLEGAL_ARGUMENT, "시작 시간은 종료 시간보다 늦을 수 없습니다."); } - public void validOverlappingTime(LocalTime newStart, LocalTime newEnd) { - if (newStart.isBefore(this.endTime) && newEnd.isAfter(this.startTime)) - throw new CustomException(ErrorCode.CONFLICT, "같은 요일에 겹치는 근무 시간이 존재합니다."); + public void validOverlappingTime(DayOfWeek newStartDay, LocalTime newStart, DayOfWeek newEndDay, LocalTime newEnd) { + long thisStartMinutes = toWeekMinutes(this.startDayOfWeek, this.startTime); + long thisEndMinutes = toWeekMinutes(this.endDayOfWeek, this.endTime); + long newStartMinutes = toWeekMinutes(newStartDay, newStart); + long newEndMinutes = toWeekMinutes(newEndDay, newEnd); + + if (newStartMinutes < thisEndMinutes && newEndMinutes > thisStartMinutes) + throw new CustomException(ErrorCode.CONFLICT, "겹치는 근무 시간이 존재합니다."); + } + + /** + * 요일과 시간을 주 시작(월요일 00:00) 기준 분 단위로 변환 + * 예: 월요일 09:00 → 540분, 화요일 18:30 → 2550분 + */ + private long toWeekMinutes(DayOfWeek dayOfWeek, LocalTime time) { + return (long) (dayOfWeek.getValue() - 1) * 24 * 60 + time.getHour() * 60 + time.getMinute(); } public void delete() { diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java index 91826741..cd0be073 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerScheduleQueryRepository.java @@ -1,6 +1,5 @@ package com.dreamteam.alter.domain.workspace.port.outbound; -import java.time.DayOfWeek; import java.util.List; import java.util.Optional; @@ -10,5 +9,5 @@ public interface WorkspaceWorkerScheduleQueryRepository { Optional findById(Long workerScheduleId); Optional getByIdWithWorkspaceWorker(Long workerScheduleId); - List getByWorkspaceWorkerAndDayOfWeekIn(WorkspaceWorker workspaceWorker, List dayOfWeeks); + List getByWorkspaceWorker(WorkspaceWorker workspaceWorker); } From 3b7c7ae46f4649f522f36ff1122bae6780b04031 Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sat, 17 Jan 2026 16:42:14 +0900 Subject: [PATCH 11/12] =?UTF-8?q?fix:=20api=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit request 필드명 변경 --- .../controller/ManagerFixedWorkerScheduleController.java | 2 +- .../workspace/dto/CreateWorkerScheduleRequestDto.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java index 16d55b4f..cda59f4d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/schedule/controller/ManagerFixedWorkerScheduleController.java @@ -27,7 +27,7 @@ @PreAuthorize("hasAnyRole('MANAGER')") @RequiredArgsConstructor @Validated -@RequestMapping("/manager/workspaces/{workspaceId}/worker-schedules") +@RequestMapping("/manager/workspaces/{workspaceId}/fixed-worker-schedules") public class ManagerFixedWorkerScheduleController implements ManagerFixedWorkerScheduleControllerSpec { private final ManagerCreateFixedWorkerScheduleUseCase managerCreateFixedWorkerSchedule; diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java index 7bda7494..725e9910 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/CreateWorkerScheduleRequestDto.java @@ -18,9 +18,9 @@ @Schema(description = "매니저 - 근무자 고정 스케줄 등록 DTO") public class CreateWorkerScheduleRequestDto { - @NotNull(message = "근무자 ID는 필수입니다.") - @Schema(description = "근무자 ID", example = "1") - private Long workerId; + @NotNull(message = "업장 근무자 ID는 필수입니다.") + @Schema(description = "업장 근무자 ID", example = "1") + private Long workspaceWorkerId; @NotEmpty(message = "스케줄 목록은 필수입니다.") @Valid From 78f521d8468fc6d5a7201a527ec0e345b5e968a4 Mon Sep 17 00:00:00 2001 From: Choi Junyoung Date: Sat, 17 Jan 2026 16:43:09 +0900 Subject: [PATCH 12/12] =?UTF-8?q?fix:=20api=20=EC=97=94=EB=93=9C=ED=8F=AC?= =?UTF-8?q?=EC=9D=B8=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit request 필드명 변경 --- .../workspace/usecase/ManagerCreateFixedWorkerSchedule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java index 55f460c7..4ab9e3b7 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerCreateFixedWorkerSchedule.java @@ -35,7 +35,7 @@ public void execute(ManagerActor actor, Long workspaceId, CreateWorkerScheduleRe if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); - WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findById(request.getWorkerId()) + WorkspaceWorker workspaceWorker = workspaceWorkerQueryRepository.findById(request.getWorkspaceWorkerId()) .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "해당 업장에 근무하는 사용자가 아닙니다.")); validOverlappingTime(workspaceWorker, request.getSchedules());