diff --git a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiLogFunction.java b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiLogFunction.java index 43a78ac7..446c7317 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiLogFunction.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiLogFunction.java @@ -129,4 +129,12 @@ public class ApiLogFunction { return m != null ? m.getMenuUid() : "SYSTEM"; } + + public static String cutRequestBody(String value) { + int MAX_LEN = 255; + if (value == null) { + return null; + } + return value.length() <= MAX_LEN ? value : value.substring(0, MAX_LEN); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseAdvice.java b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseAdvice.java index 034eccf3..72cb50bc 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseAdvice.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/api/ApiResponseAdvice.java @@ -9,6 +9,7 @@ import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository; import jakarta.servlet.http.HttpServletRequest; import java.util.LinkedHashMap; import java.util.List; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; @@ -26,6 +27,7 @@ import org.springframework.web.util.ContentCachingRequestWrapper; * *

createOK() → 201 CREATED ok() → 200 OK deleteOk() → 204 NO_CONTENT */ +@Slf4j @RestControllerAdvice public class ApiResponseAdvice implements ResponseBodyAdvice { @@ -110,7 +112,7 @@ public class ApiResponseAdvice implements ResponseBodyAdvice { ApiLogFunction.getUriMenuInfo(result, servletRequest.getRequestURI()), ip, servletRequest.getRequestURI(), - requestBody, + ApiLogFunction.cutRequestBody(requestBody), apiResponse.getErrorLogUid()); auditLogRepository.save(log); } diff --git a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java index b4fdf79b..fe1ed563 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/LabelAllocateApiController.java @@ -10,11 +10,11 @@ import com.kamco.cd.kamcoback.label.service.LabelAllocateService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; 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; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -109,63 +109,24 @@ public class LabelAllocateApiController { content = @Content( mediaType = "application/json", - schema = @Schema(implementation = Long.class), - examples = { - @ExampleObject( - name = "라벨러 할당 예시", - description = "라벨러 할당 예시", - value = - """ - { - "autoType": "AUTO", - "stage": 4, - "labelers": [ - { - "userId": "123456", - "demand": 1000 - }, - { - "userId": "010222297501", - "demand": 400 - }, - { - "userId": "01022223333", - "demand": 440 - } - ], - "inspectors": [ - { - "inspectorUid": "K20251216001", - "userCount": 1000 - }, - { - "inspectorUid": "01022225555", - "userCount": 340 - }, - { - "inspectorUid": "K20251212001", - "userCount": 500 - } - - ] - } - """) - })), + schema = @Schema(implementation = Long.class))), @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @PostMapping("/allocate") - public ApiResponseDto labelAllocate(@RequestBody LabelAllocateDto.AllocateDto dto) { - labelAllocateService.allocateAsc( - dto.getAutoType(), - dto.getStage(), - dto.getLabelers(), - dto.getInspectors(), - dto.getCompareYyyy(), - dto.getTargetYyyy()); + public ApiResponseDto labelAllocate( + @RequestBody @Valid LabelAllocateDto.AllocateDto dto) { - return ApiResponseDto.ok(null); + return ApiResponseDto.okObject( + labelAllocateService.allocateAsc( + dto.getLabelerAutoType(), + dto.getInspectorAutoType(), + dto.getStage(), + dto.getLabelers(), + dto.getInspectors(), + dto.getCompareYyyy(), + dto.getTargetYyyy())); } @Operation(summary = "추론 상세 조회", description = "분석 ID에 해당하는 추론 상세 정보를 조회합니다.") @@ -208,35 +169,13 @@ public class LabelAllocateApiController { content = @Content( mediaType = "application/json", - schema = @Schema(implementation = Long.class), - examples = { - @ExampleObject( - name = "라벨러 할당 예시", - description = "라벨러 할당 예시", - value = - """ - { - "autoType": "AUTO", - "stage": 4, - "labelers": [ - { - "userId": "123456", - "demand": 10 - }, - { - "userId": "010222297501", - "demand": 5 - } - ] - } - """) - })), + schema = @Schema(implementation = Long.class))), @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content), @ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) @PostMapping("/allocate-move") - public ApiResponseDto labelAllocateMove( + public ApiResponseDto labelAllocateMove( @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "라벨링 이관", required = true, @@ -247,13 +186,12 @@ public class LabelAllocateApiController { @RequestBody LabelAllocateDto.AllocateMoveDto dto) { - labelAllocateService.allocateMove( - dto.getAutoType(), - dto.getStage(), - dto.getLabelers(), - dto.getCompareYyyy(), - dto.getTargetYyyy()); - - return ApiResponseDto.ok(null); + return ApiResponseDto.okObject( + labelAllocateService.allocateMove( + dto.getAutoType(), + dto.getStage(), + dto.getLabelers(), + dto.getCompareYyyy(), + dto.getTargetYyyy())); } } diff --git a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java index 5fe14bbb..eb7f2f9a 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/dto/LabelAllocateDto.java @@ -87,8 +87,8 @@ public class LabelAllocateDto { @AllArgsConstructor public static class AllocateDto { - @Schema(description = "분석 ID", example = "3") - private Long analUid; + // @Schema(description = "분석 ID", example = "3") + // private Long analUid; @Schema(description = "비교년도", example = "2022", required = true) private Integer compareYyyy; @@ -96,16 +96,55 @@ public class LabelAllocateDto { @Schema(description = "기준년도", example = "2024", required = true) private Integer targetYyyy; - @Schema(description = "자동/수동여부(AUTO/MANUAL)", example = "AUTO") - private String autoType; + @Schema(description = "라벨러 자동/수동여부(AUTO/MANUAL)", example = "AUTO") + private String labelerAutoType; + + @Schema(description = "검수자 자동/수동여부(AUTO/MANUAL)", example = "AUTO") + private String inspectorAutoType; @Schema(description = "회차", example = "4") private Integer stage; - @Schema(description = "라벨러 할당 목록") + @Schema( + description = "라벨러 할당 목록", + example = + """ + [ + { + "userId": "123456", + "demand": 1000 + }, + { + "userId": "010222297501", + "demand": 400 + }, + { + "userId": "01022223333", + "demand": 440 + } + ] + """) private List labelers; - @Schema(description = "검수자 할당 목록") + @Schema( + description = "검수자 할당 목록", + example = + """ + [ + { + "inspectorUid": "K20251216001", + "userCount": 1000 + }, + { + "inspectorUid": "01022225555", + "userCount": 340 + }, + { + "inspectorUid": "K20251212001", + "userCount": 500 + } + ] + """) private List inspectors; } @@ -201,7 +240,21 @@ public class LabelAllocateDto { @Schema(description = "회차", example = "4") private Integer stage; - @Schema(description = "라벨러 할당 목록") + @Schema( + description = "라벨러 할당 목록", + example = + """ + [ + { + "userId": "123456", + "demand": 10 + }, + { + "userId": "010222297501", + "demand": 5 + } + ] + """) private List labelers; @Schema(description = "비교년도", example = "2022") diff --git a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java index 54d30f5b..80903df2 100644 --- a/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java +++ b/src/main/java/com/kamco/cd/kamcoback/label/service/LabelAllocateService.java @@ -1,5 +1,7 @@ package com.kamco.cd.kamcoback.label.service; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto; +import com.kamco.cd.kamcoback.config.api.ApiResponseDto.ApiResponseCode; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.InferenceDetail; import com.kamco.cd.kamcoback.label.dto.LabelAllocateDto.LabelerDetail; @@ -12,6 +14,7 @@ import com.kamco.cd.kamcoback.label.dto.WorkerStatsDto.WorkerStatistics; import com.kamco.cd.kamcoback.postgres.core.LabelAllocateCoreService; import java.time.LocalDate; import java.util.List; +import java.util.Objects; import java.util.UUID; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -34,14 +37,16 @@ public class LabelAllocateService { /** * 도엽 기준 asc sorting 해서 할당 수만큼 배정하는 로직 * - * @param autoType 자동/수동 배정 타입 + * @param labelerAutoType 라벨러 자동/수동 배정 타입 + * @param inspectorAutoType 검수자 자동/수동 배정 타입 * @param stage 회차 * @param targetUsers 라벨러 목록 * @param targetInspectors 검수자 목록 */ @Transactional - public void allocateAsc( - String autoType, + public ApiResponseDto.ResponseObj allocateAsc( + String labelerAutoType, + String inspectorAutoType, Integer stage, List targetUsers, List targetInspectors, @@ -52,14 +57,14 @@ public class LabelAllocateService { // geom 잔여건수 조회 Long chargeCnt = labelAllocateCoreService.findLabelUnAssignedCnt(stage, compareYyyy, targetYyyy); - // Long totalDemand = targetUsers.stream().mapToLong(TargetUser::getDemand).sum(); - // if (!Objects.equals(chargeCnt, totalDemand)) { - // log.info("chargeCnt != totalDemand"); - // return; - // } - if (chargeCnt <= 0) { - return; + return new ApiResponseDto.ResponseObj(ApiResponseCode.DUPLICATE_DATA, "이미 배정완료된 회차 입니다."); + } + + Long totalDemand = targetUsers.stream().mapToLong(TargetUser::getDemand).sum(); + if (!Objects.equals(chargeCnt, totalDemand)) { + return new ApiResponseDto.ResponseObj( + ApiResponseCode.BAD_REQUEST, "총 잔여건수와 요청 값의 합계가 맞지 않습니다."); } List allIds = @@ -92,6 +97,8 @@ public class LabelAllocateService { from = to; } + + return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "배정이 완료되었습니다."); } public List availUserList(String role) { @@ -162,7 +169,7 @@ public class LabelAllocateService { return labelAllocateCoreService.findInferenceDetail(compareYyyy, targetYyyy, stage); } - public void allocateMove( + public ApiResponseDto.ResponseObj allocateMove( String autoType, Integer stage, List targetUsers, @@ -173,7 +180,7 @@ public class LabelAllocateService { Long chargeCnt = targetUsers.stream().mapToLong(TargetUser::getDemand).sum(); if (chargeCnt <= 0) { - return; + return new ApiResponseDto.ResponseObj(ApiResponseCode.BAD_REQUEST, "이관할 데이터를 입력해주세요."); } List allIds = @@ -187,6 +194,8 @@ public class LabelAllocateService { labelAllocateCoreService.assignOwnerMove(sub, target.getUserId()); index = end; } + + return new ApiResponseDto.ResponseObj(ApiResponseCode.OK, "이관을 완료하였습니다."); } public LabelerDetail findLabelerDetail(