From 44878e9c37283e72ed33080c972de9683dd42a1d Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 3 Feb 2026 15:15:25 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=ED=95=98=EC=9D=B4=ED=8D=BC=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B8=B0=EB=8A=A5=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 --- .../com/kamco/cd/training/hyperparam/dto/HyperParamDto.java | 2 ++ .../kamco/cd/training/postgres/core/HyperParamCoreService.java | 2 ++ .../cd/training/postgres/entity/ModelHyperParamEntity.java | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/kamco/cd/training/hyperparam/dto/HyperParamDto.java b/src/main/java/com/kamco/cd/training/hyperparam/dto/HyperParamDto.java index 6b9c93c..f6f096d 100644 --- a/src/main/java/com/kamco/cd/training/hyperparam/dto/HyperParamDto.java +++ b/src/main/java/com/kamco/cd/training/hyperparam/dto/HyperParamDto.java @@ -25,6 +25,8 @@ public class HyperParamDto { public static class Basic { private UUID uuid; + private String hyperVer; + @JsonFormatDttm private ZonedDateTime createdDttm; // ------------------------- // Important diff --git a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java index c034cd6..5803749 100644 --- a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java +++ b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java @@ -132,6 +132,8 @@ public class HyperParamCoreService { public HyperParamDto.Basic getInitHyperParam() { ModelHyperParamEntity entity = new ModelHyperParamEntity(); entity.setUuid(null); + entity.setHyperVer(null); + entity.setCreatedDttm(null); return entity.toDto(); } diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java index b0d6ac6..e23421b 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java @@ -319,7 +319,8 @@ public class ModelHyperParamEntity { public HyperParamDto.Basic toDto() { return new HyperParamDto.Basic( this.uuid, - + this.hyperVer, + this.createdDttm, // ------------------------- // Important // ------------------------- From d66711e4f4108cbdd073ec3b661b8b8fee339e95 Mon Sep 17 00:00:00 2001 From: teddy Date: Tue, 3 Feb 2026 16:31:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=ED=95=98=EC=9D=B4=ED=8D=BC=ED=8C=8C?= =?UTF-8?q?=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B8=B0=EB=8A=A5=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 --- .../common/enums/TrainStatusType.java | 24 +- .../training/model/ModelMngApiController.java | 369 +++++++++--------- .../cd/training/model/dto/ModelMngDto.java | 1 + .../model/service/ModelMngService.java | 7 +- .../postgres/core/HyperParamCoreService.java | 2 +- .../postgres/core/ModelMngCoreService.java | 13 +- .../entity/ModelHyperParamEntity.java | 4 +- .../entity/ModelTrainMasterEntity.java | 3 +- .../hyperparam/HyperParamRepositoryImpl.java | 6 +- .../model/ModelMngRepositoryCustom.java | 4 + .../model/ModelMngRepositoryImpl.java | 60 +-- 11 files changed, 277 insertions(+), 216 deletions(-) diff --git a/src/main/java/com/kamco/cd/training/common/enums/TrainStatusType.java b/src/main/java/com/kamco/cd/training/common/enums/TrainStatusType.java index 8a3db27..45c598c 100644 --- a/src/main/java/com/kamco/cd/training/common/enums/TrainStatusType.java +++ b/src/main/java/com/kamco/cd/training/common/enums/TrainStatusType.java @@ -10,13 +10,21 @@ import lombok.Getter; @AllArgsConstructor public enum TrainStatusType implements EnumType { // @formatter:off - READY("READY", "대기"), - ING("ING", "진행중"), - COMPLETED("COMPLETED", "완료"), - STOPPED("STOPPED", "중단됨"), - ERROR("ERROR", "오류"); - // @formatter:on + READY("대기"), + IN_PROGRESS("진행중"), + COMPLETED("완료"), + STOPPED("중단됨"), + ERROR("오류"); - private final String id; - private final String text; + private final String desc; + + @Override + public String getId() { + return name(); + } + + @Override + public String getText() { + return desc; + } } diff --git a/src/main/java/com/kamco/cd/training/model/ModelMngApiController.java b/src/main/java/com/kamco/cd/training/model/ModelMngApiController.java index 5c0c065..9a704f0 100644 --- a/src/main/java/com/kamco/cd/training/model/ModelMngApiController.java +++ b/src/main/java/com/kamco/cd/training/model/ModelMngApiController.java @@ -12,15 +12,12 @@ 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 java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -33,7 +30,7 @@ public class ModelMngApiController { private final ModelMngService modelMngService; private final ModelTrainService modelTrainService; - @Operation(summary = "학습 모델 목록 조회", description = "학습 모델 목록을 조회합니다") + @Operation(summary = "모델관리 목록 조회", description = "모델관리 목록 조회 API") @ApiResponses( value = { @ApiResponse( @@ -46,186 +43,206 @@ public class ModelMngApiController { @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) }) - @GetMapping - public ApiResponseDto> findByModels( - @Parameter(description = "상태 코드") @RequestParam(required = false) String status, + @GetMapping("/list") + public ApiResponseDto> findByModelList( + @Parameter( + description = "상태코드", + example = "IN_PROGRESS", + schema = @Schema(allowableValues = {"", "IN_PROGRESS", "COMPLETED"})) + @RequestParam(required = false) + String status, @Parameter(description = "페이지 번호") @RequestParam(defaultValue = "0") int page, @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "20") int size) { ModelMngDto.SearchReq searchReq = new ModelMngDto.SearchReq(status, page, size); - return ApiResponseDto.ok(modelMngService.findByModels(searchReq)); + return ApiResponseDto.ok(modelMngService.getModelList(searchReq)); } - @Operation(summary = "학습 모델 상세 조회", description = "학습 모델의 상세 정보를 UUID로 조회합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.Detail.class))), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/{uuid}") - public ApiResponseDto getModelDetail( - @Parameter(description = "모델 UUID", example = "b7e99739-6736-45f9-a224-8161ecddf287") - @PathVariable - String uuid) { - return ApiResponseDto.ok(modelMngService.getModelDetailByUuid(uuid)); - } - - // ==================== 학습 모델학습관리 API (5종) ==================== - - @Operation(summary = "학습 모델 통합 조회", description = "학습 관리 화면에서 학습 이력 리스트와 현재 상태를 조회합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = List.class))), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/train") - public ApiResponseDto> getTrainModelList() { - return ApiResponseDto.ok(modelTrainService.getTrainModelList()); - } - - @Operation(summary = "학습 설정 통합 조회", description = "학습 실행 팝업 구성에 필요한 모든 데이터를 한 번에 반환합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.FormConfigRes.class))), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/train/form-config") - public ApiResponseDto getFormConfig() { - return ApiResponseDto.ok(modelTrainService.getFormConfig()); - } - - @Operation(summary = "학습 시작", description = "모든 설정(Step 1~3)을 마치고 최종적으로 학습 프로세스를 시작합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "학습 시작 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.TrainStartRes.class))), - @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @PostMapping("/train") - public ApiResponseDto startTraining( - @Valid @RequestBody ModelMngDto.TrainStartReq trainReq) { - return ApiResponseDto.ok(modelTrainService.startTraining(trainReq)); - } - - @Operation(summary = "학습 모델 삭제", description = "목록에서 특정 학습 모델을 삭제합니다") + @Operation(summary = "학습 모델 삭제", description = "학습 모델 삭제 API") @ApiResponses( value = { @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content), - @ApiResponse(responseCode = "400", description = "진행 중인 모델은 삭제 불가", content = @Content), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + @ApiResponse(responseCode = "409", description = "HPs_0001 삭제 불가", content = @Content) }) - @DeleteMapping("/train/{uuid}") - public ApiResponseDto deleteTrainModel( - @Parameter(description = "모델 UUID") @PathVariable String uuid) { - modelTrainService.deleteTrainModel(uuid); + @DeleteMapping("/{uuid}") + public ApiResponseDto deleteModelTrain( + @Parameter(description = "학습 모델 uuid", example = "f2b02229-90f2-45f5-92ea-c56cf1c29f79") + @PathVariable + UUID uuid) { + modelMngService.deleteModelTrain(uuid); return ApiResponseDto.ok(null); } - - // ==================== Resume Training (학습 재시작) ==================== - - @Operation(summary = "학습 재시작 정보 조회", description = "중단된 학습의 재시작 가능 여부와 Checkpoint 정보를 조회합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.ResumeInfo.class))), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/train/{uuid}/resume-info") - public ApiResponseDto getResumeInfo( - @Parameter(description = "모델 UUID") @PathVariable String uuid) { - return ApiResponseDto.ok(modelTrainService.getResumeInfo(uuid)); - } - - @Operation(summary = "학습 재시작", description = "중단된 지점(Checkpoint)부터 학습을 재개합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "재시작 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.ResumeResponse.class))), - @ApiResponse(responseCode = "400", description = "재시작 불가능한 상태", content = @Content), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @PostMapping("/train/{uuid}/resume") - public ApiResponseDto resumeTraining( - @Parameter(description = "모델 UUID") @PathVariable String uuid, - @Valid @RequestBody ModelMngDto.ResumeRequest resumeReq) { - return ApiResponseDto.ok(modelTrainService.resumeTraining(uuid, resumeReq)); - } - - // ==================== Best Epoch Setting (Best Epoch 설정) ==================== - - @Operation(summary = "Best Epoch 설정", description = "사용자가 직접 Best Epoch를 선택하여 설정합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "설정 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = ModelMngDto.BestEpochResponse.class))), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @PostMapping("/train/{uuid}/best-epoch") - public ApiResponseDto setBestEpoch( - @Parameter(description = "모델 UUID") @PathVariable String uuid, - @Valid @RequestBody ModelMngDto.BestEpochRequest bestEpochReq) { - return ApiResponseDto.ok(modelTrainService.setBestEpoch(uuid, bestEpochReq)); - } - - @Operation(summary = "Epoch별 성능 지표 조회", description = "학습된 모델의 Epoch별 성능 지표를 조회합니다") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = - @Content( - mediaType = "application/json", - schema = @Schema(implementation = List.class))), - @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), - @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) - }) - @GetMapping("/train/{uuid}/epoch-metrics") - public ApiResponseDto> getEpochMetrics( - @Parameter(description = "모델 UUID") @PathVariable String uuid) { - return ApiResponseDto.ok(modelTrainService.getEpochMetrics(uuid)); - } + // + // @Operation(summary = "학습 모델 상세 조회", description = "학습 모델의 상세 정보를 UUID로 조회합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "조회 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.Detail.class))), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/{uuid}") + // public ApiResponseDto getModelDetail( + // @Parameter(description = "모델 UUID", example = "b7e99739-6736-45f9-a224-8161ecddf287") + // @PathVariable + // String uuid) { + // return ApiResponseDto.ok(modelMngService.getModelDetailByUuid(uuid)); + // } + // + // // ==================== 학습 모델학습관리 API (5종) ==================== + // + // @Operation(summary = "학습 모델 통합 조회", description = "학습 관리 화면에서 학습 이력 리스트와 현재 상태를 조회합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "조회 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = List.class))), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/train") + // public ApiResponseDto> getTrainModelList() { + // return ApiResponseDto.ok(modelTrainService.getTrainModelList()); + // } + // + // @Operation(summary = "학습 설정 통합 조회", description = "학습 실행 팝업 구성에 필요한 모든 데이터를 한 번에 반환합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "조회 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.FormConfigRes.class))), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/train/form-config") + // public ApiResponseDto getFormConfig() { + // return ApiResponseDto.ok(modelTrainService.getFormConfig()); + // } + // + // @Operation(summary = "학습 시작", description = "모든 설정(Step 1~3)을 마치고 최종적으로 학습 프로세스를 시작합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "학습 시작 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.TrainStartRes.class))), + // @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @PostMapping("/train") + // public ApiResponseDto startTraining( + // @Valid @RequestBody ModelMngDto.TrainStartReq trainReq) { + // return ApiResponseDto.ok(modelTrainService.startTraining(trainReq)); + // } + // + // @Operation(summary = "학습 모델 삭제", description = "목록에서 특정 학습 모델을 삭제합니다") + // @ApiResponses( + // value = { + // @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content), + // @ApiResponse(responseCode = "400", description = "진행 중인 모델은 삭제 불가", content = @Content), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @DeleteMapping("/train/{uuid}") + // public ApiResponseDto deleteTrainModel( + // @Parameter(description = "모델 UUID") @PathVariable String uuid) { + // modelTrainService.deleteTrainModel(uuid); + // return ApiResponseDto.ok(null); + // } + // + // // ==================== Resume Training (학습 재시작) ==================== + // + // @Operation(summary = "학습 재시작 정보 조회", description = "중단된 학습의 재시작 가능 여부와 Checkpoint 정보를 조회합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "조회 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.ResumeInfo.class))), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/train/{uuid}/resume-info") + // public ApiResponseDto getResumeInfo( + // @Parameter(description = "모델 UUID") @PathVariable String uuid) { + // return ApiResponseDto.ok(modelTrainService.getResumeInfo(uuid)); + // } + // + // @Operation(summary = "학습 재시작", description = "중단된 지점(Checkpoint)부터 학습을 재개합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "재시작 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.ResumeResponse.class))), + // @ApiResponse(responseCode = "400", description = "재시작 불가능한 상태", content = @Content), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @PostMapping("/train/{uuid}/resume") + // public ApiResponseDto resumeTraining( + // @Parameter(description = "모델 UUID") @PathVariable String uuid, + // @Valid @RequestBody ModelMngDto.ResumeRequest resumeReq) { + // return ApiResponseDto.ok(modelTrainService.resumeTraining(uuid, resumeReq)); + // } + // + // // ==================== Best Epoch Setting (Best Epoch 설정) ==================== + // + // @Operation(summary = "Best Epoch 설정", description = "사용자가 직접 Best Epoch를 선택하여 설정합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "설정 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = ModelMngDto.BestEpochResponse.class))), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @PostMapping("/train/{uuid}/best-epoch") + // public ApiResponseDto setBestEpoch( + // @Parameter(description = "모델 UUID") @PathVariable String uuid, + // @Valid @RequestBody ModelMngDto.BestEpochRequest bestEpochReq) { + // return ApiResponseDto.ok(modelTrainService.setBestEpoch(uuid, bestEpochReq)); + // } + // + // @Operation(summary = "Epoch별 성능 지표 조회", description = "학습된 모델의 Epoch별 성능 지표를 조회합니다") + // @ApiResponses( + // value = { + // @ApiResponse( + // responseCode = "200", + // description = "조회 성공", + // content = + // @Content( + // mediaType = "application/json", + // schema = @Schema(implementation = List.class))), + // @ApiResponse(responseCode = "404", description = "모델을 찾을 수 없음", content = @Content), + // @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + // }) + // @GetMapping("/train/{uuid}/epoch-metrics") + // public ApiResponseDto> getEpochMetrics( + // @Parameter(description = "모델 UUID") @PathVariable String uuid) { + // return ApiResponseDto.ok(modelTrainService.getEpochMetrics(uuid)); + // } } diff --git a/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java b/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java index 700ac8f..a4b0414 100644 --- a/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java +++ b/src/main/java/com/kamco/cd/training/model/dto/ModelMngDto.java @@ -38,6 +38,7 @@ public class ModelMngDto { private String step1Status; private String step2Status; private String transferStatus; + private String statusCd; } @Schema(name = "searchReq", description = "모델 관리 목록조회 파라미터") diff --git a/src/main/java/com/kamco/cd/training/model/service/ModelMngService.java b/src/main/java/com/kamco/cd/training/model/service/ModelMngService.java index 1b1be3a..47f177f 100644 --- a/src/main/java/com/kamco/cd/training/model/service/ModelMngService.java +++ b/src/main/java/com/kamco/cd/training/model/service/ModelMngService.java @@ -4,6 +4,7 @@ import com.kamco.cd.training.model.dto.ModelMngDto; import com.kamco.cd.training.model.dto.ModelMngDto.Basic; import com.kamco.cd.training.model.dto.ModelMngDto.SearchReq; import com.kamco.cd.training.postgres.core.ModelMngCoreService; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -24,10 +25,12 @@ public class ModelMngService { * @param searchReq 검색 조건 * @return 페이징 처리된 모델 목록 */ - public Page findByModels(SearchReq searchReq) { - return modelMngCoreService.findByModels(searchReq); + public Page getModelList(SearchReq searchReq) { + return modelMngCoreService.findByModelList(searchReq); } + public void deleteModelTrain(UUID uuid) {} + /** * 모델 상세 조회 * diff --git a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java index 5803749..725c3f3 100644 --- a/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java +++ b/src/main/java/com/kamco/cd/training/postgres/core/HyperParamCoreService.java @@ -119,7 +119,7 @@ public class HyperParamCoreService { throw new CustomApiException("CONFLICT", HttpStatus.CONFLICT, "HPs_0001 버전은 삭제할수 없습니다."); } - entity.setDelYn("Y"); + entity.setDelYn(true); entity.setUpdatedUid(userUtil.getId()); entity.setUpdatedDttm(ZonedDateTime.now()); } diff --git a/src/main/java/com/kamco/cd/training/postgres/core/ModelMngCoreService.java b/src/main/java/com/kamco/cd/training/postgres/core/ModelMngCoreService.java index 6fed74c..77c1c35 100644 --- a/src/main/java/com/kamco/cd/training/postgres/core/ModelMngCoreService.java +++ b/src/main/java/com/kamco/cd/training/postgres/core/ModelMngCoreService.java @@ -1,6 +1,7 @@ package com.kamco.cd.training.postgres.core; import com.kamco.cd.training.common.exception.BadRequestException; +import com.kamco.cd.training.common.exception.CustomApiException; import com.kamco.cd.training.common.exception.NotFoundException; import com.kamco.cd.training.model.dto.ModelMngDto; import com.kamco.cd.training.model.dto.ModelMngDto.Basic; @@ -10,8 +11,10 @@ import com.kamco.cd.training.postgres.repository.model.ModelDatasetMappRepositor import com.kamco.cd.training.postgres.repository.model.ModelMngRepository; import java.time.ZonedDateTime; import java.util.List; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @Service @@ -26,11 +29,19 @@ public class ModelMngCoreService { * @param searchReq 검색 조건 * @return 페이징 처리된 모델 목록 */ - public Page findByModels(ModelMngDto.SearchReq searchReq) { + public Page findByModelList(ModelMngDto.SearchReq searchReq) { Page entityPage = modelMngRepository.findByModels(searchReq); return entityPage.map(ModelTrainMasterEntity::toDto); } + public void deleteModel(UUID uuid) { + ModelTrainMasterEntity entity = + modelMngRepository + .findByUuid(uuid) + .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND)); + // entity.setDelYn(); + } + /** * 모델 상세 조회 * diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java index e23421b..698484e 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelHyperParamEntity.java @@ -280,9 +280,9 @@ public class ModelHyperParamEntity { private String memo; @NotNull - @ColumnDefault("'N'") + @ColumnDefault("false") @Column(name = "del_yn", nullable = false, length = 1) - private String delYn = "N"; + private Boolean delYn = false; @NotNull @ColumnDefault("CURRENT_TIMESTAMP") diff --git a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java index 99a9fb9..b510725 100644 --- a/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java +++ b/src/main/java/com/kamco/cd/training/postgres/entity/ModelTrainMasterEntity.java @@ -186,6 +186,7 @@ public class ModelTrainMasterEntity { this.step2Duration, this.step1Status, this.step2Status, - this.transferStatus); + this.transferStatus, + this.statusCd); } } diff --git a/src/main/java/com/kamco/cd/training/postgres/repository/hyperparam/HyperParamRepositoryImpl.java b/src/main/java/com/kamco/cd/training/postgres/repository/hyperparam/HyperParamRepositoryImpl.java index d0aa583..a68feca 100644 --- a/src/main/java/com/kamco/cd/training/postgres/repository/hyperparam/HyperParamRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/training/postgres/repository/hyperparam/HyperParamRepositoryImpl.java @@ -35,7 +35,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom { queryFactory .select(modelHyperParamEntity) .from(modelHyperParamEntity) - .where(modelHyperParamEntity.delYn.eq("N")) + .where(modelHyperParamEntity.delYn.isFalse()) .orderBy(modelHyperParamEntity.hyperVer.desc()) .limit(1) .fetchOne()); @@ -47,7 +47,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom { queryFactory .select(modelHyperParamEntity) .from(modelHyperParamEntity) - .where(modelHyperParamEntity.delYn.eq("N").and(modelHyperParamEntity.uuid.eq(uuid))) + .where(modelHyperParamEntity.delYn.isFalse().and(modelHyperParamEntity.uuid.eq(uuid))) .fetchOne()); } @@ -56,7 +56,7 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom { Pageable pageable = req.toPageable(); BooleanBuilder builder = new BooleanBuilder(); - builder.and(modelHyperParamEntity.delYn.eq("N")); + builder.and(modelHyperParamEntity.delYn.isFalse()); if (req.getHyperVer() != null && !req.getHyperVer().isEmpty()) { // 버전 diff --git a/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryCustom.java b/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryCustom.java index 7b15582..6093c07 100644 --- a/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryCustom.java @@ -2,6 +2,8 @@ package com.kamco.cd.training.postgres.repository.model; import com.kamco.cd.training.model.dto.ModelMngDto; import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity; +import java.util.Optional; +import java.util.UUID; import org.springframework.data.domain.Page; public interface ModelMngRepositoryCustom { @@ -13,4 +15,6 @@ public interface ModelMngRepositoryCustom { * @return */ Page findByModels(ModelMngDto.SearchReq searchReq); + + Optional findByUuid(UUID uuid); } diff --git a/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryImpl.java b/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryImpl.java index faf8814..7f2ed20 100644 --- a/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/training/postgres/repository/model/ModelMngRepositoryImpl.java @@ -1,12 +1,14 @@ package com.kamco.cd.training.postgres.repository.model; +import static com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity.modelTrainMasterEntity; + import com.kamco.cd.training.model.dto.ModelMngDto; import com.kamco.cd.training.postgres.entity.ModelTrainMasterEntity; -import com.kamco.cd.training.postgres.entity.QModelTrainMasterEntity; import com.querydsl.core.BooleanBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import java.util.Optional; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -18,43 +20,57 @@ import org.springframework.stereotype.Repository; public class ModelMngRepositoryImpl implements ModelMngRepositoryCustom { private final JPAQueryFactory queryFactory; - private final QModelTrainMasterEntity modelMng = QModelTrainMasterEntity.modelTrainMasterEntity; /** * 모델 목록 조회 * - * @param searchReq + * @param req * @return */ @Override - public Page findByModels(ModelMngDto.SearchReq searchReq) { - Pageable pageable = searchReq.toPageable(); + public Page findByModels(ModelMngDto.SearchReq req) { + Pageable pageable = req.toPageable(); BooleanBuilder builder = new BooleanBuilder(); - // - // if (StringUtils.isNotBlank(searchReq.getStatus())) { - // builder.and(modelMng.statusCd.eq(searchReq.getStatus())); - // } - // Entity 직접 조회 (Projections 사용 지양) + if (req.getStatus() != null && !req.getStatus().isEmpty()) { + builder.and(modelTrainMasterEntity.statusCd.eq(req.getStatus())); + } + List content = queryFactory - .selectFrom(modelMng) - .where(builder.and(modelMng.delYn.isFalse())) + .selectFrom(modelTrainMasterEntity) + .where(builder) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) - .orderBy(modelMng.createdDttm.desc()) + .orderBy(modelTrainMasterEntity.createdDttm.desc()) .fetch(); // Count 쿼리 별도 실행 (null safe handling) - long total = - Optional.ofNullable( - queryFactory - .select(modelMng.count()) - .from(modelMng) - .where(builder.and(modelMng.delYn.isFalse())) - .fetchOne()) - .orElse(0L); + Long total = + queryFactory + .select(modelTrainMasterEntity.count()) + .from(modelTrainMasterEntity) + .where(builder) + .fetchOne(); - return new PageImpl<>(content, pageable, total); + long totalCount = (total != null) ? total : 0L; + + return new PageImpl<>(content, pageable, totalCount); + } + + /** + * 모델 조회 + * + * @param uuid + * @return + */ + @Override + public Optional findByUuid(UUID uuid) { + return Optional.ofNullable( + queryFactory + .select(modelTrainMasterEntity) + .from(modelTrainMasterEntity) + .where(modelTrainMasterEntity.uuid.eq(uuid)) + .fetchOne()); } }