From 573230f0446c51d1e992aefef2dec81d73957f59 Mon Sep 17 00:00:00 2001 From: Seungwan Yoo Date: Sun, 10 May 2026 17:28:34 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=BD=94=EB=93=9C=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=ED=95=84=EB=93=9C=20=EB=B0=8F=20UseCase=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 --- ...ManagerUpdateWorkspaceWorkerColorCode.java | 52 +++++++++++++++++++ .../workspace/entity/WorkspaceWorker.java | 10 ++++ ...UpdateWorkspaceWorkerColorCodeUseCase.java | 8 +++ .../WorkspaceWorkerQueryRepository.java | 8 +-- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java new file mode 100644 index 00000000..1b727869 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java @@ -0,0 +1,52 @@ +package com.dreamteam.alter.application.workspace.usecase; + +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; +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.WorkspaceWorker; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkspaceWorkerColorCodeUseCase; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; +import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceWorkerQueryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service("managerUpdateWorkspaceWorkerColorCode") +@RequiredArgsConstructor +@Transactional +public class ManagerUpdateWorkspaceWorkerColorCode implements ManagerUpdateWorkspaceWorkerColorCodeUseCase { + + private final WorkspaceQueryRepository workspaceQueryRepository; + private final WorkspaceWorkerQueryRepository workspaceWorkerQueryRepository; + + @Override + public void execute( + ManagerActor actor, + Long workspaceId, + Long workerId, + UpdateWorkspaceWorkerColorRequestDto request + ) { + if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) { + throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); + } + + WorkspaceWorker worker = workspaceWorkerQueryRepository.findById(workerId) + .orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "근무자를 찾을 수 없습니다")); + + if (!worker.getWorkspace().getId().equals(workspaceId)) { + throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); + } + + if (!WorkspaceWorker.DEFAULT_COLOR_CODE.equals(request.getColorCode()) + && workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode( + workspaceId, + request.getColorCode(), + workerId + )) { + throw new CustomException(ErrorCode.CONFLICT, "이미 사용 중인 근무자 색상입니다."); + } + + worker.updateColorCode(request.getColorCode()); + } +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java index 1c264fc0..f0004377 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java @@ -20,6 +20,8 @@ @EntityListeners(AuditingEntityListener.class) public class WorkspaceWorker { + public static final String DEFAULT_COLOR_CODE = "#9CA3AF"; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -36,6 +38,10 @@ public class WorkspaceWorker { @Column(name = "status", nullable = false) private WorkspaceWorkerStatus status; + @Builder.Default + @Column(name = "color_code", nullable = false, length = 7) + private String colorCode = DEFAULT_COLOR_CODE; + @Column(name = "employed_at", nullable = false) private LocalDate employedAt; @@ -67,4 +73,8 @@ public void resign() { this.resignedAt = LocalDate.now(); } + public void updateColorCode(String colorCode) { + this.colorCode = colorCode; + } + } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java new file mode 100644 index 00000000..97973a83 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java @@ -0,0 +1,8 @@ +package com.dreamteam.alter.domain.workspace.port.inbound; + +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; +import com.dreamteam.alter.domain.user.context.ManagerActor; + +public interface ManagerUpdateWorkspaceWorkerColorCodeUseCase { + void execute(ManagerActor actor, Long workspaceId, Long workerId, UpdateWorkspaceWorkerColorRequestDto request); +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerQueryRepository.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerQueryRepository.java index 5bd94ecc..c6bdc9c4 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerQueryRepository.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerQueryRepository.java @@ -15,11 +15,13 @@ public interface WorkspaceWorkerQueryRepository { Optional findById(Long id); List findAllById(List ids); List findAllActiveByUserId(Long userId); - + long getUserActiveWorkspaceCount(User user); - + List getUserActiveWorkspaceListWithCursor( - CursorPageRequest request, + CursorPageRequest request, User user ); + + boolean existsActivatedByWorkspaceAndColorCode(Long workspaceId, String colorCode, Long excludeWorkerId); } From bd47f56e1cfa9b285f122231c1244569397ece17 Mon Sep 17 00:00:00 2001 From: Seungwan Yoo Date: Sun, 10 May 2026 17:28:39 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?DTO=20=EB=B0=8F=20=EC=9D=91=EB=8B=B5=20=ED=95=84=EB=93=9C=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 --- .../inbound/common/dto/WorkerSummaryDto.java | 10 +++++--- ...ManagerWorkspaceWorkerListResponseDto.java | 5 ++++ .../UpdateWorkspaceWorkerColorRequestDto.java | 20 ++++++++++++++++ .../WorkspaceQueryRepositoryImpl.java | 2 ++ .../WorkspaceWorkerQueryRepositoryImpl.java | 24 ++++++++++++++++++- .../ManagerWorkspaceWorkerListResponse.java | 2 ++ 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/UpdateWorkspaceWorkerColorRequestDto.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/common/dto/WorkerSummaryDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/common/dto/WorkerSummaryDto.java index 750ff327..dfcae9b5 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/common/dto/WorkerSummaryDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/common/dto/WorkerSummaryDto.java @@ -11,21 +11,25 @@ @Builder(access = AccessLevel.PRIVATE) @Schema(description = "근무자 요약 정보") public class WorkerSummaryDto { - + @Schema(description = "근무자 ID", example = "1") private Long workerId; - + @Schema(description = "근무자명", example = "김알바") private String workerName; + @Schema(description = "근무자 표시 색상 (hex)", example = "#9CA3AF") + private String colorCode; + public static WorkerSummaryDto of(WorkspaceWorker workspaceWorker) { if (ObjectUtils.isEmpty(workspaceWorker)) { return null; } - + return WorkerSummaryDto.builder() .workerId(workspaceWorker.getId()) .workerName(workspaceWorker.getUser().getName()) + .colorCode(workspaceWorker.getColorCode()) .build(); } } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/ManagerWorkspaceWorkerListResponseDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/ManagerWorkspaceWorkerListResponseDto.java index bc32c277..290f90c9 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/ManagerWorkspaceWorkerListResponseDto.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/ManagerWorkspaceWorkerListResponseDto.java @@ -34,6 +34,10 @@ public class ManagerWorkspaceWorkerListResponseDto { @Schema(description = "직책") private WorkerPositionResponseDto position; + @NotNull + @Schema(description = "근무자 표시 색상 (hex)", example = "#9CA3AF") + private String colorCode; + @NotNull @Schema(description = "채용일자", example = "2023-10-01T12:00:00") private LocalDate employedAt; @@ -50,6 +54,7 @@ public static ManagerWorkspaceWorkerListResponseDto of(ManagerWorkspaceWorkerLis .user(WorkspaceWorkerResponseDto.of(entity.getUser())) .status(DescribedEnumDto.of(entity.getStatus(), WorkspaceWorkerStatus.describe())) .position(WorkerPositionResponseDto.from(entity.getPosition())) + .colorCode(entity.getColorCode()) .employedAt(entity.getEmployedAt()) .resignedAt(entity.getResignedAt()) .nextShiftDateTime(entity.getNextShiftDateTime()) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/UpdateWorkspaceWorkerColorRequestDto.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/UpdateWorkspaceWorkerColorRequestDto.java new file mode 100644 index 00000000..cff7059c --- /dev/null +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/UpdateWorkspaceWorkerColorRequestDto.java @@ -0,0 +1,20 @@ +package com.dreamteam.alter.adapter.inbound.manager.workspace.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "매니저 - 근무자 색상 변경 요청 DTO") +public class UpdateWorkspaceWorkerColorRequestDto { + + @NotBlank + @Pattern(regexp = "^#[0-9A-Fa-f]{6}$", message = "색상은 #로 시작하는 6자리 16진수여야 합니다.") + @Schema(description = "변경할 색상 (hex)", example = "#93B0A4") + private String colorCode; +} 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 21f9644e..7063653e 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 @@ -173,6 +173,7 @@ public List getWorkspaceWorkerListWithCursor ), qWorkspaceWorker.status, Expressions.constant(WorkerPositionType.WORKER), + qWorkspaceWorker.colorCode, qWorkspaceWorker.employedAt, qWorkspaceWorker.resignedAt, qWorkspaceWorker.createdAt, @@ -205,6 +206,7 @@ public List getWorkspaceWorkerListWithCursor qUser.contact, qUser.gender, qWorkspaceWorker.status, + qWorkspaceWorker.colorCode, qWorkspaceWorker.employedAt, qWorkspaceWorker.resignedAt, qWorkspaceWorker.createdAt diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerQueryRepositoryImpl.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerQueryRepositoryImpl.java index e7fd6cb4..8beff8ae 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerQueryRepositoryImpl.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerQueryRepositoryImpl.java @@ -131,8 +131,30 @@ public List getUserActiveWorkspaceListWithCursor( } + @Override + public boolean existsActivatedByWorkspaceAndColorCode(Long workspaceId, String colorCode, Long excludeWorkerId) { + QWorkspaceWorker qWorkspaceWorker = QWorkspaceWorker.workspaceWorker; + + BooleanExpression excludeCondition = ObjectUtils.isNotEmpty(excludeWorkerId) + ? qWorkspaceWorker.id.ne(excludeWorkerId) + : null; + + Integer result = queryFactory + .selectOne() + .from(qWorkspaceWorker) + .where( + qWorkspaceWorker.workspace.id.eq(workspaceId), + qWorkspaceWorker.colorCode.eq(colorCode), + qWorkspaceWorker.status.eq(WorkspaceWorkerStatus.ACTIVATED), + excludeCondition + ) + .fetchFirst(); + + return result != null; + } + private BooleanExpression cursorConditions( - QWorkspaceWorker qWorkspaceWorker, + QWorkspaceWorker qWorkspaceWorker, CursorDto cursor ) { if (ObjectUtils.isEmpty(cursor)) { diff --git a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/readonly/ManagerWorkspaceWorkerListResponse.java b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/readonly/ManagerWorkspaceWorkerListResponse.java index aa303712..75abfe67 100644 --- a/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/readonly/ManagerWorkspaceWorkerListResponse.java +++ b/src/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/readonly/ManagerWorkspaceWorkerListResponse.java @@ -26,6 +26,8 @@ public class ManagerWorkspaceWorkerListResponse { @Enumerated(EnumType.STRING) private WorkerPositionType position; + private String colorCode; + private LocalDate employedAt; private LocalDate resignedAt; From bf9e97e3600010b38e888708146bb939d0c43f0c Mon Sep 17 00:00:00 2001 From: Seungwan Yoo Date: Sun, 10 May 2026 17:28:43 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EA=B7=BC=EB=AC=B4=EC=9E=90=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?API=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=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 --- .../ManagerWorkspaceController.java | 17 +++++++ .../ManagerWorkspaceControllerSpec.java | 44 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java index 56234cfa..b9cb685d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java @@ -21,6 +21,7 @@ import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.ManagerWorkspaceWorkerListFilterDto; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.ManagerWorkspaceWorkerListResponseDto; import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateFixedScheduleDateRequestDto; +import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; import com.dreamteam.alter.application.aop.ManagerActionContext; import com.dreamteam.alter.domain.user.context.ManagerActor; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceListUseCase; @@ -28,6 +29,7 @@ import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceUseCase; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceWorkerListUseCase; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateFixedScheduleDateUseCase; +import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkspaceWorkerColorCodeUseCase; import jakarta.annotation.Resource; import jakarta.validation.Valid; @@ -55,6 +57,9 @@ public class ManagerWorkspaceController implements ManagerWorkspaceControllerSpe @Resource(name = "managerUpdateFixedScheduleDate") private final ManagerUpdateFixedScheduleDateUseCase managerUpdateFixedScheduleDate; + @Resource(name = "managerUpdateWorkspaceWorkerColorCode") + private final ManagerUpdateWorkspaceWorkerColorCodeUseCase managerUpdateWorkspaceWorkerColor; + @Override @GetMapping public ResponseEntity>> getWorkspaceList() { @@ -106,4 +111,16 @@ public ResponseEntity> updateFixedScheduleDate( managerUpdateFixedScheduleDate.execute(actor, workspaceId, request); return ResponseEntity.ok(CommonApiResponse.empty()); } + + @Override + @PatchMapping("/{workspaceId}/workers/{workerId}/color") + public ResponseEntity> updateWorkspaceWorkerColorCode( + @PathVariable Long workspaceId, + @PathVariable Long workerId, + @RequestBody @Valid UpdateWorkspaceWorkerColorRequestDto request + ) { + ManagerActor actor = ManagerActionContext.getInstance().getActor(); + managerUpdateWorkspaceWorkerColor.execute(actor, workspaceId, workerId, request); + return ResponseEntity.ok(CommonApiResponse.empty()); + } } diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java index 8aa504c4..61b7f21d 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java @@ -86,6 +86,50 @@ ResponseEntity> updateFixedScheduleDate( @RequestBody @Valid UpdateFixedScheduleDateRequestDto request ); + @Operation(summary = "매니저 - 근무자 색상 변경", description = "근무자 캘린더에서 사용할 표시 색상을 변경합니다. 같은 업장의 ACTIVATED 근무자끼리 색상은 unique 합니다 (기본 색상 #9CA3AF 제외).") + @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\" : \"B001\"}" + ), + })), + @ApiResponse(responseCode = "404", description = "존재하지 않는 업장 또는 근무자", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "존재하지 않는 업장입니다.", + value = "{\"code\" : \"B008\"}" + ), + @ExampleObject( + name = "근무자를 찾을 수 없습니다.", + value = "{\"code\" : \"B019\"}" + ), + })), + @ApiResponse(responseCode = "409", description = "이미 사용 중인 색상", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "이미 사용 중인 근무자 색상입니다.", + value = "{\"code\" : \"B026\"}" + ), + })), + }) + ResponseEntity> updateWorkspaceWorkerColorCode( + @PathVariable Long workspaceId, + @PathVariable Long workerId, + @RequestBody @Valid UpdateWorkspaceWorkerColorRequestDto request + ); + // 업장 근무자 상세 정보 조회 // 업장 근무자 상태 변경 From 6093aaf6ae0684525e3eed22cadf379a0c602f66 Mon Sep 17 00:00:00 2001 From: Seungwan Yoo Date: Sun, 10 May 2026 17:58:54 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20Command=20=ED=8C=A8=ED=84=B4?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20UseCase=20=EC=95=84=ED=82=A4=ED=85=8D?= =?UTF-8?q?=EC=B2=98=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UpdateWorkspaceWorkerColorCommand 도메인 Command 클래스 신규 생성 - 인바운드 포트(ManagerUpdateWorkspaceWorkerColorCodeUseCase)에서 어댑터 DTO 의존 제거 - UseCase 구현체에서 Command 사용으로 변경 - 컨트롤러에서 DTO → Command 변환 후 호출 (어댑터 검증 책임 유지) 헥사고날 아키텍처 경계 준수 (CodeRabbit 리뷰 #2, #5 반영) --- .../ManagerWorkspaceController.java | 8 +++++++- ...ManagerUpdateWorkspaceWorkerColorCode.java | 10 +++++----- .../UpdateWorkspaceWorkerColorCommand.java | 20 +++++++++++++++++++ ...UpdateWorkspaceWorkerColorCodeUseCase.java | 4 ++-- 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.java diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java index b9cb685d..d9aa69ea 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.java @@ -24,6 +24,7 @@ import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; import com.dreamteam.alter.application.aop.ManagerActionContext; import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.command.UpdateWorkspaceWorkerColorCommand; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceListUseCase; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceManagerListUseCase; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerGetWorkspaceUseCase; @@ -120,7 +121,12 @@ public ResponseEntity> updateWorkspaceWorkerColorCode( @RequestBody @Valid UpdateWorkspaceWorkerColorRequestDto request ) { ManagerActor actor = ManagerActionContext.getInstance().getActor(); - managerUpdateWorkspaceWorkerColor.execute(actor, workspaceId, workerId, request); + managerUpdateWorkspaceWorkerColor.execute( + actor, + workspaceId, + workerId, + UpdateWorkspaceWorkerColorCommand.of(request.getColorCode()) + ); return ResponseEntity.ok(CommonApiResponse.empty()); } } diff --git a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java index 1b727869..0c1fa4dd 100644 --- a/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java +++ b/src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java @@ -1,9 +1,9 @@ package com.dreamteam.alter.application.workspace.usecase; -import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; 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.command.UpdateWorkspaceWorkerColorCommand; import com.dreamteam.alter.domain.workspace.entity.WorkspaceWorker; import com.dreamteam.alter.domain.workspace.port.inbound.ManagerUpdateWorkspaceWorkerColorCodeUseCase; import com.dreamteam.alter.domain.workspace.port.outbound.WorkspaceQueryRepository; @@ -25,7 +25,7 @@ public void execute( ManagerActor actor, Long workspaceId, Long workerId, - UpdateWorkspaceWorkerColorRequestDto request + UpdateWorkspaceWorkerColorCommand command ) { if (!workspaceQueryRepository.existsByIdAndManagerUser(workspaceId, actor.getManagerUser())) { throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); @@ -38,15 +38,15 @@ public void execute( throw new CustomException(ErrorCode.WORKSPACE_NOT_FOUND); } - if (!WorkspaceWorker.DEFAULT_COLOR_CODE.equals(request.getColorCode()) + if (!WorkspaceWorker.DEFAULT_COLOR_CODE.equals(command.getColorCode()) && workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode( workspaceId, - request.getColorCode(), + command.getColorCode(), workerId )) { throw new CustomException(ErrorCode.CONFLICT, "이미 사용 중인 근무자 색상입니다."); } - worker.updateColorCode(request.getColorCode()); + worker.updateColorCode(command.getColorCode()); } } diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.java b/src/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.java new file mode 100644 index 00000000..63817416 --- /dev/null +++ b/src/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.java @@ -0,0 +1,20 @@ +package com.dreamteam.alter.domain.workspace.command; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class UpdateWorkspaceWorkerColorCommand { + + private String colorCode; + + public static UpdateWorkspaceWorkerColorCommand of(String colorCode) { + return UpdateWorkspaceWorkerColorCommand.builder() + .colorCode(colorCode) + .build(); + } +} diff --git a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java index 97973a83..07c65fc1 100644 --- a/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java +++ b/src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java @@ -1,8 +1,8 @@ package com.dreamteam.alter.domain.workspace.port.inbound; -import com.dreamteam.alter.adapter.inbound.manager.workspace.dto.UpdateWorkspaceWorkerColorRequestDto; import com.dreamteam.alter.domain.user.context.ManagerActor; +import com.dreamteam.alter.domain.workspace.command.UpdateWorkspaceWorkerColorCommand; public interface ManagerUpdateWorkspaceWorkerColorCodeUseCase { - void execute(ManagerActor actor, Long workspaceId, Long workerId, UpdateWorkspaceWorkerColorRequestDto request); + void execute(ManagerActor actor, Long workspaceId, Long workerId, UpdateWorkspaceWorkerColorCommand command); } From a0024da63755cc97311723d36fa3c31ab682fbea Mon Sep 17 00:00:00 2001 From: Seungwan Yoo Date: Sun, 10 May 2026 17:59:04 +0900 Subject: [PATCH 5/5] =?UTF-8?q?docs:=20ControllerSpec=20ErrorCode=20?= =?UTF-8?q?=EC=98=88=EC=8B=9C=20=EC=A0=95=ED=95=A9=EC=84=B1=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 - 409 응답의 불명시 ErrorCode B026 → B020(CONFLICT)으로 수정 - 실제 UseCase가 throw하는 ErrorCode.CONFLICT와 일치하도록 정정 - 404 응답 예시(B008 업장, B019 근무자)는 정의된 코드로 유지 Swagger 문서 정합성 개선 (CodeRabbit 리뷰 #1 + 추가 발견 반영) --- .../workspace/controller/ManagerWorkspaceControllerSpec.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java index 61b7f21d..eee42223 100644 --- a/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java +++ b/src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java @@ -120,7 +120,7 @@ ResponseEntity> updateFixedScheduleDate( examples = { @ExampleObject( name = "이미 사용 중인 근무자 색상입니다.", - value = "{\"code\" : \"B026\"}" + value = "{\"code\" : \"B020\"}" ), })), })