-
Notifications
You must be signed in to change notification settings - Fork 0
fix: [alt-276] 사장님(MANAGER) 구인구직 API 결함 수정 #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e151141
e1bf564
3cc06bd
71d33df
4b20c0d
62cd4f0
7903d67
a05bf5e
7104cd6
ede2c0c
ad0d656
ca6fa40
e5c6cbd
f28c8db
51416ac
5d011b7
59a1bb0
6537d58
ee15e43
294451b
a370007
5020087
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,10 @@ public interface ManagerPostingControllerSpec { | |
| mediaType = "application/json", | ||
| schema = @Schema(implementation = ErrorResponse.class), | ||
| examples = { | ||
| @ExampleObject( | ||
| name = "존재하지 않거나, 자신이 관리하지 않거나, 활성화되지 않은 업장", | ||
| value = "{\"code\" : \"B008\"}" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [사소] 이 400 블록에 C001 이 섞여 있습니다 (기존 문제) B008 을 400 블록에 넣으신 건 정확합니다. 다만 바로 아래 "서버 내부 오류 C001" 예시가 같은 400 블록에 들어 있는데, C001 은 500 입니다. 이 PR 이 만든 문제는 아니지만 바로 옆 줄을 건드리신 김에 500 블록으로 옮기시면 어떨까요. |
||
| ), | ||
| @ExampleObject( | ||
| name = "서버 내부 오류", | ||
| value = "{\"code\" : \"C001\"}" | ||
|
|
@@ -155,7 +159,10 @@ ResponseEntity<CommonApiResponse<Void>> updatePostingStatus( | |
| @Valid @RequestBody UpdatePostingStatusRequestDto request | ||
| ); | ||
|
|
||
| @Operation(summary = "매니저 - 내가 등록한 공고 내용 수정", description = "") | ||
| @Operation( | ||
| summary = "매니저 - 내가 등록한 공고 내용 수정", | ||
| description = "수정을 마친 뒤 남은 근무일정이 하나도 없으면 공고가 모집 완료(CLOSED)로 바뀌며 더 이상 지원을 받지 않습니다." | ||
| ) | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "공고 내용 수정 성공"), | ||
| @ApiResponse(responseCode = "400", description = "실패 케이스", | ||
|
|
@@ -167,14 +174,6 @@ ResponseEntity<CommonApiResponse<Void>> updatePostingStatus( | |
| name = "존재하지 않는 공고", | ||
| value = "{\"code\" : \"B007\"}" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [하] 이번에 추가된 409 케이스가 스펙에 빠졌습니다. 공고 등록 쪽에는 |
||
| ), | ||
| @ExampleObject( | ||
| name = "등록되지 않은 키워드로 요청", | ||
| value = "{\"code\" : \"B006\"}" | ||
| ), | ||
| @ExampleObject( | ||
| name = "요청에 키워드가 포함되지 않은 경우", | ||
| value = "{\"code\" : \"B001\"}" | ||
| ), | ||
| })), | ||
| @ApiResponse(responseCode = "404", description = "404 Error 실패 케이스", | ||
| content = @Content( | ||
|
|
@@ -190,6 +189,16 @@ ResponseEntity<CommonApiResponse<Void>> updatePostingStatus( | |
| value = "{\"code\" : \"B019\"}" | ||
| ), | ||
| })), | ||
| @ApiResponse(responseCode = "409", description = "409 Error 실패 케이스", | ||
| content = @Content( | ||
| mediaType = "application/json", | ||
| schema = @Schema(implementation = ErrorResponse.class), | ||
| examples = { | ||
| @ExampleObject( | ||
| name = "DELETED 상태의 공고는 내용 수정 불가", | ||
| value = "{\"code\" : \"B020\"}" | ||
| ), | ||
| })), | ||
| }) | ||
| ResponseEntity<CommonApiResponse<Void>> updatePosting( | ||
| @PathVariable Long postingId, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,12 @@ | ||
| package com.dreamteam.alter.adapter.inbound.manager.posting.dto; | ||
|
|
||
| import java.util.List; | ||
| import java.util.function.Function; | ||
|
|
||
| import org.apache.commons.lang3.ObjectUtils; | ||
|
|
||
| import com.dreamteam.alter.adapter.inbound.general.posting.dto.CreatePostingScheduleRequestDto; | ||
| import com.dreamteam.alter.domain.posting.command.UpdatePostingCommand; | ||
| import com.dreamteam.alter.domain.posting.type.PaymentType; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
@@ -27,6 +31,7 @@ public class UpdatePostingRequestDto { | |
| @Schema(description = "공고 제목", example = "홀서빙 구합니다") | ||
| private String title; | ||
|
|
||
| @NotBlank | ||
| @Schema(description = "공고 설명", example = "홀서빙 구합니다. 주말 근무 가능하신 분 우대합니다.") | ||
| private String description; | ||
|
|
||
|
|
@@ -48,4 +53,20 @@ public class UpdatePostingRequestDto { | |
|
|
||
| @Schema(description = "삭제할 스케줄 ID", example = "[2, 3]") | ||
| private List<Long> deleteScheduleIds; | ||
|
|
||
| public UpdatePostingCommand toCommand() { | ||
| return new UpdatePostingCommand( | ||
| title, | ||
| description, | ||
| payAmount, | ||
| paymentType, | ||
| toCommands(createSchedules, CreatePostingScheduleRequestDto::toCommand), | ||
| toCommands(updateSchedules, UpdatePostingScheduleDto::toCommand), | ||
| ObjectUtils.isEmpty(deleteScheduleIds) ? List.of() : deleteScheduleIds | ||
| ); | ||
| } | ||
|
|
||
| private static <T, R> List<R> toCommands(List<T> source, Function<T, R> mapper) { | ||
|
Comment on lines
+63
to
+69
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [낮음]
ObjectUtils.isEmpty(deleteScheduleIds) ? List.of() : deleteScheduleIds한 줄이면 셋 다 동일해집니다. |
||
| return ObjectUtils.isEmpty(source) ? List.of() : source.stream().map(mapper).toList(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,15 @@ | ||
| package com.dreamteam.alter.adapter.inbound.manager.posting.dto; | ||
|
|
||
| import com.dreamteam.alter.domain.posting.command.UpdatePostingScheduleCommand; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.NotEmpty; | ||
| import jakarta.validation.constraints.NotNull; | ||
| import jakarta.validation.constraints.Positive; | ||
| import lombok.*; | ||
|
|
||
| import java.time.DayOfWeek; | ||
| import java.time.LocalTime; | ||
| import java.util.List; | ||
|
|
||
| @Getter | ||
|
|
@@ -18,23 +23,27 @@ public class UpdatePostingScheduleDto { | |
| @Schema(description = "스케줄 ID", example = "1") | ||
| private Long id; | ||
|
|
||
| @NotNull | ||
| @NotEmpty | ||
| @Schema(description = "근무일", example = "[\"MONDAY\", \"WEDNESDAY\"]") | ||
| private List<String> workingDays; | ||
| private List<DayOfWeek> workingDays; | ||
|
|
||
| @NotNull | ||
| @Schema(description = "시작 시간", example = "09:00") | ||
| private String startTime; | ||
| private LocalTime startTime; | ||
|
Comment on lines
+26
to
+32
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타입 정리 좋습니다 — 응답 코드 변화만 확인 부탁드립니다
와이어 포맷( 다만 잘못된 값이 올 때 응답이 달라집니다. 기존에는 도메인까지 들어와 참고로 |
||
|
|
||
| @NotNull | ||
| @Schema(description = "종료 시간", example = "18:00") | ||
| private String endTime; | ||
| private LocalTime endTime; | ||
|
|
||
| @NotNull | ||
| @Positive | ||
| @Schema(description = "필요 인원", example = "3") | ||
| private int positionsNeeded; | ||
|
|
||
| @NotBlank | ||
| @Schema(description = "포지션", example = "홀서빙") | ||
| private String position; | ||
|
|
||
| public UpdatePostingScheduleCommand toCommand() { | ||
| return new UpdatePostingScheduleCommand(id, workingDays, startTime, endTime, positionsNeeded, position); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,7 @@ public long getCountOfPostings(PostingListFilterDto filter) { | |
| .select(qPosting.countDistinct()) | ||
| .from(qPosting) | ||
| .leftJoin(qPosting.schedules, qPostingSchedule) | ||
| .on(qPostingSchedule.status.ne(PostingStatus.DELETED)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [중간] 활성 근무일정이 0개인 공고가 목록에 남습니다
다만 gteStartTime(qPostingSchedule, filter.getStartTime()),
lteEndTime(qPostingSchedule, filter.getEndTime())필터가 "삭제된 근무일정을 공고 응답에서 제외" 라는 이 PR 의 목적을 생각하면 이런 공고는 목록에서 빠지는 게 자연스러워 보입니다. 의도적으로 남기신 거라면 그대로 두셔도 됩니다. 다만 98번 라인의 |
||
| .leftJoin(qPosting.workspace, qWorkspace) | ||
| .where( | ||
| qPosting.status.eq(PostingStatus.OPEN), | ||
|
|
@@ -103,6 +104,7 @@ public List<PostingListResponse> getPostingsWithCursor(CursorPageRequest<CursorD | |
| .select(qPosting.id) | ||
| .from(qPosting) | ||
| .leftJoin(qPosting.schedules, qPostingSchedule) | ||
| .on(qPostingSchedule.status.ne(PostingStatus.DELETED)) | ||
| .leftJoin(qPosting.workspace, qWorkspace) | ||
| .where( | ||
| qPosting.status.eq(PostingStatus.OPEN), | ||
|
|
@@ -603,7 +605,8 @@ public Optional<ManagerPostingDetailResponse> getManagerPostingDetail(Long posti | |
| .leftJoin(qWorkspace.businessType, QBusinessType.businessType).fetchJoin() | ||
| .where( | ||
| qPosting.id.eq(postingId), | ||
| qWorkspace.managerUser.eq(managerUser) | ||
| qWorkspace.managerUser.eq(managerUser), | ||
| qPosting.status.ne(PostingStatus.DELETED) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [사소] 매니저 목록 2차 쿼리와 필터링 방식이 다릅니다 상세 조회에 DELETED 제외를 넣으신 건 맞습니다. 다만 전체적으로 보면 삭제 필터링이 세 가지 방식으로 섞여 있습니다.
최종 응답은 어느 경로든 |
||
| ) | ||
| .fetchOne(); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[중간] 실질적으로 파괴적인 검증 변경 — 릴리스 노트에 남겨주세요
이 PR 에서
javax.validation.constraints.NotNullimport 를jakarta.validation.constraints.NotNull로 교체하셨는데, 이게 생각보다 영향이 큽니다.Jakarta EE 9+ 검증기는
javax.validation어노테이션을 인식하지 않습니다. 즉 지금까지workspaceId와paymentType의@NotNull은 아무 일도 하지 않았고,workspaceId: null로 요청하면 그대로 통과해 NPE 나 엉뚱한 조회로 이어졌을 겁니다. 좋은 수정입니다.다만 결과적으로 아래 세 가지가 동시에 클라이언트에 400 을 새로 발생시킵니다.
workspaceId누락 (기존엔 통과)paymentType누락 (기존엔 통과)schedules빈 배열 · 누락 (@NotEmpty신규)PR 설명의 "필수값 검증 보강" 만으로는 앱 팀이 영향 범위를 알기 어렵습니다. 어떤 필드가 새로 400 을 내는지 목록으로 적어두시면 좋겠습니다.