81 Commits

Author SHA1 Message Date
6204a6e5fa Merge remote-tracking branch 'origin/develop' into feat/training_260202
# Conflicts:
#	src/main/resources/application-prod.yml
2026-02-12 21:15:21 +09:00
83204abfe9 Merge pull request '성공시 csv 파일 테이블에 저장 연결' (#74) from feat/training_260202 into develop
Reviewed-on: #74
2026-02-12 21:01:48 +09:00
452494d44d Merge pull request '테스트 실행 경로 수정' (#73) from feat/training_260202 into develop
Reviewed-on: #73
2026-02-12 20:49:30 +09:00
e442f105bc Merge pull request '도커명 변경' (#72) from feat/training_260202 into develop
Reviewed-on: #72
2026-02-12 20:37:00 +09:00
b4c2685059 Merge pull request '도커 설정 추가' (#71) from feat/training_260202 into develop
Reviewed-on: #71
2026-02-12 20:25:16 +09:00
97b06eb3b3 Merge pull request '임시파일생성 경로 수정' (#70) from feat/training_260202 into develop
Reviewed-on: #70
2026-02-12 20:03:32 +09:00
98a1283ebe Merge pull request '임시파일생성 경로 수정' (#69) from feat/training_260202 into develop
Reviewed-on: #69
2026-02-12 19:36:06 +09:00
c3c9191d9d Merge pull request 'hyperparam_with_modeltype' (#68) from feat/dean/hyperparam_with_modelType-bug into develop
Reviewed-on: #68
2026-02-12 19:30:29 +09:00
9fd5a15a72 hyperparam_with_modeltype 2026-02-12 19:30:08 +09:00
12f9de7367 hyperparam_with_modeltype 2026-02-12 19:16:24 +09:00
5455da1e96 hyperparam_with_modeltype 2026-02-12 19:16:13 +09:00
9e803661cd Merge pull request 'feat/training_260202' (#67) from feat/training_260202 into develop
Reviewed-on: #67
2026-02-12 19:14:39 +09:00
b0cf9e77ec Merge branch 'develop' of https://kamco.git.gs.dabeeo.com/MVPTeam/kamco-train-api into develop 2026-02-12 19:14:10 +09:00
d5b2b8ecec hyperparam_with_modeltype 2026-02-12 19:14:01 +09:00
49d3e37458 Merge pull request '임시파일생성 경로 수정' (#66) from feat/training_260202 into develop
Reviewed-on: #66
2026-02-12 19:12:37 +09:00
d7766edd24 Merge pull request 'return 형식 수정' (#65) from feat/training_260202 into develop
Reviewed-on: #65
2026-02-12 18:59:37 +09:00
0bc4453c9c hyperparam_with_modeltype 2026-02-12 18:56:32 +09:00
37d776dd2c Merge pull request 'hyperparam_with_modeltype' (#64) from feat/dean/hyperparam_with_modelType into develop
Reviewed-on: #64
2026-02-12 18:50:32 +09:00
0c34ea7dcb hyperparam_with_modeltype 2026-02-12 18:48:14 +09:00
3106d36431 Merge pull request '업로드 시 같은 uid로 업로드하지 못하게 조건 추가' (#63) from feat/training_260202 into develop
Reviewed-on: #63
2026-02-12 18:44:49 +09:00
da92b28d97 Merge pull request '임시파일생성 소프트링크에서 하드링크로 변경' (#62) from feat/training_260202 into develop
Reviewed-on: #62
2026-02-12 18:20:30 +09:00
e3f00876f1 Merge pull request '문제되는 하이퍼파라미터 주석처리' (#61) from feat/training_260202 into develop
Reviewed-on: #61
2026-02-12 17:53:11 +09:00
60962bbc75 Merge pull request '학습실행 mount 경로 수정' (#60) from feat/training_260202 into develop
Reviewed-on: #60
2026-02-12 17:44:15 +09:00
64d37dcc08 Merge pull request '임시폴더생성 api 추가' (#59) from feat/training_260202 into develop
Reviewed-on: #59
2026-02-12 17:23:53 +09:00
a2490f30e6 Merge pull request '임시폴더생성 api 수정' (#58) from feat/training_260202 into develop
Reviewed-on: #58
2026-02-12 17:14:52 +09:00
bd04e1f4e8 Merge pull request '임시폴더생성 api 추가' (#57) from feat/training_260202 into develop
Reviewed-on: #57
2026-02-12 17:03:39 +09:00
5fc15937c0 Merge pull request 'feat/training_260202' (#56) from feat/training_260202 into develop
Reviewed-on: #56
2026-02-12 17:00:08 +09:00
3547c28361 Merge pull request 'feat/training_260202' (#55) from feat/training_260202 into develop
Reviewed-on: #55
2026-02-12 16:56:23 +09:00
2a1dbee290 Merge pull request '모델학습 1단계 실행중인 것이 있는지 count API' (#54) from feat/training_260202 into develop
Reviewed-on: #54
2026-02-12 16:51:09 +09:00
f4e97d389b Merge pull request 'file 확인 API 수정' (#53) from feat/training_260202 into develop
Reviewed-on: #53
2026-02-12 16:42:20 +09:00
a01c872982 Merge pull request 'feat/training_260202' (#52) from feat/training_260202 into develop
Reviewed-on: #52
2026-02-12 16:15:11 +09:00
7f3f5dca40 Merge pull request 'feat/training_260202' (#51) from feat/training_260202 into develop
Reviewed-on: #51
2026-02-12 16:13:19 +09:00
26e8e1492f Merge pull request 'feat/training_260202' (#50) from feat/training_260202 into develop
Reviewed-on: #50
2026-02-12 15:52:09 +09:00
cd0cf5726d Merge pull request 'feat/training_260202' (#49) from feat/training_260202 into develop
Reviewed-on: #49
2026-02-12 15:44:11 +09:00
7e9c867f34 Merge pull request '모델 등록할 때 step1State를 READY로 업데이트' (#48) from feat/training_260202 into develop
Reviewed-on: #48
2026-02-12 14:35:52 +09:00
9e713cb49d Merge pull request '업로드 로직 재수정' (#47) from feat/training_260202 into develop
Reviewed-on: #47
2026-02-12 14:21:57 +09:00
87c6b599b4 Merge pull request 'feat/training_260202' (#46) from feat/training_260202 into develop
Reviewed-on: #46
2026-02-12 12:10:04 +09:00
22aa071476 Merge pull request 'feat/training_260202' (#45) from feat/training_260202 into develop
Reviewed-on: #45
2026-02-12 12:06:04 +09:00
be6365807c Merge pull request '실행 오류 수정' (#43) from feat/training_260202 into develop
Reviewed-on: #43
2026-02-12 10:20:05 +09:00
f66bc22c95 Merge pull request '실행 오류 수정' (#42) from feat/training_260202 into develop
Reviewed-on: #42
2026-02-12 10:14:54 +09:00
352ec6ccb0 Merge pull request 'feat/training_260202' (#41) from feat/training_260202 into develop
Reviewed-on: #41
2026-02-12 09:53:02 +09:00
0602db1436 Merge pull request '테스트 실행 추가' (#40) from feat/training_260202 into develop
Reviewed-on: #40
2026-02-11 21:58:58 +09:00
75231ccbba Merge pull request '추론 실행 추가' (#39) from feat/training_260202 into develop
Reviewed-on: #39
2026-02-11 20:22:01 +09:00
00c78eb42f Merge pull request '성능정보 그래프 데이터 API 추가' (#38) from feat/training_260202 into develop
Reviewed-on: #38
2026-02-11 19:52:23 +09:00
47a2a159ef Merge pull request 'test metrics 스케줄 추가' (#37) from feat/training_260202 into develop
Reviewed-on: #37
2026-02-11 19:10:37 +09:00
2debdc5312 Merge pull request 'feat/training_260202' (#36) from feat/training_260202 into develop
Reviewed-on: #36
2026-02-11 18:51:01 +09:00
c843703ee7 Merge pull request 'file 가져오기 86 호출하는 거로 추가' (#35) from feat/training_260202 into develop
Reviewed-on: #35
2026-02-11 16:53:25 +09:00
0df977ae81 Merge pull request '업로드 로직 86으로 수행하기 수정' (#34) from feat/training_260202 into develop
Reviewed-on: #34
2026-02-11 16:33:03 +09:00
3ec1a71406 Merge pull request '업로드 로직 수정' (#33) from feat/training_260202 into develop
Reviewed-on: #33
2026-02-11 15:53:21 +09:00
41911014c9 Merge pull request '업로드 로직 수정' (#32) from feat/training_260202 into develop
Reviewed-on: #32
2026-02-11 15:44:54 +09:00
a4ac80c787 Merge pull request '업로드 경로 수정' (#31) from feat/training_260202 into develop
Reviewed-on: #31
2026-02-11 15:11:02 +09:00
2f63b9ddcd Merge pull request 'feat/training_260202' (#30) from feat/training_260202 into develop
Reviewed-on: #30
2026-02-11 14:08:58 +09:00
885b72a0c6 Merge pull request '모델별 데이터셋 목록 조회 수정' (#29) from feat/training_260202 into develop
Reviewed-on: #29
2026-02-11 12:29:08 +09:00
fbb5a34867 Merge pull request '업로드 경로 원복' (#28) from feat/training_260202 into develop
Reviewed-on: #28
2026-02-11 12:12:43 +09:00
6b3f22dd66 Merge pull request '업로드 파일 max 수정' (#27) from feat/training_260202 into develop
Reviewed-on: #27
2026-02-11 11:53:04 +09:00
29e1d0ec7e Merge pull request '업로드 경로 수정' (#26) from feat/training_260202 into develop
Reviewed-on: #26
2026-02-11 11:41:49 +09:00
a2072e0148 Merge pull request 'feat/training_260202' (#25) from feat/training_260202 into develop
Reviewed-on: #25
2026-02-11 10:28:38 +09:00
2d5de88a6b Merge pull request '학습데이터 업로드, unzip 로직 진행중' (#24) from feat/training_260202 into develop
Reviewed-on: #24
2026-02-10 10:44:28 +09:00
eda1d19942 Merge pull request '스웨거 로그인 설정 수정' (#23) from feat/training_260202 into develop
Reviewed-on: #23
2026-02-06 14:54:56 +09:00
653717a074 Merge pull request 'feat/training_260202' (#22) from feat/training_260202 into develop
Reviewed-on: #22
2026-02-06 11:09:36 +09:00
679795d14d Merge pull request '전이학습 추가' (#21) from feat/training_260202 into develop
Reviewed-on: #21
2026-02-05 18:23:30 +09:00
9655c62d35 Merge pull request '하이퍼 파라미터 최적값 조회 수정' (#20) from feat/training_260202 into develop
Reviewed-on: #20
2026-02-05 15:22:56 +09:00
af16933378 Merge pull request 'feat/training_260202' (#19) from feat/training_260202 into develop
Reviewed-on: #19
2026-02-05 15:08:41 +09:00
03135a972a Merge pull request '모델학습 데이터셋 선택 목록 수정' (#18) from feat/training_260202 into develop
Reviewed-on: #18
2026-02-05 13:59:00 +09:00
947cba2742 Merge pull request 'feat/training_260202' (#17) from feat/training_260202 into develop
Reviewed-on: #17
2026-02-04 19:54:23 +09:00
b25fc6fe68 Merge pull request 'feat/training_260202' (#16) from feat/training_260202 into develop
Reviewed-on: #16
2026-02-04 18:01:15 +09:00
5bc59c0e0b Merge pull request '데이터셋 조회 수정' (#15) from feat/training_260202 into develop
Reviewed-on: #15
2026-02-04 14:11:00 +09:00
cdac9d6148 Merge pull request '모델학습 설정 dto 수정' (#14) from feat/training_260202 into develop
Reviewed-on: #14
2026-02-04 14:03:41 +09:00
d238debcc8 Merge pull request '모델학습 설정 dto 수정' (#13) from feat/training_260202 into develop
Reviewed-on: #13
2026-02-04 13:57:00 +09:00
3e780ef007 Merge pull request 'feat/training_260202' (#12) from feat/training_260202 into develop
Reviewed-on: #12
2026-02-04 12:32:36 +09:00
2110f395b7 Merge pull request 'dataset 테이블 수정, 모델학습 설정 dto 추가' (#11) from feat/training_260202 into develop
Reviewed-on: #11
2026-02-04 12:25:19 +09:00
50464c1aa8 Merge pull request 'feat/training_260202' (#10) from feat/training_260202 into develop
Reviewed-on: #10
2026-02-03 18:52:24 +09:00
5dfcd3d181 Merge pull request '하이퍼파라미터 , 모델관리 수정' (#9) from feat/training_260202 into develop
Reviewed-on: #9
2026-02-03 18:25:13 +09:00
38b037da31 Merge pull request 'feat/training_260202' (#8) from feat/training_260202 into develop
Reviewed-on: #8
2026-02-03 16:32:02 +09:00
53c8e1dd50 Merge pull request 'feat/training_260202' (#7) from feat/training_260202 into develop
Reviewed-on: #7
2026-02-03 15:09:29 +09:00
d6f16544e2 Merge pull request '하이퍼파라미터 기능 추가' (#6) from feat/training_260202 into develop
Reviewed-on: #6
2026-02-03 14:39:27 +09:00
77912b7081 Merge pull request '하이퍼파라미터 기능 추가' (#5) from feat/training_260202 into develop
Reviewed-on: #5
2026-02-03 14:32:31 +09:00
25d4cbf672 Merge pull request 'feat/training_260202' (#4) from feat/training_260202 into develop
Reviewed-on: #4
2026-02-02 20:20:37 +09:00
210306151b Merge pull request 'feat/training_260202' (#3) from feat/training_260202 into develop
Reviewed-on: #3
2026-02-02 19:32:22 +09:00
4b64b03e53 Merge pull request 'upload 수정' (#2) from feat/training_260202 into develop
Reviewed-on: #2
2026-02-02 17:53:29 +09:00
37f8d728fa Merge pull request 'init spotless 적용' (#1) from feat/training_260202 into develop
Reviewed-on: #1
2026-02-02 15:49:14 +09:00
14 changed files with 285 additions and 116 deletions

View File

@@ -3,6 +3,7 @@ plugins {
id 'org.springframework.boot' version '3.5.7' id 'org.springframework.boot' version '3.5.7'
id 'io.spring.dependency-management' version '1.1.7' id 'io.spring.dependency-management' version '1.1.7'
id 'com.diffplug.spotless' version '6.25.0' id 'com.diffplug.spotless' version '6.25.0'
id 'idea'
} }
group = 'com.kamco.cd' group = 'com.kamco.cd'
@@ -21,11 +22,23 @@ configurations {
} }
} }
// QueryDSL 생성된 소스 디렉토리 정의
def generatedSourcesDir = file("$buildDir/generated/sources/annotationProcessor/java/main")
repositories { repositories {
mavenCentral() mavenCentral()
maven { url "https://repo.osgeo.org/repository/release/" } maven { url "https://repo.osgeo.org/repository/release/" }
} }
// Gradle이 생성된 소스를 컴파일 경로에 포함하도록 설정
sourceSets {
main {
java {
srcDirs += generatedSourcesDir
}
}
}
dependencies { dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
@@ -87,6 +100,21 @@ dependencies {
implementation 'org.apache.commons:commons-csv:1.10.0' implementation 'org.apache.commons:commons-csv:1.10.0'
} }
// IntelliJ가 생성된 소스를 인식하도록 설정
idea {
module {
// 소스 디렉토리로 인식
sourceDirs += generatedSourcesDir
// Generated Sources Root로 마킹 (IntelliJ에서 특별 처리)
generatedSourceDirs += generatedSourcesDir
// 소스 및 Javadoc 다운로드
downloadJavadoc = true
downloadSources = true
}
}
configurations.configureEach { configurations.configureEach {
exclude group: 'javax.media', module: 'jai_core' exclude group: 'javax.media', module: 'jai_core'
} }
@@ -95,6 +123,21 @@ tasks.named('test') {
useJUnitPlatform() useJUnitPlatform()
} }
// 컴파일 전 생성된 소스 디렉토리 생성 보장
tasks.named('compileJava') {
doFirst {
generatedSourcesDir.mkdirs()
}
}
// 생성된 소스 정리 태스크
tasks.register('cleanGeneratedSources', Delete) {
delete generatedSourcesDir
}
tasks.named('clean') {
dependsOn 'cleanGeneratedSources'
}
bootJar { bootJar {
archiveFileName = 'ROOT.jar' archiveFileName = 'ROOT.jar'

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.training.common.dto; package com.kamco.cd.training.common.dto;
import com.kamco.cd.training.common.enums.ModelType;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@@ -14,6 +15,10 @@ public class HyperParam {
// ------------------------- // -------------------------
// Important // Important
// ------------------------- // -------------------------
@Schema(description = "모델", example = "large")
private ModelType model; // backbone
@Schema(description = "백본 네트워크", example = "large") @Schema(description = "백본 네트워크", example = "large")
private String backbone; // backbone private String backbone; // backbone

View File

@@ -2,6 +2,7 @@ package com.kamco.cd.training.common.enums;
import com.kamco.cd.training.common.utils.enums.CodeExpose; import com.kamco.cd.training.common.utils.enums.CodeExpose;
import com.kamco.cd.training.common.utils.enums.EnumType; import com.kamco.cd.training.common.utils.enums.EnumType;
import java.util.Arrays;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@@ -15,6 +16,13 @@ public enum ModelType implements EnumType {
private String desc; private String desc;
public static ModelType getValueData(String modelNo) {
return Arrays.stream(ModelType.values())
.filter(m -> m.getId().equals(modelNo))
.findFirst()
.orElse(G1);
}
@Override @Override
public String getId() { public String getId() {
return name(); return name();

View File

@@ -1,6 +1,7 @@
package com.kamco.cd.training.hyperparam; package com.kamco.cd.training.hyperparam;
import com.kamco.cd.training.common.dto.HyperParam; import com.kamco.cd.training.common.dto.HyperParam;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.config.api.ApiResponseDto; import com.kamco.cd.training.config.api.ApiResponseDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.List; import com.kamco.cd.training.hyperparam.dto.HyperParamDto.List;
@@ -65,7 +66,7 @@ public class HyperParamApiController {
mediaType = "application/json", mediaType = "application/json",
schema = @Schema(implementation = String.class))), schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content), @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
@ApiResponse(responseCode = "422", description = "HPs_0001 수정 불가", content = @Content), @ApiResponse(responseCode = "422", description = "default는 삭제불가", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@PutMapping("/{uuid}") @PutMapping("/{uuid}")
@@ -98,8 +99,11 @@ public class HyperParamApiController {
LocalDate startDate, LocalDate startDate,
@Parameter(description = "종료일", example = "2026-02-28") @RequestParam(required = false) @Parameter(description = "종료일", example = "2026-02-28") @RequestParam(required = false)
LocalDate endDate, LocalDate endDate,
@Parameter(description = "버전명", example = "HPs_0001") @RequestParam(required = false) @Parameter(description = "버전명", example = "G_000001") @RequestParam(required = false)
String hyperVer, String hyperVer,
@Parameter(description = "모델 타입 (G1, G2, G3 중 하나)", example = "G1")
@RequestParam(required = false)
ModelType model,
@Parameter( @Parameter(
description = "정렬", description = "정렬",
example = "createdDttm desc", example = "createdDttm desc",
@@ -124,7 +128,7 @@ public class HyperParamApiController {
searchReq.setSort(sort); searchReq.setSort(sort);
searchReq.setPage(page); searchReq.setPage(page);
searchReq.setSize(size); searchReq.setSize(size);
Page<List> list = hyperParamService.getHyperParamList(searchReq); Page<List> list = hyperParamService.getHyperParamList(model, searchReq);
return ApiResponseDto.ok(list); return ApiResponseDto.ok(list);
} }
@@ -133,7 +137,7 @@ public class HyperParamApiController {
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content), @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
@ApiResponse(responseCode = "422", description = "HPs_0001 삭제 불가", content = @Content), @ApiResponse(responseCode = "422", description = "default 삭제 불가", content = @Content),
@ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
}) })
@DeleteMapping("/{uuid}") @DeleteMapping("/{uuid}")
@@ -179,8 +183,9 @@ public class HyperParamApiController {
@ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content), @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
}) })
@GetMapping("/init") @GetMapping("/init/{model}")
public ApiResponseDto<HyperParamDto.Basic> getInitHyperParam() { public ApiResponseDto<HyperParamDto.Basic> getInitHyperParam(@PathVariable ModelType model) {
return ApiResponseDto.ok(hyperParamService.getInitHyperParam());
return ApiResponseDto.ok(hyperParamService.getInitHyperParam(model));
} }
} }

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.training.hyperparam.dto; package com.kamco.cd.training.hyperparam.dto;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.common.utils.enums.CodeExpose; import com.kamco.cd.training.common.utils.enums.CodeExpose;
import com.kamco.cd.training.common.utils.enums.EnumType; import com.kamco.cd.training.common.utils.enums.EnumType;
import com.kamco.cd.training.common.utils.interfaces.JsonFormatDttm; import com.kamco.cd.training.common.utils.interfaces.JsonFormatDttm;
@@ -24,6 +25,7 @@ public class HyperParamDto {
@AllArgsConstructor @AllArgsConstructor
public static class Basic { public static class Basic {
private ModelType model; // 20250212 modeltype추가
private UUID uuid; private UUID uuid;
private String hyperVer; private String hyperVer;
@JsonFormatDttm private ZonedDateTime createdDttm; @JsonFormatDttm private ZonedDateTime createdDttm;
@@ -98,6 +100,8 @@ public class HyperParamDto {
private Integer gpuCnt; private Integer gpuCnt;
private String gpuIds; private String gpuIds;
private Integer masterPort; private Integer masterPort;
private Boolean isDefault;
} }
@Getter @Getter
@@ -106,9 +110,11 @@ public class HyperParamDto {
@AllArgsConstructor @AllArgsConstructor
public static class List { public static class List {
private UUID uuid; private UUID uuid;
private ModelType model;
private String hyperVer; private String hyperVer;
@JsonFormatDttm private ZonedDateTime createDttm; @JsonFormatDttm private ZonedDateTime createDttm;
@JsonFormatDttm private ZonedDateTime lastUsedDttm; @JsonFormatDttm private ZonedDateTime lastUsedDttm;
private String memo;
private Long m1UseCnt; private Long m1UseCnt;
private Long m2UseCnt; private Long m2UseCnt;
private Long m3UseCnt; private Long m3UseCnt;

View File

@@ -1,8 +1,10 @@
package com.kamco.cd.training.hyperparam.service; package com.kamco.cd.training.hyperparam.service;
import com.kamco.cd.training.common.dto.HyperParam; import com.kamco.cd.training.common.dto.HyperParam;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.List; import com.kamco.cd.training.hyperparam.dto.HyperParamDto.List;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.SearchReq;
import com.kamco.cd.training.postgres.core.HyperParamCoreService; import com.kamco.cd.training.postgres.core.HyperParamCoreService;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -20,11 +22,12 @@ public class HyperParamService {
/** /**
* 하이퍼 파라미터 목록 조회 * 하이퍼 파라미터 목록 조회
* *
* @param model
* @param req * @param req
* @return 목록 * @return 목록
*/ */
public Page<List> getHyperParamList(HyperParamDto.SearchReq req) { public Page<List> getHyperParamList(ModelType model, SearchReq req) {
return hyperParamCoreService.findByHyperVerList(req); return hyperParamCoreService.findByHyperVerList(model, req);
} }
/** /**
@@ -59,8 +62,8 @@ public class HyperParamService {
} }
/** 하이퍼파라미터 최적화 설정값 조회 */ /** 하이퍼파라미터 최적화 설정값 조회 */
public HyperParamDto.Basic getInitHyperParam() { public HyperParamDto.Basic getInitHyperParam(ModelType model) {
return hyperParamCoreService.getInitHyperParam(); return hyperParamCoreService.getInitHyperParam(model);
} }
/** /**

View File

@@ -74,7 +74,7 @@ public class ModelTrainMngApiController {
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content), @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
@ApiResponse(responseCode = "409", description = "HPs_0001 삭제 불가", content = @Content) @ApiResponse(responseCode = "409", description = "G1_000001 삭제 불가", content = @Content)
}) })
@DeleteMapping("/{uuid}") @DeleteMapping("/{uuid}")
public ApiResponseDto<Void> deleteModelTrain( public ApiResponseDto<Void> deleteModelTrain(

View File

@@ -1,10 +1,12 @@
package com.kamco.cd.training.postgres.core; package com.kamco.cd.training.postgres.core;
import com.kamco.cd.training.common.dto.HyperParam; import com.kamco.cd.training.common.dto.HyperParam;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.common.exception.CustomApiException; import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.common.utils.UserUtil; import com.kamco.cd.training.common.utils.UserUtil;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.Basic; import com.kamco.cd.training.hyperparam.dto.HyperParamDto.Basic;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.SearchReq;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity; import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import com.kamco.cd.training.postgres.repository.hyperparam.HyperParamRepository; import com.kamco.cd.training.postgres.repository.hyperparam.HyperParamRepository;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
@@ -17,6 +19,7 @@ import org.springframework.stereotype.Service;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class HyperParamCoreService { public class HyperParamCoreService {
private final HyperParamRepository hyperParamRepository; private final HyperParamRepository hyperParamRepository;
private final UserUtil userUtil; private final UserUtil userUtil;
@@ -27,7 +30,7 @@ public class HyperParamCoreService {
* @return 등록된 버전명 * @return 등록된 버전명
*/ */
public Basic createHyperParam(HyperParam createReq) { public Basic createHyperParam(HyperParam createReq) {
String firstVersion = getFirstHyperParamVersion(); String firstVersion = getFirstHyperParamVersion(createReq.getModel());
ModelHyperParamEntity entity = new ModelHyperParamEntity(); ModelHyperParamEntity entity = new ModelHyperParamEntity();
entity.setHyperVer(firstVersion); entity.setHyperVer(firstVersion);
@@ -57,7 +60,7 @@ public class HyperParamCoreService {
.findHyperParamByUuid(uuid) .findHyperParamByUuid(uuid)
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND)); .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
if (entity.getHyperVer().equals("HPs_0001")) { if (entity.getIsDefault()) {
throw new CustomApiException("UNPROCESSABLE_ENTITY_UPDATE", HttpStatus.UNPROCESSABLE_ENTITY); throw new CustomApiException("UNPROCESSABLE_ENTITY_UPDATE", HttpStatus.UNPROCESSABLE_ENTITY);
} }
applyHyperParam(entity, createReq); applyHyperParam(entity, createReq);
@@ -69,11 +72,112 @@ public class HyperParamCoreService {
return entity.getHyperVer(); return entity.getHyperVer();
} }
/**
* 하이퍼파라미터 삭제
*
* @param uuid
*/
public void deleteHyperParam(UUID uuid) {
ModelHyperParamEntity entity =
hyperParamRepository
.findHyperParamByUuid(uuid)
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
// if (entity.getHyperVer().equals("HPs_0001")) {
// throw new CustomApiException("UNPROCESSABLE_ENTITY", HttpStatus.UNPROCESSABLE_ENTITY);
// }
// 디폴트면 삭제불가
if (entity.getIsDefault()) {
throw new CustomApiException("UNPROCESSABLE_ENTITY", HttpStatus.UNPROCESSABLE_ENTITY);
}
entity.setDelYn(true);
entity.setUpdatedUid(userUtil.getId());
entity.setUpdatedDttm(ZonedDateTime.now());
}
/**
* 하이퍼파라미터 최적화 설정값 조회
*
* @return
*/
public HyperParamDto.Basic getInitHyperParam(ModelType model) {
ModelHyperParamEntity entity =
hyperParamRepository.getHyperparamByType(model).stream()
.filter(e -> e.getIsDefault() == Boolean.TRUE)
.findFirst()
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
return entity.toDto();
}
/**
* 하이퍼파라미터 상세 조회
*
* @return
*/
public HyperParamDto.Basic getHyperParam(UUID uuid) {
ModelHyperParamEntity entity =
hyperParamRepository
.findHyperParamByUuid(uuid)
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
return entity.toDto();
}
/**
* 하이퍼파라미터 목록 조회
*
* @param model
* @param req
* @return
*/
public Page<HyperParamDto.List> findByHyperVerList(ModelType model, SearchReq req) {
return hyperParamRepository.findByHyperVerList(model, req);
}
/**
* 하이퍼파라미터 버전 조회
*
* @param model 모델 타입
* @return ver
*/
public String getFirstHyperParamVersion(ModelType model) {
return hyperParamRepository
.findHyperParamVerByModelType(model)
.map(ModelHyperParamEntity::getHyperVer)
.map(ver -> increase(ver, model))
.orElse(model.name() + "_000001");
}
/**
* 하이퍼 파라미터의 버전을 증가시킨다.
*
* @param hyperVer 현재 버전
* @param modelType 모델 타입
* @return 증가된 버전
*/
private String increase(String hyperVer, ModelType modelType) {
String prefix = modelType.name() + "_";
int num = Integer.parseInt(hyperVer.substring(prefix.length()));
return prefix + String.format("%06d", num + 1);
}
private void applyHyperParam(ModelHyperParamEntity entity, HyperParam src) { private void applyHyperParam(ModelHyperParamEntity entity, HyperParam src) {
ModelType model = src.getModel();
// 하드코딩 모델별로 다른경우 250212 bbn 하드코딩
if (model == ModelType.G3) {
entity.setCropSize("512,512");
} else {
entity.setCropSize("256,256");
}
// entity.setCropSize(src.getCropSize());
// Important // Important
entity.setModelType(model); // 20250212 modeltype추가
entity.setBackbone(src.getBackbone()); entity.setBackbone(src.getBackbone());
entity.setInputSize(src.getInputSize()); entity.setInputSize(src.getInputSize());
entity.setCropSize(src.getCropSize());
entity.setBatchSize(src.getBatchSize()); entity.setBatchSize(src.getBatchSize());
// Data // Data
@@ -110,79 +214,4 @@ public class HyperParamCoreService {
// memo // memo
entity.setMemo(src.getMemo()); entity.setMemo(src.getMemo());
} }
/**
* 하이퍼파라미터 삭제
*
* @param uuid
*/
public void deleteHyperParam(UUID uuid) {
ModelHyperParamEntity entity =
hyperParamRepository
.findHyperParamByUuid(uuid)
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
if (entity.getHyperVer().equals("HPs_0001")) {
throw new CustomApiException("UNPROCESSABLE_ENTITY", HttpStatus.UNPROCESSABLE_ENTITY);
}
entity.setDelYn(true);
entity.setUpdatedUid(userUtil.getId());
entity.setUpdatedDttm(ZonedDateTime.now());
}
/**
* 하이퍼파라미터 최적화 설정값 조회
*
* @return
*/
public HyperParamDto.Basic getInitHyperParam() {
ModelHyperParamEntity entity =
hyperParamRepository
.findHyperParamByHyperVer("HPs_0001")
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
return entity.toDto();
}
/**
* 하이퍼파라미터 상세 조회
*
* @return
*/
public HyperParamDto.Basic getHyperParam(UUID uuid) {
ModelHyperParamEntity entity =
hyperParamRepository
.findHyperParamByUuid(uuid)
.orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
return entity.toDto();
}
/**
* 하이퍼파라미터 목록 조회
*
* @param req
* @return
*/
public Page<HyperParamDto.List> findByHyperVerList(HyperParamDto.SearchReq req) {
return hyperParamRepository.findByHyperVerList(req);
}
/**
* 하이퍼파라미터 버전 조회
*
* @return ver
*/
public String getFirstHyperParamVersion() {
return hyperParamRepository
.findHyperParamVer()
.map(ModelHyperParamEntity::getHyperVer)
.map(this::increase)
.orElse("HPs_0001");
}
private String increase(String hyperVer) {
String prefix = "HPs_";
int num = Integer.parseInt(hyperVer.substring(prefix.length()));
return prefix + String.format("%04d", num + 1);
}
} }

View File

@@ -83,9 +83,15 @@ public class ModelTrainMngCoreService {
ModelMasterEntity entity = new ModelMasterEntity(); ModelMasterEntity entity = new ModelMasterEntity();
ModelHyperParamEntity hyperParamEntity = new ModelHyperParamEntity(); ModelHyperParamEntity hyperParamEntity = new ModelHyperParamEntity();
// 최적화 파라미터는 HPs_0001 사용 // 최적화 파라미터는 모델 type의 디폴트사용
if (HyperParamSelectType.OPTIMIZED.getId().equals(addReq.getHyperParamType())) { if (HyperParamSelectType.OPTIMIZED.getId().equals(addReq.getHyperParamType())) {
hyperParamEntity = hyperParamRepository.findByHyperVer("HPs_0001").orElse(null); ModelType modelType = ModelType.getValueData(addReq.getModelNo());
hyperParamEntity =
hyperParamRepository.getHyperparamByType(modelType).stream()
.filter(e -> e.getIsDefault() == Boolean.TRUE)
.findFirst()
.orElse(null);
// hyperParamEntity = hyperParamRepository.findByHyperVer("HPs_0001").orElse(null);
} else { } else {
hyperParamEntity = hyperParamEntity =

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.training.postgres.entity; package com.kamco.cd.training.postgres.entity;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@@ -311,8 +312,16 @@ public class ModelHyperParamEntity {
@Column(name = "m3_use_cnt") @Column(name = "m3_use_cnt")
private Long m3UseCnt = 0L; private Long m3UseCnt = 0L;
@Column(name = "model_type")
@Enumerated(EnumType.STRING)
private ModelType modelType;
@Column(name = "default_param")
private Boolean isDefault = false;
public HyperParamDto.Basic toDto() { public HyperParamDto.Basic toDto() {
return new HyperParamDto.Basic( return new HyperParamDto.Basic(
this.modelType,
this.uuid, this.uuid,
this.hyperVer, this.hyperVer,
this.createdDttm, this.createdDttm,
@@ -385,6 +394,7 @@ public class ModelHyperParamEntity {
// ------------------------- // -------------------------
this.gpuCnt, this.gpuCnt,
this.gpuIds, this.gpuIds,
this.masterPort); this.masterPort,
this.isDefault);
} }
} }

View File

@@ -1,7 +1,10 @@
package com.kamco.cd.training.postgres.repository.hyperparam; package com.kamco.cd.training.postgres.repository.hyperparam;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.SearchReq;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity; import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -13,11 +16,22 @@ public interface HyperParamRepositoryCustom {
* *
* @return * @return
*/ */
@Deprecated
Optional<ModelHyperParamEntity> findHyperParamVer(); Optional<ModelHyperParamEntity> findHyperParamVer();
/**
* 모델 타입별 마지막 버전 조회
*
* @param modelType 모델 타입
* @return
*/
Optional<ModelHyperParamEntity> findHyperParamVerByModelType(ModelType modelType);
Optional<ModelHyperParamEntity> findHyperParamByHyperVer(String hyperVer); Optional<ModelHyperParamEntity> findHyperParamByHyperVer(String hyperVer);
Optional<ModelHyperParamEntity> findHyperParamByUuid(UUID uuid); Optional<ModelHyperParamEntity> findHyperParamByUuid(UUID uuid);
Page<HyperParamDto.List> findByHyperVerList(HyperParamDto.SearchReq req); Page<HyperParamDto.List> findByHyperVerList(ModelType model, SearchReq req);
List<ModelHyperParamEntity> getHyperparamByType(ModelType modelType);
} }

View File

@@ -2,8 +2,10 @@ package com.kamco.cd.training.postgres.repository.hyperparam;
import static com.kamco.cd.training.postgres.entity.QModelHyperParamEntity.modelHyperParamEntity; import static com.kamco.cd.training.postgres.entity.QModelHyperParamEntity.modelHyperParamEntity;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto; import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.HyperType; import com.kamco.cd.training.hyperparam.dto.HyperParamDto.HyperType;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.SearchReq;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity; import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections; import com.querydsl.core.types.Projections;
@@ -41,6 +43,23 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
.fetchOne()); .fetchOne());
} }
@Override
public Optional<ModelHyperParamEntity> findHyperParamVerByModelType(ModelType modelType) {
return Optional.ofNullable(
queryFactory
.select(modelHyperParamEntity)
.from(modelHyperParamEntity)
.where(
modelHyperParamEntity
.delYn
.isFalse()
.and(modelHyperParamEntity.modelType.eq(modelType)))
.orderBy(modelHyperParamEntity.hyperVer.desc())
.limit(1)
.fetchOne());
}
@Override @Override
public Optional<ModelHyperParamEntity> findHyperParamByHyperVer(String hyperVer) { public Optional<ModelHyperParamEntity> findHyperParamByHyperVer(String hyperVer) {
@@ -68,10 +87,13 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
} }
@Override @Override
public Page<HyperParamDto.List> findByHyperVerList(HyperParamDto.SearchReq req) { public Page<HyperParamDto.List> findByHyperVerList(ModelType model, SearchReq req) {
Pageable pageable = req.toPageable(); Pageable pageable = req.toPageable();
BooleanBuilder builder = new BooleanBuilder(); BooleanBuilder builder = new BooleanBuilder();
if (model != null) {
builder.and(modelHyperParamEntity.modelType.eq(model));
}
builder.and(modelHyperParamEntity.delYn.isFalse()); builder.and(modelHyperParamEntity.delYn.isFalse());
if (req.getHyperVer() != null && !req.getHyperVer().isEmpty()) { if (req.getHyperVer() != null && !req.getHyperVer().isEmpty()) {
@@ -109,9 +131,11 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
Projections.constructor( Projections.constructor(
HyperParamDto.List.class, HyperParamDto.List.class,
modelHyperParamEntity.uuid, modelHyperParamEntity.uuid,
modelHyperParamEntity.modelType.as("model"),
modelHyperParamEntity.hyperVer, modelHyperParamEntity.hyperVer,
modelHyperParamEntity.createdDttm, modelHyperParamEntity.createdDttm,
modelHyperParamEntity.lastUsedDttm, modelHyperParamEntity.lastUsedDttm,
modelHyperParamEntity.memo,
modelHyperParamEntity.m1UseCnt, modelHyperParamEntity.m1UseCnt,
modelHyperParamEntity.m2UseCnt, modelHyperParamEntity.m2UseCnt,
modelHyperParamEntity.m3UseCnt, modelHyperParamEntity.m3UseCnt,
@@ -161,4 +185,17 @@ public class HyperParamRepositoryImpl implements HyperParamRepositoryCustom {
return new PageImpl<>(content, pageable, totalCount); return new PageImpl<>(content, pageable, totalCount);
} }
@Override
public List<ModelHyperParamEntity> getHyperparamByType(ModelType modelType) {
return queryFactory
.select(modelHyperParamEntity)
.from(modelHyperParamEntity)
.where(
modelHyperParamEntity
.delYn
.isFalse()
.and(modelHyperParamEntity.modelType.eq(modelType)))
.fetch();
}
} }

View File

@@ -4,7 +4,7 @@ spring:
on-profile: prod on-profile: prod
jpa: jpa:
show-sql: false show-sql: true
hibernate: hibernate:
ddl-auto: validate ddl-auto: validate
properties: properties:
@@ -12,41 +12,40 @@ spring:
default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지 default_batch_fetch_size: 100 # ✅ 성능 - N+1 쿼리 방지
order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지 order_updates: true # ✅ 성능 - 업데이트 순서 정렬로 데드락 방지
use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용) use_sql_comments: true # ⚠️ 선택 - SQL에 주석 추가 (디버깅용)
format_sql: true # ⚠️ 선택 - SQL 포맷팅 (가독성)
datasource: datasource:
url: jdbc:postgresql://10.100.0.10:25432/temp url: jdbc:postgresql://127.0.01:15432/kamco_training_db
username: temp # url: jdbc:postgresql://localhost:15432/kamco_training_db
password: temp123! username: kamco_training_user
password: kamco_training_user_2025_!@#
hikari: hikari:
minimum-idle: 10 minimum-idle: 10
maximum-pool-size: 20 maximum-pool-size: 20
connection-timeout: 60000 # 60초 연결 타임아웃
idle-timeout: 300000 # 5분 유휴 타임아웃
max-lifetime: 1800000 # 30분 최대 수명
leak-detection-threshold: 60000 # 연결 누수 감지
transaction:
default-timeout: 300 # 5분 트랜잭션 타임아웃
jwt: jwt:
secret: "kamco_token_prod_dfc6446d-68fc-4eba-a2ff-c80a14a0bf3a" secret: "kamco_token_dev_dfc6446d-68fc-4eba-a2ff-c80a14a0bf3a"
access-token-validity-in-ms: 86400000 # 1일 access-token-validity-in-ms: 86400000 # 1일
refresh-token-validity-in-ms: 604800000 # 7일 refresh-token-validity-in-ms: 604800000 # 7일
token: token:
refresh-cookie-name: kamco # 개발용 쿠키 이름 refresh-cookie-name: kamco # 개발용 쿠키 이름
refresh-cookie-secure: true # 로컬 http 테스트면 false refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
member: member:
init_password: kamco1234! init_password: kamco1234!
swagger:
local-port: 9080
file:
sync-root-dir: /app/original-images/
sync-tmp-dir: ${file.sync-root-dir}tmp/
sync-file-extention: tfw,tif
dataset-dir: /home/kcomu/data/request/
dataset-tmp-dir: ${file.dataset-dir}tmp/
pt-path: /home/kcomu/data/response/v6-cls-checkpoints/
pt-FileName: yolov8_6th-6m.pt
train: train:
docker: docker:
image: "kamco-cd-train:latest" image: "kamco-cd-train:latest"

View File

@@ -9667,7 +9667,7 @@ INSERT INTO public.tb_audit_log VALUES (1813, 3, 'CREATE', 'SUCCESS', 'SYSTEM',
INSERT INTO public.tb_audit_log VALUES (1814, 3, 'READ', 'SUCCESS', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:44:49.832926+00', NULL, '', '/api/models/train'); INSERT INTO public.tb_audit_log VALUES (1814, 3, 'READ', 'SUCCESS', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:44:49.832926+00', NULL, '', '/api/models/train');
INSERT INTO public.tb_audit_log VALUES (1815, NULL, 'CREATE', 'FAILED', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:53:40.899603+00', 467, '{ INSERT INTO public.tb_audit_log VALUES (1815, NULL, 'CREATE', 'FAILED', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:53:40.899603+00', 467, '{
"username": "1234567", "username": "1234567",
"password":"****" "password":"****"
}', '/api/auth/signin'); }', '/api/auth/signin');
INSERT INTO public.tb_audit_log VALUES (1816, NULL, 'CREATE', 'SUCCESS', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:55:27.731595+00', NULL, '{ INSERT INTO public.tb_audit_log VALUES (1816, NULL, 'CREATE', 'SUCCESS', 'SYSTEM', '127.0.0.1', NULL, '2025-12-26 00:55:27.731595+00', NULL, '{
"username": "1234567", "username": "1234567",
@@ -30396,6 +30396,8 @@ ALTER TABLE ONLY public.tb_menu
ADD CONSTRAINT fksw914diut87r7lfykekc7xm2a FOREIGN KEY (parent_menu_uid) REFERENCES public.tb_menu(menu_uid); ADD CONSTRAINT fksw914diut87r7lfykekc7xm2a FOREIGN KEY (parent_menu_uid) REFERENCES public.tb_menu(menu_uid);
-- Completed on 2025-12-26 16:11:11 KST -- Completed on 2025-12-26 16:11:11 KST
-- --
@@ -30404,3 +30406,5 @@ ALTER TABLE ONLY public.tb_menu
\unrestrict IYrUYfSgA4Fo2gubHcb84jDXfbBZEIiOZnyLtZgnMi641GaRQa5QDogarpTr7IG \unrestrict IYrUYfSgA4Fo2gubHcb84jDXfbBZEIiOZnyLtZgnMi641GaRQa5QDogarpTr7IG