feat: [alt-216] 근무자 색상 코드 변경 기능 추가#85
Conversation
📝 WalkthroughWalkthrough관리자가 워크스페이스 근무자의 표시 색상 코드를 설정·수정하는 기능을 도메인 필드·커맨드·유스케이스, 저장소 쿼리·프로젝션, 요청/응답 DTO, 컨트롤러 엔드포인트까지 추가·연결했습니다. 변경 사항근무자 색상 코드 업데이트
Estimated code review effort 🎯 3 (보통) | ⏱️ ~25분 제안 레이블
제안 리뷰어
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java (1)
14-43:⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift도메인 엔티티에 인프라 의존성이 존재합니다.
도메인 레이어 가이드라인에 따르면 "ZERO infrastructure dependencies (no Spring, no JPA annotations, no external libs)"를 준수해야 하지만, 이 엔티티는 JPA 어노테이션(
@Entity,@Column,@JoinColumn등)과 Spring Data 어노테이션(@CreatedDate,@LastModifiedDate, AuditingEntityListener)을 사용하고 있습니다.헥사고날 아키텍처를 엄격하게 적용하려면 순수 도메인 모델과 별도의 영속성 매핑을 분리해야 합니다.
As per coding guidelines: "도메인 레이어는 ZERO infrastructure dependencies (no Spring, no JPA annotations, no external libs)를 준수해야 합니다."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java` around lines 14 - 43, The WorkspaceWorker domain class contains infrastructure concerns (JPA/Spring annotations like `@Entity`, `@Table`, `@Id`, `@GeneratedValue`, `@ManyToOne`, `@JoinColumn`, `@Enumerated`, `@Column`, `@EntityListeners`(AuditingEntityListener.class)) which violates the zero-infrastructure rule; refactor by stripping all persistence and Spring annotations from the domain WorkspaceWorker (and keep constants like DEFAULT_COLOR_CODE and domain fields such as id, workspace, user, status, colorCode) and move the annotated mapping into a new infrastructure-side class (e.g., WorkspaceWorkerEntity) that contains the JPA annotations and mapping to Workspace and User entities; implement conversion methods or a mapper in the repository layer to translate between WorkspaceWorker and WorkspaceWorkerEntity and remove any auditing annotations from the pure domain model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java`:
- Around line 102-114: The 404 ApiResponse example in
ManagerWorkspaceControllerSpec (the ApiResponse block for "존재하지 않는 업장 또는 근무자")
uses an inconsistent error code ("B008"); update the ExampleObject value for the
"존재하지 않는 업장입니다." example to use the correct error code "B019" so it matches the
existing spec/ErrorCode mapping in this class.
In
`@src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java`:
- Line 3: The class ManagerUpdateWorkspaceWorkerColorCode is importing and
depending on the adapter DTO UpdateWorkspaceWorkerColorRequestDto, breaking the
application-layer boundary; replace that direct reference with a
use-case-specific request/command model (e.g., create a
UpdateWorkspaceWorkerColorCommand in the application or domain/application
package) and update the handler method(s) in
ManagerUpdateWorkspaceWorkerColorCode to accept that command instead of
UpdateWorkspaceWorkerColorRequestDto; map incoming adapter DTOs to the new
command at the adapter/inbound layer (controller/mapper) so the application
package has no direct dependency on adapter classes.
- Around line 41-50: There is a race between the
existsActivatedByWorkspaceAndColorCode check and worker.updateColorCode which
can allow duplicate color codes under concurrency; fix by enforcing uniqueness
at the DB and handling constraint violations or by using a DB lock: add a
DB-level unique constraint/partial index on (workspace_id, color_code) for
activated workers (and exclude DEFAULT_COLOR_CODE as needed), and in
ManagerUpdateWorkspaceWorkerColorCode wrap the update in a transaction and catch
the resulting DataIntegrityViolationException (or the JPA/Persistence exception)
when saving/updating the worker to translate it into
CustomException(ErrorCode.CONFLICT, ...); alternatively, obtain a row lock first
via repository method (e.g., lockByIdForUpdate or findByIdForUpdate) before
calling workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode
and worker.updateColorCode to prevent concurrent inserts.
In
`@src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java`:
- Around line 76-78: The updateColorCode method on WorkspaceWorker must enforce
domain invariants: add null check, ensure the value matches hex color regex
^#[0-9A-Fa-f]{6}$ and enforce expected length (7 characters including '#'); if
validation fails throw a clear runtime/domain exception (e.g.,
IllegalArgumentException or a custom WorkspaceDomainException). Update
WorkspaceWorker.updateColorCode to perform these checks before assigning
this.colorCode so invalid values never get set.
In
`@src/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java`:
- Around line 1-8: The inbound port ManagerUpdateWorkspaceWorkerColorCodeUseCase
currently depends on the adapter DTO UpdateWorkspaceWorkerColorRequestDto;
change the port to accept a domain-safe type instead (either a primitive like
String colorCode or a domain command record such as
UpdateWorkerColorCodeCommand) so the domain layer does not depend on adapter
types; create the new command record inside the domain
workspace.port.inbound.command package (e.g., UpdateWorkerColorCodeCommand with
a String colorCode and optional validation) and update the execute signature on
ManagerUpdateWorkspaceWorkerColorCodeUseCase to accept that command (keeping
ManagerActor, workspaceId, workerId unchanged), then update the adapter layer to
map UpdateWorkspaceWorkerColorRequestDto to the new command before calling the
port.
---
Outside diff comments:
In
`@src/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.java`:
- Around line 14-43: The WorkspaceWorker domain class contains infrastructure
concerns (JPA/Spring annotations like `@Entity`, `@Table`, `@Id`, `@GeneratedValue`,
`@ManyToOne`, `@JoinColumn`, `@Enumerated`, `@Column`,
`@EntityListeners`(AuditingEntityListener.class)) which violates the
zero-infrastructure rule; refactor by stripping all persistence and Spring
annotations from the domain WorkspaceWorker (and keep constants like
DEFAULT_COLOR_CODE and domain fields such as id, workspace, user, status,
colorCode) and move the annotated mapping into a new infrastructure-side class
(e.g., WorkspaceWorkerEntity) that contains the JPA annotations and mapping to
Workspace and User entities; implement conversion methods or a mapper in the
repository layer to translate between WorkspaceWorker and WorkspaceWorkerEntity
and remove any auditing annotations from the pure domain model.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ff9eff96-cd06-42f5-916e-4b49a60328b0
📒 Files selected for processing (12)
src/main/java/com/dreamteam/alter/adapter/inbound/common/dto/WorkerSummaryDto.javasrc/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.javasrc/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.javasrc/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/ManagerWorkspaceWorkerListResponseDto.javasrc/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/dto/UpdateWorkspaceWorkerColorRequestDto.javasrc/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceQueryRepositoryImpl.javasrc/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/WorkspaceWorkerQueryRepositoryImpl.javasrc/main/java/com/dreamteam/alter/adapter/outbound/workspace/persistence/readonly/ManagerWorkspaceWorkerListResponse.javasrc/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.javasrc/main/java/com/dreamteam/alter/domain/workspace/entity/WorkspaceWorker.javasrc/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.javasrc/main/java/com/dreamteam/alter/domain/workspace/port/outbound/WorkspaceWorkerQueryRepository.java
- 409 응답의 불명시 ErrorCode B026 → B020(CONFLICT)으로 수정 - 실제 UseCase가 throw하는 ErrorCode.CONFLICT와 일치하도록 정정 - 404 응답 예시(B008 업장, B019 근무자)는 정의된 코드로 유지 Swagger 문서 정합성 개선 (CodeRabbit 리뷰 #1 + 추가 발견 반영)
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java (1)
41-50:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift색상 중복 검사와 갱신 사이에 TOCTOU 레이스가 남아 있습니다.
Line 41~50은 동시 요청에서 둘 다
exists... == false를 통과한 뒤 동일 색상으로 갱신될 수 있습니다. DB 유니크 제약(조건부 포함) 또는 락 기반으로 무결성을 강제하고, 제약 위반을ErrorCode.CONFLICT로 변환해 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java` around lines 41 - 50, The current check using workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode(...) before worker.updateColorCode(...) has a TOCTOU race; enforce uniqueness at the DB level (add a conditional unique constraint/index on (workspace_id, color_code, activated) or use a row lock via SELECT ... FOR UPDATE around the worker update) and handle any resulting constraint/lock violation by catching the DB exception (e.g., DataIntegrityViolationException / SQLException) in the use case (ManagerUpdateWorkspaceWorkerColorCode) and rethrowing as new CustomException(ErrorCode.CONFLICT, "이미 사용 중인 근무자 색상입니다."); keep the pre-check if desired but rely on the DB constraint/lock as the source of truth and reference the methods workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode and worker.updateColorCode when making the change.src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java (1)
107-114:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win404 에러 예시 코드가 서로 뒤바뀐 것으로 보입니다.
Line 109~113에서
"존재하지 않는 업장입니다."와"근무자를 찾을 수 없습니다."의 코드 매핑이 파일 내 다른 스펙과 불일치합니다. 예시 코드를 실제 ErrorCode 매핑과 동일하게 맞춰 주세요.📝 제안 수정안
`@ExampleObject`( name = "존재하지 않는 업장입니다.", - value = "{\"code\" : \"B008\"}" + value = "{\"code\" : \"B019\"}" ), `@ExampleObject`( name = "근무자를 찾을 수 없습니다.", - value = "{\"code\" : \"B019\"}" + value = "{\"code\" : \"B008\"}" ),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java` around lines 107 - 114, In ManagerWorkspaceControllerSpec swap the JSON values of the two `@ExampleObject` annotations so the name "존재하지 않는 업장입니다." maps to the correct error code and "근무자를 찾을 수 없습니다." maps to its correct code (i.e., correct the reversed mappings between the two ExampleObject entries currently using codes "B008" and "B019"); update the two `@ExampleObject` value strings to match the actual ErrorCode enum mapping used elsewhere in the specs to keep them consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.java`:
- Around line 3-11: The UpdateWorkspaceWorkerColorCommand class currently uses
Lombok annotations (`@Getter`, `@Builder`, `@AllArgsConstructor`, AccessLevel.PRIVATE)
which introduces an external-library dependency into the domain layer; replace
Lombok with plain Java by removing those annotations and implementing explicit
private final fields, a private all-args constructor, public getters for each
field, and a builder or static factory implemented manually inside
UpdateWorkspaceWorkerColorCommand (or a nested static Builder class) to preserve
the creation API while keeping the domain layer free of external dependencies.
---
Duplicate comments:
In
`@src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.java`:
- Around line 107-114: In ManagerWorkspaceControllerSpec swap the JSON values of
the two `@ExampleObject` annotations so the name "존재하지 않는 업장입니다." maps to the
correct error code and "근무자를 찾을 수 없습니다." maps to its correct code (i.e., correct
the reversed mappings between the two ExampleObject entries currently using
codes "B008" and "B019"); update the two `@ExampleObject` value strings to match
the actual ErrorCode enum mapping used elsewhere in the specs to keep them
consistent.
In
`@src/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.java`:
- Around line 41-50: The current check using
workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode(...)
before worker.updateColorCode(...) has a TOCTOU race; enforce uniqueness at the
DB level (add a conditional unique constraint/index on (workspace_id,
color_code, activated) or use a row lock via SELECT ... FOR UPDATE around the
worker update) and handle any resulting constraint/lock violation by catching
the DB exception (e.g., DataIntegrityViolationException / SQLException) in the
use case (ManagerUpdateWorkspaceWorkerColorCode) and rethrowing as new
CustomException(ErrorCode.CONFLICT, "이미 사용 중인 근무자 색상입니다."); keep the pre-check
if desired but rely on the DB constraint/lock as the source of truth and
reference the methods
workspaceWorkerQueryRepository.existsActivatedByWorkspaceAndColorCode and
worker.updateColorCode when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 96368448-537e-4fe0-8d18-2014a8a256a8
📒 Files selected for processing (5)
src/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceController.javasrc/main/java/com/dreamteam/alter/adapter/inbound/manager/workspace/controller/ManagerWorkspaceControllerSpec.javasrc/main/java/com/dreamteam/alter/application/workspace/usecase/ManagerUpdateWorkspaceWorkerColorCode.javasrc/main/java/com/dreamteam/alter/domain/workspace/command/UpdateWorkspaceWorkerColorCommand.javasrc/main/java/com/dreamteam/alter/domain/workspace/port/inbound/ManagerUpdateWorkspaceWorkerColorCodeUseCase.java
변경사항
Summary by CodeRabbit