[agent-pipeline] pipe-20260328055039-5mki round-1

This commit is contained in:
DDD1542
2026-03-28 15:14:38 +09:00
parent 4289c7ef91
commit 21e30e5f60
120 changed files with 2787 additions and 1695 deletions
Symlink
+1
View File
@@ -0,0 +1 @@
/Users/gbpark/agent-pipeline/test-vex
@@ -1 +0,0 @@
{"pid":10584,"round":3,"status":"running","timestamp":"2026-03-28T04:44:15.604Z","uptimeMs":1569419.41675}
@@ -1,7 +1,7 @@
{ {
"version": 1, "version": 1,
"lastUpdated": "2026-03-27T20:12:58.287Z", "lastUpdated": "2026-03-28T04:44:35.408Z",
"totalRuns": 3, "totalRuns": 4,
"patterns": [ "patterns": [
{ {
"id": "fp-zhbg8k", "id": "fp-zhbg8k",
@@ -1851,6 +1851,136 @@
"pipelineIds": [ "pipelineIds": [
"pipe-20260327153425-pn5v" "pipe-20260327153425-pn5v"
] ]
},
{
"id": "sp-jewito",
"agent": "backend",
"taskDescription": "Screen/Layout XML 포맷팅 (3+4 분리)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-ipd5bs",
"agent": "backend",
"taskDescription": "Screen/Layout XML 포맷팅 나머지 (4개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-rauju9",
"agent": "backend",
"taskDescription": "Finance/Tax XML 포맷팅 (4개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-b6r56p",
"agent": "backend",
"taskDescription": "Finance/Report XML 포맷팅 (3개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-b2s4w4",
"agent": "backend",
"taskDescription": "Logistics XML 포맷팅 1 (7개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-bjtrab",
"agent": "backend",
"taskDescription": "Logistics XML 포맷팅 2 (7개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-c0vdoi",
"agent": "backend",
"taskDescription": "Logistics XML 포맷팅 3 (7개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-e3xl7u",
"agent": "backend",
"taskDescription": "나머지 XML 포맷팅 (9개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-p8uj34",
"agent": "backend",
"taskDescription": "XML 파일명 변경 (96개)",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ls src/main/resources/mapper/ | grep -c - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
},
{
"id": "sp-2qzrp6",
"agent": "backend",
"taskDescription": "전체 빌드 검증",
"files": [],
"keyApproach": "- 에이전트: backend - 시도: 1회 - 검증 로그: - L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20 - L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa",
"occurrences": 1,
"firstSeen": "2026-03-28T04:44:35.407Z",
"lastSeen": "2026-03-28T04:44:35.407Z",
"pipelineIds": [
"pipe-20260328041806-pbum"
]
} }
] ]
} }
@@ -1,6 +1,6 @@
{ {
"id": "pipe-20260328041806-pbum", "id": "pipe-20260328041806-pbum",
"status": "running", "status": "completed",
"config": { "config": {
"maxRetries": 3, "maxRetries": 3,
"parallel": true, "parallel": true,
@@ -485,5 +485,6 @@
"failedTasks": 0, "failedTasks": 0,
"runningTasks": 0, "runningTasks": 0,
"startedAt": "2026-03-28T04:18:06.314Z", "startedAt": "2026-03-28T04:18:06.314Z",
"runDir": "/Users/gbpark/TEST-VEX/_pipeline/runs/2026-03-28_pipe-20260328041806-pbum" "runDir": "/Users/gbpark/TEST-VEX/_pipeline/runs/2026-03-28_pipe-20260328041806-pbum",
"completedAt": "2026-03-28T04:44:35.399Z"
} }
@@ -0,0 +1 @@
{"pid":10584,"round":3,"status":"completed","timestamp":"2026-03-28T04:44:35.402Z","uptimeMs":1589217.470125}
@@ -2,21 +2,21 @@
| 항목 | 값 | | 항목 | 값 |
|------|------| |------|------|
| 총 에이전트 호출 | 11회 | | 총 에이전트 호출 | 13회 |
| 총 소요 시간 | 4670초 | | 총 소요 시간 | 4780초 |
| 평균 호출 시간 | 425초 | | 평균 호출 시간 | 368초 |
## 토큰 사용량 ## 토큰 사용량
| 항목 | 값 | | 항목 | 값 |
|------|------| |------|------|
| input_tokens | 23249 | | input_tokens | 23257 |
| output_tokens | 373951 | | output_tokens | 374387 |
| cache_read_tokens | 6930735 | | cache_read_tokens | 7001778 |
| cache_write_tokens | 1218035 | | cache_write_tokens | 1222760 |
| 입력 비용 | $0.3487 | | 입력 비용 | $0.3489 |
| 출력 비용 | $28.0463 | | 출력 비용 | $28.0790 |
| 총 비용 | $28.3951 | | 총 비용 | $28.4279 |
## 호출 상세 ## 호출 상세
| 에이전트 | 라운드 | 소요(s) | 입력토큰 | 출력토큰 | 시간 | | 에이전트 | 라운드 | 소요(s) | 입력토큰 | 출력토큰 | 시간 |
@@ -32,3 +32,5 @@
| pm | 1 | 23 | 0 | 0 | 오후 1:39:10 | | pm | 1 | 23 | 0 | 0 | 오후 1:39:10 |
| backend | 2 | 101 | 12 | 5.1K | 오후 1:40:51 | | backend | 2 | 101 | 12 | 5.1K | 오후 1:40:51 |
| pm | 2 | 114 | 0 | 0 | 오후 1:42:45 | | pm | 2 | 114 | 0 | 0 | 오후 1:42:45 |
| backend | 3 | 92 | 8 | 436 | 오후 1:44:18 |
| pm | 3 | 17 | 0 | 0 | 오후 1:44:35 |
@@ -1,9 +1,9 @@
# Pipeline: pipe-20260328041806-pbum # Pipeline: pipe-20260328041806-pbum
- 시작: 2026. 3. 28. 오후 1:18:06 - 시작: 2026. 3. 28. 오후 1:18:06
- 상태: **running** - 상태: **completed**
- 현재 라운드: 3/25 - 현재 라운드: 3/25
- 경과 시간: 26분 9초 - 경과 시간: 26분 29초
- 성공: 9 / 실패: 0 / 전체: 10 - 성공: 10 / 실패: 0 / 전체: 10
## 태스크 현황 ## 태스크 현황
| 태스크 | 에이전트 | 상태 | 시도 | 검증 | | 태스크 | 에이전트 | 상태 | 시도 | 검증 |
@@ -17,13 +17,14 @@
| task-7 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V | | task-7 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V |
| task-8 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V | | task-8 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V |
| task-9 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V | | task-9 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V |
| task-10 | backend | 대기 | 0/3 | - | | task-10 | backend | 완료 | 1/3 | L2 통과: cd /Users/gbpark/TEST-V |
## PM 판단 이력 ## PM 판단 이력
- R2 [continue]: → 목표: task-9, task-10 실행 및 검증하여 파이프라인 완료. task-10(bootJar)은 이미 L2에서 빌드 성공이 확인되었으므로 빠르게 통과할 것으로 예상. - R2 [continue]: → 목표: task-9, task-10 실행 및 검증하여 파이프라인 완료. task-10(bootJar)은 이미 L2에서 빌드 성공이 확인되었으므로 빠르게 통과할 것으로 예상.
- R3 [complete]: → 목표: 모든 태스크 완료. L5 브라우저 테스트 자동 실행 대기.
## PM 마지막 판단 ## PM 마지막 판단
Round 2에서 backend 에이전트가 96개 XML Mapper 파일명을 PascalCase+Mapper.xml → camelCase.xml로 git mv를 사용해 일괄 변환 완료. 파일 내용 변경 없이 순수 rename만 수행하여 git 이력 보존됨. L1(파일명 패턴 검증) 통과, L2(bootJar 빌드) 통과. application.yml의 m Round 3에서 task-10(bootJar 빌드) 완료. backend 에이전트가 bootJar BUILD SUCCESSFUL 확인. L1(compileJava), L2(bootJar) 모두 통과. git diff를 보면 실제 코드 변경고 파이프라인 상태 파일과 incident-history(이전 라운드 범위 밖 파일 롤백 기록)만 업데이트됨. 이
--- ---
마지막 업데이트: 2026. 3. 28. 오후 1:44:15 마지막 업데이트: 2026. 3. 28. 오후 1:44:35
@@ -0,0 +1,82 @@
# Pipeline 결과 보고서
| 항목 | 값 |
|------|------|
| ID | pipe-20260328041806-pbum |
| 상태 | **completed** |
| 시작 | 2026. 3. 28. 오후 1:18:06 |
| 완료 | 2026. 3. 28. 오후 1:44:35 |
| 소요 시간 | 26분 29초 |
| 총 라운드 | 3 |
| 태스크 | 10 성공 / 0 실패 / 10 전체 |
## 태스크 상세
### [OK] Screen/Layout XML 포맷팅 (3+4 분리) (task-1)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Screen/Layout XML 포맷팅 나머지 (4개) (task-2)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Finance/Tax XML 포맷팅 (4개) (task-3)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Finance/Report XML 포맷팅 (3개) (task-4)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Logistics XML 포맷팅 1 (7개) (task-5)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Logistics XML 포맷팅 2 (7개) (task-6)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] Logistics XML 포맷팅 3 (7개) (task-7)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] 나머지 XML 포맷팅 (9개) (task-8)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] XML 파일명 변경 (96개) (task-9)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ls src/main/resources/mapper/ | grep -c
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
### [OK] 전체 빌드 검증 (task-10)
- 에이전트: backend
- 시도: 1회
- 검증 로그:
- L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
- L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
@@ -0,0 +1,22 @@
# PM 판단 - Round 3
- 시간: 2026. 3. 28. 오후 1:44:35
## 분석
Round 3에서 task-10(bootJar 빌드) 완료. backend 에이전트가 bootJar BUILD SUCCESSFUL 확인. L1(compileJava), L2(bootJar) 모두 통과. git diff를 보면 실제 코드 변경은 없고 파이프라인 상태 파일과 incident-history(이전 라운드 범위 밖 파일 롤백 기록)만 업데이트됨. 이는 task-10이 빌드 성공 확인 태스크이므로 정상적인 결과. 전체 10개 태스크 현황: task-1~8(SQL 대문자+줄띄움) 완료, task-9(XML 파일명 camelCase 변환) 완료, task-10(bootJar 성공) 완료. 모든 done_when 조건 충족, 모든 검증(L1, L2) 통과.
## 판정: **complete**
## 다음 라운드 핵심: 모든 태스크 완료. L5 브라우저 테스트 자동 실행 대기.
---
## PM 원본 응답
```
```json
{
"analysis": "Round 3에서 task-10(bootJar 빌드) 완료. backend 에이전트가 bootJar BUILD SUCCESSFUL 확인. L1(compileJava), L2(bootJar) 모두 통과. git diff를 보면 실제 코드 변경은 없고 파이프라인 상태 파일과 incident-history(이전 라운드 범위 밖 파일 롤백 기록)만 업데이트됨. 이는 task-10이 빌드 성공 확인 태스크이므로 정상적인 결과. 전체 10개 태스크 현황: task-1~8(SQL 대문자+줄띄움) 완료, task-9(XML 파일명 camelCase 변환) 완료, task-10(bootJar 성공) 완료. 모든 done_when 조건 충족, 모든 검증(L1, L2) 통과.",
"taskUpdates": [],
"newTasks": [],
"overallStatus": "complete",
"nextRoundFocus": "모든 태스크 완료. L5 브라우저 테스트 자동 실행 대기."
}
```
```
@@ -0,0 +1,261 @@
# Round 3
- 시간: 2026. 3. 28. 오후 1:44:18
## backend (성공)
### 에이전트 응답
```
task-10 완료. `./gradlew bootJar` BUILD SUCCESSFUL.
```
## 코드 변경 (git diff)
### Unstaged 변경
```
_pipeline/knowledge/incident-history.json | 866 ++++++++++++++++++++-
_pipeline/pipeline-state.json | 37 +-
.../heartbeat.json | 2 +-
.../2026-03-28_pipe-20260328041806-pbum/metrics.md | 24 +-
.../progress.md | 15 +-
.../resume-state.json | 41 +-
6 files changed, 951 insertions(+), 34 deletions(-)
```
### 새 파일
```
_pipeline/runs/2026-03-28_pipe-20260328041806-pbum/rounds/round-2-pm.md
_pipeline/runs/2026-03-28_pipe-20260328041806-pbum/rounds/round-2.md
```
### 상세 diff
```diff
diff --git a/_pipeline/knowledge/incident-history.json b/_pipeline/knowledge/incident-history.json
index 448f9f19..db889b0d 100644
--- a/_pipeline/knowledge/incident-history.json
+++ b/_pipeline/knowledge/incident-history.json
@@ -1,6 +1,6 @@
{
"version": 1,
- "lastUpdated": "2026-03-27T15:01:33.842Z",
+ "lastUpdated": "2026-03-28T04:40:51.875Z",
"incidents": [
{
"type": "out-of-scope-change",
@@ -2053,6 +2053,870 @@
"action": "rolled-back",
"id": "inc-mn914lqq-ijr6",
"timestamp": "2026-03-27T15:01:33.842Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/admin.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-9df9",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/aiAssistantProxy.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-cxc4",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/analyticsReport.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-h2dc",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/approval.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-ogli",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/auditLog.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-183g",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/auth.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-hf52",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/barcodeLabel.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-43h7",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/batch.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-ktd6",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/batchExecutionLog.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-zc4h",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/batchManagement.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-okx0",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/bom.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-70ql",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/booking.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-wery",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/buttonActionStandard.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-9to2",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/buttonDataflow.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-9bli",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/cascadingAutoFill.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-mm92",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/cascadingCondition.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-sswf",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/cascadingHierarchy.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-2niv",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/cascadingMutualExclusion.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-7z9i",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/cascadingRelation.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-pj51",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/categoryTree.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-j0ds",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/categoryValueCascading.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-3i58",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
+ "pipelineId": "pipe-20260328041806-pbum",
+ "file": "backend-spring/src/main/resources/mapper/codeMerge.xml",
+ "description": "범위 밖 파일 변경 → 자동 롤백",
+ "action": "rolled-back",
+ "id": "inc-mn9ue8bn-ibtb",
+ "timestamp": "2026-03-28T04:40:51.875Z"
+ },
+ {
+ "type": "out-of-scope-change",
... (truncated)
```
## 검증 결과
### L1 [PASS]: L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
```
L1 통과: cd backend-spring && ./gradlew compileJava 2>&1 | tail -20
```
### L2 [PASS]: L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
```
L2 통과: cd /Users/gbpark/TEST-VEX/backend-spring && ./gradlew bootJa
```
@@ -46,7 +46,7 @@ public class AdminService extends BaseService {
} }
Map<String, Object> parent = parents.get(0); Map<String, Object> parent = parents.get(0);
Object parentObjid = parent.get("objid"); Object parentObjid = parent.get("objid");
Object parentCompanyCode = parent.get("companyCode"); Object parentCompanyCode = parent.get("company_code");
Map<String, Object> childParams = new HashMap<>(); Map<String, Object> childParams = new HashMap<>();
childParams.put("parentObjid", parentObjid); childParams.put("parentObjid", parentObjid);
@@ -55,7 +55,7 @@ public class AdminService extends BaseService {
Map<String, Object> landingMenu = children.stream() Map<String, Object> landingMenu = children.stream()
.filter(m -> { .filter(m -> {
Object desc = m.get("menuDesc"); Object desc = m.get("menu_desc");
return desc != null && desc.toString().contains("[POP_LANDING]"); return desc != null && desc.toString().contains("[POP_LANDING]");
}) })
.findFirst() .findFirst()
@@ -196,10 +196,10 @@ public class AdminService extends BaseService {
if (userInfo == null) return null; if (userInfo == null) return null;
List<Map<String, Object>> depts = sqlSession.selectList("admin.selectUserDeptList", params); List<Map<String, Object>> depts = sqlSession.selectList("admin.selectUserDeptList", params);
Map<String, Object> mainDept = depts.stream() Map<String, Object> mainDept = depts.stream()
.filter(d -> Boolean.TRUE.equals(d.get("isPrimary"))) .filter(d -> Boolean.TRUE.equals(d.get("is_primary")))
.findFirst().orElse(null); .findFirst().orElse(null);
List<Map<String, Object>> subDepts = depts.stream() List<Map<String, Object>> subDepts = depts.stream()
.filter(d -> !Boolean.TRUE.equals(d.get("isPrimary"))) .filter(d -> !Boolean.TRUE.equals(d.get("is_primary")))
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put("userInfo", userInfo); result.put("userInfo", userInfo);
@@ -276,12 +276,12 @@ public class AdminService extends BaseService {
// 1. 기존 부서 목록 조회 // 1. 기존 부서 목록 조회
List<Map<String, Object>> existingDepts = sqlSession.selectList("admin.selectUserDeptList", Map.of("userId", userId)); List<Map<String, Object>> existingDepts = sqlSession.selectList("admin.selectUserDeptList", Map.of("userId", userId));
Map<String, Object> existingMain = existingDepts.stream() Map<String, Object> existingMain = existingDepts.stream()
.filter(d -> Boolean.TRUE.equals(d.get("isPrimary"))) .filter(d -> Boolean.TRUE.equals(d.get("is_primary")))
.findFirst().orElse(null); .findFirst().orElse(null);
// 2. 메인 부서 변경 시 기존 메인을 겸직으로 전환 // 2. 메인 부서 변경 시 기존 메인을 겸직으로 전환
if (mainDept != null && deptCode != null && existingMain != null) { if (mainDept != null && deptCode != null && existingMain != null) {
String existingMainCode = (String) existingMain.get("deptCode"); String existingMainCode = (String) existingMain.get("dept_code");
if (existingMainCode != null && !existingMainCode.equals(deptCode)) { if (existingMainCode != null && !existingMainCode.equals(deptCode)) {
sqlSession.update("admin.updateUserDeptNotPrimary", Map.of("userId", userId, "deptCode", existingMainCode)); sqlSession.update("admin.updateUserDeptNotPrimary", Map.of("userId", userId, "deptCode", existingMainCode));
} }
@@ -79,7 +79,7 @@ public class ApprovalService extends BaseService {
if (template == null) throw new IllegalArgumentException("결재선 템플릿을 찾을 수 없습니다."); if (template == null) throw new IllegalArgumentException("결재선 템플릿을 찾을 수 없습니다.");
Map<String, Object> stepP = new HashMap<>(); Map<String, Object> stepP = new HashMap<>();
stepP.put("templateId", template.get("templateId")); stepP.put("templateId", template.get("template_id"));
stepP.put("companyCode", params.get("companyCode")); stepP.put("companyCode", params.get("companyCode"));
template.put("steps", sqlSession.selectList("approval.selectTemplateSteps", stepP)); template.put("steps", sqlSession.selectList("approval.selectTemplateSteps", stepP));
return template; return template;
@@ -171,7 +171,7 @@ public class ApprovalService extends BaseService {
if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다."); if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다.");
Map<String, Object> lineP = new HashMap<>(); Map<String, Object> lineP = new HashMap<>();
lineP.put("requestId", request.get("requestId")); lineP.put("requestId", request.get("request_id"));
lineP.put("companyCode", params.get("companyCode")); lineP.put("companyCode", params.get("companyCode"));
request.put("lines", sqlSession.selectList("approval.selectLinesByRequestId", lineP)); request.put("lines", sqlSession.selectList("approval.selectLinesByRequestId", lineP));
return request; return request;
@@ -209,7 +209,7 @@ public class ApprovalService extends BaseService {
defP.put("companyCode", companyCode); defP.put("companyCode", companyCode);
Map<String, Object> def = sqlSession.selectOne("approval.selectDefinitionById", defP); Map<String, Object> def = sqlSession.selectOne("approval.selectDefinitionById", defP);
if (def != null) { if (def != null) {
Object allow = def.get("allowSelfApproval"); Object allow = def.get("allow_self_approval");
boolean allowed = allow == null || Boolean.TRUE.equals(allow) boolean allowed = allow == null || Boolean.TRUE.equals(allow)
|| "true".equalsIgnoreCase(allow.toString()); || "true".equalsIgnoreCase(allow.toString());
if (!allowed) if (!allowed)
@@ -314,7 +314,7 @@ public class ApprovalService extends BaseService {
reqP.put("companyCode", companyCode); reqP.put("companyCode", companyCode);
Map<String, Object> request = sqlSession.selectOne("approval.selectRequestById", reqP); Map<String, Object> request = sqlSession.selectOne("approval.selectRequestById", reqP);
if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다."); if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다.");
if (!userId.equals(String.valueOf(request.get("requesterId")))) if (!userId.equals(String.valueOf(request.get("requester_id"))))
throw new IllegalArgumentException("본인이 요청한 건만 회수할 수 있습니다."); throw new IllegalArgumentException("본인이 요청한 건만 회수할 수 있습니다.");
String status = (String) request.get("status"); String status = (String) request.get("status");
if (!List.of("requested", "in_progress", "post_pending").contains(status)) if (!List.of("requested", "in_progress", "post_pending").contains(status))
@@ -336,9 +336,9 @@ public class ApprovalService extends BaseService {
reqP.put("companyCode", companyCode); reqP.put("companyCode", companyCode);
Map<String, Object> request = sqlSession.selectOne("approval.selectRequestById", reqP); Map<String, Object> request = sqlSession.selectOne("approval.selectRequestById", reqP);
if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다."); if (request == null) throw new IllegalArgumentException("결재 요청을 찾을 수 없습니다.");
if (!"post".equals(request.get("approvalType"))) if (!"post".equals(request.get("approval_type")))
throw new IllegalArgumentException("후결 유형의 결재 요청만 후결 처리할 수 있습니다."); throw new IllegalArgumentException("후결 유형의 결재 요청만 후결 처리할 수 있습니다.");
if (Boolean.TRUE.equals(request.get("isPostApproved"))) if (Boolean.TRUE.equals(request.get("is_post_approved")))
throw new IllegalArgumentException("이미 후결 처리된 요청입니다."); throw new IllegalArgumentException("이미 후결 처리된 요청입니다.");
Number pendingNum = sqlSession.selectOne("approval.countPendingLinesForRequest", reqP); Number pendingNum = sqlSession.selectOne("approval.countPendingLinesForRequest", reqP);
@@ -378,10 +378,10 @@ public class ApprovalService extends BaseService {
if (line == null) throw new IllegalArgumentException("결재 라인을 찾을 수 없습니다."); if (line == null) throw new IllegalArgumentException("결재 라인을 찾을 수 없습니다.");
if (!"pending".equals(line.get("status"))) throw new IllegalArgumentException("대기 중인 결재만 처리할 수 있습니다."); if (!"pending".equals(line.get("status"))) throw new IllegalArgumentException("대기 중인 결재만 처리할 수 있습니다.");
String lineCC = (String) line.get("companyCode"); String lineCC = (String) line.get("company_code");
String approverId = (String) line.get("approverId"); String approverId = (String) line.get("approver_id");
long requestId = toLong(line.get("requestId")); long requestId = toLong(line.get("request_id"));
int stepOrder = toInt(line.get("stepOrder")); int stepOrder = toInt(line.get("step_order"));
String proxyFor = null; String proxyFor = null;
String proxyReasonVal = null; String proxyReasonVal = null;
@@ -416,9 +416,9 @@ public class ApprovalService extends BaseService {
Map.of("requestId", requestId, "companyCode", lineCC)); Map.of("requestId", requestId, "companyCode", lineCC));
if (reqForUpdate == null) return; if (reqForUpdate == null) return;
int totalSteps = toInt(reqForUpdate.get("totalSteps")); int totalSteps = toInt(reqForUpdate.get("total_steps"));
String stepType = (String) line.getOrDefault("stepType", "approval"); String stepType = (String) line.getOrDefault("step_type", "approval");
boolean isLegacy = isLegacyParallel(reqForUpdate.get("targetRecordData"), stepType); boolean isLegacy = isLegacyParallel(reqForUpdate.get("target_record_data"), stepType);
if ("rejected".equals(action)) { if ("rejected".equals(action)) {
Map<String, Object> rejP = new HashMap<>(); Map<String, Object> rejP = new HashMap<>();
@@ -537,7 +537,7 @@ public class ApprovalService extends BaseService {
return; return;
} }
String nextStepType = (String) nextLines.get(0).getOrDefault("stepType", "approval"); String nextStepType = (String) nextLines.get(0).getOrDefault("step_type", "approval");
if ("notification".equals(nextStepType)) { if ("notification".equals(nextStepType)) {
Map<String, Object> notifP = new HashMap<>(); Map<String, Object> notifP = new HashMap<>();
@@ -569,8 +569,8 @@ public class ApprovalService extends BaseService {
Map<String, Object> req = sqlSession.selectOne("approval.selectRequestForSync", syncP); Map<String, Object> req = sqlSession.selectOne("approval.selectRequestForSync", syncP);
if (req == null) return; if (req == null) return;
String targetTable = (String) req.get("targetTable"); String targetTable = (String) req.get("target_table");
Object targetRecordId = req.get("targetRecordId"); Object targetRecordId = req.get("target_record_id");
if (targetTable == null || targetRecordId == null if (targetTable == null || targetRecordId == null
|| "0".equals(targetRecordId.toString()) || "0".equals(targetRecordId.toString())
|| targetRecordId.toString().isBlank()) return; || targetRecordId.toString().isBlank()) return;
@@ -105,7 +105,7 @@ public class AuditLogService extends BaseService {
json, new TypeReference<Map<String, Object>>() {}); json, new TypeReference<Map<String, Object>>() {});
if (!isSuperAdmin) { if (!isSuperAdmin) {
String tableName = (String) entry.get("tableName"); String tableName = (String) entry.get("table_name");
if (tableName != null && SECURED_TABLES.contains(tableName)) { if (tableName != null && SECURED_TABLES.contains(tableName)) {
maskMapValues(changes, "before"); maskMapValues(changes, "before");
maskMapValues(changes, "after"); maskMapValues(changes, "after");
@@ -93,26 +93,27 @@ public class AuthService extends BaseService {
return result; return result;
} }
String companyCode = getStr(userInfoRow, "companyCode", null); // DB resultType="map" → 키가 DB 컬럼명 소문자(PostgreSQL)로 옴
String userType = getStr(userInfoRow, "userType", "USER"); String companyCode = getStr(userInfoRow, "company_code", null);
String userType = getStr(userInfoRow, "user_type", "USER");
// 4. 회사명 조회 // 4. 회사명 조회
String companyName = ""; String companyName = "";
if (companyCode != null) { if (companyCode != null) {
Map<String, Object> companyRow = sqlSession.selectOne("auth.selectCompanyName", Map<String, Object> companyRow = sqlSession.selectOne("auth.selectCompanyName",
Map.of("companyCode", companyCode)); Map.of("companyCode", companyCode));
companyName = companyRow != null ? getStr(companyRow, "companyName", "") : ""; companyName = companyRow != null ? getStr(companyRow, "company_name", "") : "";
} }
// 5. JWT 토큰 생성 — Node.js 동일 페이로드 구조 // 5. JWT 토큰 생성 — Node.js 동일 페이로드 구조
Map<String, Object> personBean = new HashMap<>(); Map<String, Object> personBean = new HashMap<>();
personBean.put("userId", userId); personBean.put("userId", userId);
personBean.put("userName", getStr(userInfoRow, "userName", "")); personBean.put("userName", getStr(userInfoRow, "user_name", ""));
personBean.put("deptName", getStr(userInfoRow, "deptName", "")); personBean.put("deptName", getStr(userInfoRow, "dept_name", ""));
personBean.put("companyCode", companyCode); personBean.put("companyCode", companyCode);
personBean.put("companyName", companyName); personBean.put("companyName", companyName);
personBean.put("userType", userType); personBean.put("userType", userType);
personBean.put("userTypeName", getStr(userInfoRow, "userTypeName", "일반사용자")); personBean.put("userTypeName", getStr(userInfoRow, "user_type_name", "일반사용자"));
String token = jwtTokenProvider.generateToken(personBean); String token = jwtTokenProvider.generateToken(personBean);
// 6. firstMenuPath 계산 (Node.js authController 동일 로직) // 6. firstMenuPath 계산 (Node.js authController 동일 로직)
@@ -169,8 +170,8 @@ public class AuthService extends BaseService {
// 8. 응답 data 구성 (Node.js 응답 형식 일치) // 8. 응답 data 구성 (Node.js 응답 형식 일치)
Map<String, Object> userInfo = new HashMap<>(); Map<String, Object> userInfo = new HashMap<>();
userInfo.put("userId", userId); userInfo.put("userId", userId);
userInfo.put("userName", getStr(userInfoRow, "userName", "")); userInfo.put("userName", getStr(userInfoRow, "user_name", ""));
userInfo.put("deptName", getStr(userInfoRow, "deptName", "")); userInfo.put("deptName", getStr(userInfoRow, "dept_name", ""));
userInfo.put("companyCode", companyCode); userInfo.put("companyCode", companyCode);
Map<String, Object> data = new HashMap<>(); Map<String, Object> data = new HashMap<>();
@@ -223,13 +224,13 @@ public class AuthService extends BaseService {
// 권한명 목록 조회 // 권한명 목록 조회
List<Map<String, Object>> authList = sqlSession.selectList("auth.selectUserAuth", Map.of("userId", userId)); List<Map<String, Object>> authList = sqlSession.selectList("auth.selectUserAuth", Map.of("userId", userId));
String authNames = authList.stream() String authNames = authList.stream()
.map(a -> getStr(a, "authName", "")) .map(a -> getStr(a, "auth_name", ""))
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
String companyCode = jwtCompanyCode != null ? jwtCompanyCode String companyCode = jwtCompanyCode != null ? jwtCompanyCode
: getStr(dbUser, "companyCode", null); : getStr(dbUser, "company_code", null);
String userType = jwtUserType != null ? jwtUserType String userType = jwtUserType != null ? jwtUserType
: getStr(dbUser, "userType", "USER"); : getStr(dbUser, "user_type", "USER");
// photo 변환 (byte[] → base64) // photo 변환 (byte[] → base64)
Object rawPhoto = dbUser.get("photo"); Object rawPhoto = dbUser.get("photo");
@@ -240,16 +241,16 @@ public class AuthService extends BaseService {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put("userId", userId); result.put("userId", userId);
result.put("userName", getStr(dbUser, "userName", "")); result.put("userName", getStr(dbUser, "user_name", ""));
result.put("deptName", getStr(dbUser, "deptName", "")); result.put("deptName", getStr(dbUser, "dept_name", ""));
result.put("companyCode", companyCode); result.put("companyCode", companyCode);
result.put("company_code", companyCode); result.put("company_code", companyCode);
result.put("userType", userType); result.put("userType", userType);
result.put("userTypeName", getStr(dbUser, "userTypeName", "일반사용자")); result.put("userTypeName", getStr(dbUser, "user_type_name", "일반사용자"));
result.put("email", getStr(dbUser, "email", "")); result.put("email", getStr(dbUser, "email", ""));
result.put("photo", photoStr); result.put("photo", photoStr);
result.put("locale", getStr(dbUser, "locale", "KR")); result.put("locale", getStr(dbUser, "locale", "KR"));
result.put("deptCode", dbUser.get("deptCode")); result.put("deptCode", dbUser.get("dept_code"));
result.put("authName", authNames); result.put("authName", authNames);
result.put("isAdmin", "ADMIN".equals(userType) || "wace".equals(userId) result.put("isAdmin", "ADMIN".equals(userType) || "wace".equals(userId)
|| "SUPER_ADMIN".equals(userType)); || "SUPER_ADMIN".equals(userType));
@@ -111,7 +111,7 @@ public class BatchManagementService extends BaseService {
if (batchConfig == null) throw new RuntimeException("배치 설정을 찾을 수 없습니다."); if (batchConfig == null) throw new RuntimeException("배치 설정을 찾을 수 없습니다.");
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
String batchName = str(batchConfig.getOrDefault("batchName", batchConfig.get("batch_name"))); String batchName = str(batchConfig.get("batch_name"));
log.info("배치 수동 실행: id={}, name={}", id, batchName); log.info("배치 수동 실행: id={}, name={}", id, batchName);
long duration = System.currentTimeMillis() - startTime; long duration = System.currentTimeMillis() - startTime;
@@ -77,9 +77,9 @@ public class BatchService extends BaseService {
for (Map<String, Object> conn : externalConns) { for (Map<String, Object> conn : externalConns) {
Map<String, Object> item = new LinkedHashMap<>(); Map<String, Object> item = new LinkedHashMap<>();
item.put("id", conn.get("id")); item.put("id", conn.get("id"));
item.put("name", conn.get("connectionName") != null ? conn.get("connectionName") : conn.get("connection_name")); item.put("name", conn.get("connection_name"));
item.put("type", "external"); item.put("type", "external");
item.put("dbType", conn.get("dbType") != null ? conn.get("dbType") : conn.get("db_type")); item.put("dbType", conn.get("db_type"));
result.add(item); result.add(item);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -149,14 +149,14 @@ public class ButtonActionStandardService extends BaseService {
/** /**
* JSON String → Java Object (SELECT 결과 후처리용) * JSON String → Java Object (SELECT 결과 후처리용)
* map-underscore-to-camel-case=true 이므로 결과 키는 camelCase * resultType="map"은 DB 컬럼명 그대로 snake_case 반환
*/ */
private void parseJsonFields(Map<String, Object> row) { private void parseJsonFields(Map<String, Object> row) {
for (String camelKey : List.of("validationRules", "actionConfig")) { for (String snakeKey : List.of("validation_rules", "action_config")) {
Object val = row.get(camelKey); Object val = row.get(snakeKey);
if (val instanceof String s && !s.isBlank()) { if (val instanceof String s && !s.isBlank()) {
try { try {
row.put(camelKey, objectMapper.readValue(s, Object.class)); row.put(snakeKey, objectMapper.readValue(s, Object.class));
} catch (Exception ignored) { } catch (Exception ignored) {
// 파싱 실패 시 원문 String 유지 // 파싱 실패 시 원문 String 유지
} }
@@ -78,8 +78,8 @@ public class CascadingConditionService extends BaseService {
Map<String, Object> matchedCondition = null; Map<String, Object> matchedCondition = null;
if (conditionFieldValue != null) { if (conditionFieldValue != null) {
for (Map<String, Object> cond : conditions) { for (Map<String, Object> cond : conditions) {
String operator = (String) cond.get("conditionOperator"); String operator = (String) cond.get("condition_operator");
String expectedValue = (String) cond.get("conditionValue"); String expectedValue = (String) cond.get("condition_value");
if (evaluateCondition(conditionFieldValue, operator, expectedValue)) { if (evaluateCondition(conditionFieldValue, operator, expectedValue)) {
matchedCondition = cond; matchedCondition = cond;
break; break;
@@ -88,15 +88,15 @@ public class CascadingConditionService extends BaseService {
} }
// 4. 동적 옵션 쿼리 생성 // 4. 동적 옵션 쿼리 생성
String childTable = String.valueOf(relation.get("childTable")); String childTable = String.valueOf(relation.get("child_table"));
String valueCol = String.valueOf(relation.get("childValueColumn")); String valueCol = String.valueOf(relation.get("child_value_column"));
String labelCol = String.valueOf(relation.get("childLabelColumn")); String labelCol = String.valueOf(relation.get("child_label_column"));
Object filterColObj = relation.get("childFilterColumn"); Object filterColObj = relation.get("child_filter_column");
Object orderColObj = relation.get("childOrderColumn"); Object orderColObj = relation.get("child_order_column");
String filterCol = filterColObj != null ? String.valueOf(filterColObj) : null; String filterCol = filterColObj != null ? String.valueOf(filterColObj) : null;
String orderCol = orderColObj != null ? String.valueOf(orderColObj) : null; String orderCol = orderColObj != null ? String.valueOf(orderColObj) : null;
String orderDir = relation.get("childOrderDirection") != null String orderDir = relation.get("child_order_direction") != null
? String.valueOf(relation.get("childOrderDirection")) : "ASC"; ? String.valueOf(relation.get("child_order_direction")) : "ASC";
StringBuilder sql = new StringBuilder("SELECT ") StringBuilder sql = new StringBuilder("SELECT ")
.append(valueCol).append(" as value, ") .append(valueCol).append(" as value, ")
@@ -91,9 +91,9 @@ public class CascadingRelationService extends BaseService {
throw new NoSuchElementException("연쇄 관계를 찾을 수 없습니다."); throw new NoSuchElementException("연쇄 관계를 찾을 수 없습니다.");
} }
String parentTable = (String) relation.get("parentTable"); String parentTable = (String) relation.get("parent_table");
String parentValueColumn = (String) relation.get("parentValueColumn"); String parentValueColumn = (String) relation.get("parent_value_column");
String parentLabelColumn = (String) relation.get("parentLabelColumn"); String parentLabelColumn = (String) relation.get("parent_label_column");
if (parentLabelColumn == null || parentLabelColumn.isEmpty()) { if (parentLabelColumn == null || parentLabelColumn.isEmpty()) {
parentLabelColumn = parentValueColumn; parentLabelColumn = parentValueColumn;
} }
@@ -149,12 +149,12 @@ public class CascadingRelationService extends BaseService {
throw new NoSuchElementException("연쇄 관계를 찾을 수 없습니다."); throw new NoSuchElementException("연쇄 관계를 찾을 수 없습니다.");
} }
String childTable = (String) relation.get("childTable"); String childTable = (String) relation.get("child_table");
String childFilterColumn = (String) relation.get("childFilterColumn"); String childFilterColumn = (String) relation.get("child_filter_column");
String childValueColumn = (String) relation.get("childValueColumn"); String childValueColumn = (String) relation.get("child_value_column");
String childLabelColumn = (String) relation.get("childLabelColumn"); String childLabelColumn = (String) relation.get("child_label_column");
String childOrderColumn = (String) relation.get("childOrderColumn"); String childOrderColumn = (String) relation.get("child_order_column");
String childOrderDir = (String) relation.get("childOrderDirection"); String childOrderDir = (String) relation.get("child_order_direction");
if (childOrderDir == null || childOrderDir.isEmpty()) childOrderDir = "ASC"; if (childOrderDir == null || childOrderDir.isEmpty()) childOrderDir = "ASC";
boolean hasCompanyCode = hasColumn(childTable, "company_code"); boolean hasCompanyCode = hasColumn(childTable, "company_code");
@@ -128,10 +128,10 @@ public class CategoryTreeService extends BaseService {
Map<String, Object> current = sqlSession.selectOne(NS + "getCategoryTreeInfo", currentParams); Map<String, Object> current = sqlSession.selectOne(NS + "getCategoryTreeInfo", currentParams);
if (current == null) return null; if (current == null) return null;
String currentLabel = (String) current.get("valueLabel"); String currentLabel = (String) current.get("value_label");
int currentDepth = ((Number) current.get("depth")).intValue(); int currentDepth = ((Number) current.get("depth")).intValue();
String currentPath = (String) current.get("path"); String currentPath = (String) current.get("path");
Object currentParentId = current.get("parentValueId"); Object currentParentId = current.get("parent_value_id");
String newLabel = body.containsKey("valueLabel") ? (String) body.get("valueLabel") : currentLabel; String newLabel = body.containsKey("valueLabel") ? (String) body.get("valueLabel") : currentLabel;
int newDepth = currentDepth; int newDepth = currentDepth;
@@ -233,7 +233,7 @@ public class CategoryTreeService extends BaseService {
int count = ((Number) usage.get("count")).intValue(); int count = ((Number) usage.get("count")).intValue();
Map<String, Object> res = new LinkedHashMap<>(); Map<String, Object> res = new LinkedHashMap<>();
res.put("canDelete", false); res.put("canDelete", false);
res.put("reason", "이 카테고리 값(" + value.get("valueLabel") + ")은 " + count + "건의 데이터에서 사용 중이므로 삭제할 수 없습니다."); res.put("reason", "이 카테고리 값(" + value.get("value_label") + ")은 " + count + "건의 데이터에서 사용 중이므로 삭제할 수 없습니다.");
return res; return res;
} }
@@ -267,8 +267,8 @@ public class CategoryTreeService extends BaseService {
if (inUse) { if (inUse) {
int count = ((Number) usage.get("count")).intValue(); int count = ((Number) usage.get("count")).intValue();
throw new IllegalStateException( throw new IllegalStateException(
"VALIDATION:이 카테고리 값(" + value.get("valueLabel") + ")은 " "VALIDATION:이 카테고리 값(" + value.get("value_label") + ")은 "
+ value.get("tableName") + " 테이블에서 " + count + "건의 데이터가 사용 중이므로 삭제할 수 없습니다."); + value.get("table_name") + " 테이블에서 " + count + "건의 데이터가 사용 중이므로 삭제할 수 없습니다.");
} }
// 3. 삭제 // 3. 삭제
@@ -309,12 +309,12 @@ public class CategoryTreeService extends BaseService {
for (Map<String, Object> item : flatList) { for (Map<String, Object> item : flatList) {
Map<String, Object> node = new LinkedHashMap<>(item); Map<String, Object> node = new LinkedHashMap<>(item);
node.put("children", new ArrayList<>()); node.put("children", new ArrayList<>());
map.put(item.get("valueId"), node); map.put(item.get("value_id"), node);
} }
for (Map<String, Object> item : flatList) { for (Map<String, Object> item : flatList) {
Object parentId = item.get("parentValueId"); Object parentId = item.get("parent_value_id");
Map<String, Object> node = map.get(item.get("valueId")); Map<String, Object> node = map.get(item.get("value_id"));
if (parentId != null && map.containsKey(parentId)) { if (parentId != null && map.containsKey(parentId)) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Map<String, Object>> children = List<Map<String, Object>> children =
@@ -338,15 +338,15 @@ public class CategoryTreeService extends BaseService {
List<Map<String, Object>> children = sqlSession.selectList(NS + "getCategoryTreeChildrenList", params); List<Map<String, Object>> children = sqlSession.selectList(NS + "getCategoryTreeChildrenList", params);
for (Map<String, Object> child : children) { for (Map<String, Object> child : children) {
String valueLabel = (String) child.get("valueLabel"); String valueLabel = (String) child.get("value_label");
String newPath = parentPath + "/" + valueLabel; String newPath = parentPath + "/" + valueLabel;
Map<String, Object> updateParams = new HashMap<>(); Map<String, Object> updateParams = new HashMap<>();
updateParams.put("valueId", child.get("valueId")); updateParams.put("valueId", child.get("value_id"));
updateParams.put("path", newPath); updateParams.put("path", newPath);
sqlSession.update(NS + "updateCategoryTreeChildPath", updateParams); sqlSession.update(NS + "updateCategoryTreeChildPath", updateParams);
int childId = ((Number) child.get("valueId")).intValue(); int childId = ((Number) child.get("value_id")).intValue();
updateChildrenPaths(companyCode, childId, newPath); updateChildrenPaths(companyCode, childId, newPath);
} }
} }
@@ -356,9 +356,9 @@ public class CategoryTreeService extends BaseService {
* 오류 발생 시 무시하고 삭제 허용 (Node.js 동일 동작) * 오류 발생 시 무시하고 삭제 허용 (Node.js 동일 동작)
*/ */
private Map<String, Object> checkCategoryValueInUse(String companyCode, Map<String, Object> value) { private Map<String, Object> checkCategoryValueInUse(String companyCode, Map<String, Object> value) {
String tableName = (String) value.get("tableName"); String tableName = (String) value.get("table_name");
String columnName = (String) value.get("columnName"); String columnName = (String) value.get("column_name");
String valueCode = (String) value.get("valueCode"); String valueCode = (String) value.get("value_code");
Map<String, Object> notInUse = Map.of("inUse", false, "count", 0); Map<String, Object> notInUse = Map.of("inUse", false, "count", 0);
@@ -30,11 +30,9 @@ public class CodeMergeService extends BaseService {
params.put("columnName", columnName); params.put("columnName", columnName);
List<Map<String, Object>> rows = sqlSession.selectList(NS + "getTablesWithColumn", params); List<Map<String, Object>> rows = sqlSession.selectList(NS + "getTablesWithColumn", params);
// map-underscore-to-camel-case: true 적용 → key = "tableName"
List<String> tables = rows.stream() List<String> tables = rows.stream()
.map(r -> { .map(r -> {
Object val = r.get("tableName"); Object val = r.get("table_name");
if (val == null) val = r.get("table_name");
return val != null ? val.toString() : null; return val != null ? val.toString() : null;
}) })
.filter(Objects::nonNull) .filter(Objects::nonNull)
@@ -72,8 +70,7 @@ public class CodeMergeService extends BaseService {
int totalRows = 0; int totalRows = 0;
for (Map<String, Object> tableRow : tableRows) { for (Map<String, Object> tableRow : tableRows) {
Object nameVal = tableRow.get("tableName"); Object nameVal = tableRow.get("table_name");
if (nameVal == null) nameVal = tableRow.get("table_name");
if (nameVal == null) continue; if (nameVal == null) continue;
String tableName = nameVal.toString(); String tableName = nameVal.toString();
@@ -44,7 +44,7 @@ public class CompanyManagementService extends BaseService {
throw new IllegalArgumentException("존재하지 않는 회사입니다."); throw new IllegalArgumentException("존재하지 않는 회사입니다.");
} }
String companyName = (String) existing.get("companyName"); String companyName = (String) existing.get("company_name");
// 2. 파일 정리 // 2. 파일 정리
try { try {
@@ -98,7 +98,7 @@ public class CompanyManagementService extends BaseService {
"companyManagement.selectAllCompanyCodes", new HashMap<>()); "companyManagement.selectAllCompanyCodes", new HashMap<>());
for (Map<String, Object> row : companyCodes) { for (Map<String, Object> row : companyCodes) {
String code = (String) row.get("companyCode"); String code = (String) row.get("company_code");
Path dir = Paths.get(uploadBasePath, code); Path dir = Paths.get(uploadBasePath, code);
long[] stats = calculateDirStats(dir); long[] stats = calculateDirStats(dir);
@@ -212,7 +212,7 @@ public class ComponentStandardService extends BaseService {
List<Map<String, Object>> byStatus = new ArrayList<>(); List<Map<String, Object>> byStatus = new ArrayList<>();
for (Map<String, Object> row : byStatusRaw) { for (Map<String, Object> row : byStatusRaw) {
Map<String, Object> item = new LinkedHashMap<>(); Map<String, Object> item = new LinkedHashMap<>();
item.put("status", row.get("isActive")); // camelCase (map-underscore-to-camel) item.put("status", row.get("is_active"));
item.put("count", toLong(row.get("count"))); item.put("count", toLong(row.get("count")));
byStatus.add(item); byStatus.add(item);
} }
@@ -280,17 +280,17 @@ public class DdlService extends BaseService {
Map<String, Long> byDdlType = new LinkedHashMap<>(); Map<String, Long> byDdlType = new LinkedHashMap<>();
for (Map<String, Object> row : byType) { for (Map<String, Object> row : byType) {
byDdlType.put(String.valueOf(row.get("ddlType")), toLong(row.get("count"))); byDdlType.put(String.valueOf(row.get("ddl_type")), toLong(row.get("count")));
} }
Map<String, Long> byUserMap = new LinkedHashMap<>(); Map<String, Long> byUserMap = new LinkedHashMap<>();
for (Map<String, Object> row : byUser) { for (Map<String, Object> row : byUser) {
byUserMap.put(String.valueOf(row.get("userId")), toLong(row.get("count"))); byUserMap.put(String.valueOf(row.get("user_id")), toLong(row.get("count")));
} }
return Map.of( return Map.of(
"totalExecutions", toLong(totalStats != null ? totalStats.get("totalExecutions") : null), "totalExecutions", toLong(totalStats != null ? totalStats.get("total_executions") : null),
"successfulExecutions", toLong(totalStats != null ? totalStats.get("successfulExecutions") : null), "successfulExecutions", toLong(totalStats != null ? totalStats.get("successful_executions") : null),
"failedExecutions", toLong(totalStats != null ? totalStats.get("failedExecutions") : null), "failedExecutions", toLong(totalStats != null ? totalStats.get("failed_executions") : null),
"byDDLType", byDdlType, "byDDLType", byDdlType,
"byUser", byUserMap, "byUser", byUserMap,
"recentFailures", recentFailures "recentFailures", recentFailures
@@ -24,7 +24,7 @@ public class DepartmentService extends BaseService {
// member_count를 int로 변환 // member_count를 int로 변환
for (Map<String, Object> dept : departments) { for (Map<String, Object> dept : departments) {
Object cnt = dept.get("memberCount"); Object cnt = dept.get("member_count");
if (cnt != null) { if (cnt != null) {
dept.put("memberCount", ((Number) cnt).intValue()); dept.put("memberCount", ((Number) cnt).intValue());
} else { } else {
@@ -61,13 +61,13 @@ public class DepartmentService extends BaseService {
Map<String, Object> companyParams = new HashMap<>(); Map<String, Object> companyParams = new HashMap<>();
companyParams.put("companyCode", companyCode); companyParams.put("companyCode", companyCode);
Map<String, Object> company = sqlSession.selectOne("department.selectCompanyName", companyParams); Map<String, Object> company = sqlSession.selectOne("department.selectCompanyName", companyParams);
String companyName = (company != null && company.get("companyName") != null) String companyName = (company != null && company.get("company_name") != null)
? (String) company.get("companyName") ? (String) company.get("company_name")
: companyCode; : companyCode;
// 부서 코드 생성 // 부서 코드 생성
Map<String, Object> codeResult = sqlSession.selectOne("department.selectNextDeptNumber", null); Map<String, Object> codeResult = sqlSession.selectOne("department.selectNextDeptNumber", null);
long nextNumber = codeResult != null ? ((Number) codeResult.get("nextNumber")).longValue() : 1L; long nextNumber = codeResult != null ? ((Number) codeResult.get("next_number")).longValue() : 1L;
String deptCode = "DEPT_" + nextNumber; String deptCode = "DEPT_" + nextNumber;
// 부서 생성 // 부서 생성
@@ -30,14 +30,14 @@ public class DriverService extends BaseService {
Map<String, Object> vehicle = sqlSession.selectOne("driver.getDriverVehicle", params); Map<String, Object> vehicle = sqlSession.selectOne("driver.getDriverVehicle", params);
Map<String, Object> result = new LinkedHashMap<>(); Map<String, Object> result = new LinkedHashMap<>();
result.put("userId", userInfo.get("userId")); result.put("userId", userInfo.get("user_id"));
result.put("userName", userInfo.get("userName")); result.put("userName", userInfo.get("user_name"));
result.put("phoneNumber", userInfo.get("cellPhone")); result.put("phoneNumber", userInfo.get("cell_phone"));
result.put("licenseNumber", userInfo.get("licenseNumber")); result.put("licenseNumber", userInfo.get("license_number"));
result.put("vehicleNumber", userInfo.get("vehicleNumber")); result.put("vehicleNumber", userInfo.get("vehicle_number"));
result.put("vehicleType", vehicle != null ? vehicle.get("vehicleType") : null); result.put("vehicleType", vehicle != null ? vehicle.get("vehicle_type") : null);
result.put("vehicleStatus", vehicle != null ? vehicle.get("status") : null); result.put("vehicleStatus", vehicle != null ? vehicle.get("status") : null);
result.put("branchName", userInfo.get("branchName")); result.put("branchName", userInfo.get("branch_name"));
return result; return result;
} }
@@ -69,9 +69,9 @@ public class DriverService extends BaseService {
throw new IllegalArgumentException("사용자를 찾을 수 없습니다."); throw new IllegalArgumentException("사용자를 찾을 수 없습니다.");
} }
// user_info에서 이름/전화번호 보완 // user_info에서 이름/전화번호 보완
if (params.get("userName") == null) params.put("userName", userInfo.get("userName")); if (params.get("userName") == null) params.put("userName", userInfo.get("user_name"));
if (params.get("phoneNumber") == null) params.put("phoneNumber", userInfo.get("cellPhone")); if (params.get("phoneNumber") == null) params.put("phoneNumber", userInfo.get("cell_phone"));
if (params.get("companyCode") == null) params.put("companyCode", userInfo.get("companyCode")); if (params.get("companyCode") == null) params.put("companyCode", userInfo.get("company_code"));
sqlSession.insert("driver.insertDriverVehicle", params); sqlSession.insert("driver.insertDriverVehicle", params);
@@ -129,11 +129,11 @@ public class EntityJoinService extends BaseService {
} }
for (Map<String, Object> col : entityColumns) { for (Map<String, Object> col : entityColumns) {
String columnName = (String) col.get("columnName"); String columnName = (String) col.get("column_name");
String inputType = (String) col.get("inputType"); String inputType = (String) col.get("input_type");
String refTable = (String) col.get("referenceTable"); String refTable = (String) col.get("reference_table");
String refCol = (String) col.get("referenceColumn"); String refCol = (String) col.get("reference_column");
String displayCol = (String) col.get("displayColumn"); String displayCol = (String) col.get("display_column");
if ("category".equals(inputType)) { if ("category".equals(inputType)) {
refTable = notBlank(refTable) ? refTable : "category_values"; refTable = notBlank(refTable) ? refTable : "category_values";
@@ -182,17 +182,17 @@ public class EntityJoinService extends BaseService {
List<Map<String, Object>> metaCols = sqlSession.selectList(NS + "selectColumnMetadata", metaParams); List<Map<String, Object>> metaCols = sqlSession.selectList(NS + "selectColumnMetadata", metaParams);
Map<String, Map<String, Object>> metaByCol = metaCols.stream() Map<String, Map<String, Object>> metaByCol = metaCols.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
m -> (String) m.get("columnName"), m -> (String) m.get("column_name"),
m -> m, m -> m,
(a, b) -> a)); (a, b) -> a));
List<Map<String, Object>> result = new ArrayList<>(); List<Map<String, Object>> result = new ArrayList<>();
for (Map<String, Object> col : schemaCols) { for (Map<String, Object> col : schemaCols) {
String colName = (String) col.get("columnName"); String colName = (String) col.get("column_name");
String dataType = (String) col.get("dataType"); String dataType = (String) col.get("data_type");
Map<String, Object> meta = metaByCol.getOrDefault(colName, Collections.emptyMap()); Map<String, Object> meta = metaByCol.getOrDefault(colName, Collections.emptyMap());
String label = (String) meta.getOrDefault("columnLabel", colName); String label = (String) meta.getOrDefault("column_label", colName);
String inputType = (String) meta.get("inputType"); String inputType = (String) meta.get("input_type");
Map<String, Object> item = new LinkedHashMap<>(); Map<String, Object> item = new LinkedHashMap<>();
item.put("columnName", colName); item.put("columnName", colName);
@@ -411,7 +411,7 @@ public class EntityJoinService extends BaseService {
p.put("tableName", refTable); p.put("tableName", refTable);
List<Map<String, Object>> cols = sqlSession.selectList(NS + "selectTableSchemaColumns", p); List<Map<String, Object>> cols = sqlSession.selectList(NS + "selectTableSchemaColumns", p);
List<String> colNames = cols.stream() List<String> colNames = cols.stream()
.map(c -> (String) c.get("columnName")) .map(c -> (String) c.get("column_name"))
.collect(Collectors.toList()); .collect(Collectors.toList());
return colNames.stream() return colNames.stream()
@@ -27,16 +27,16 @@ public class EntityReferenceService extends BaseService {
"컬럼 정보를 찾을 수 없습니다: " + tableName + "." + columnName); "컬럼 정보를 찾을 수 없습니다: " + tableName + "." + columnName);
} }
String inputType = (String) columnInfo.get("inputType"); String inputType = (String) columnInfo.get("input_type");
if (!"entity".equals(inputType)) { if (!"entity".equals(inputType)) {
throw new IllegalStateException( throw new IllegalStateException(
"컬럼 '" + tableName + "." + columnName + "'은 entity 타입이 아닙니다. inputType: " + inputType); "컬럼 '" + tableName + "." + columnName + "'은 entity 타입이 아닙니다. inputType: " + inputType);
} }
String referenceTable = (String) columnInfo.get("referenceTable"); String referenceTable = (String) columnInfo.get("reference_table");
String referenceColumn = (String) columnInfo.get("referenceColumn"); String referenceColumn = (String) columnInfo.get("reference_column");
String displayColumn = columnInfo.get("displayColumn") != null String displayColumn = columnInfo.get("display_column") != null
? (String) columnInfo.get("displayColumn") : "name"; ? (String) columnInfo.get("display_column") : "name";
if (referenceTable == null || referenceColumn == null) { if (referenceTable == null || referenceColumn == null) {
throw new IllegalStateException( throw new IllegalStateException(
@@ -81,8 +81,8 @@ public class EntityReferenceService extends BaseService {
List<Map<String, Object>> options = new ArrayList<>(); List<Map<String, Object>> options = new ArrayList<>();
for (Map<String, Object> row : rows) { for (Map<String, Object> row : rows) {
Object val = row.get("refValue"); Object val = row.get("ref_value");
Object disp = row.get("displayName"); Object disp = row.get("display_name");
Map<String, Object> opt = new LinkedHashMap<>(); Map<String, Object> opt = new LinkedHashMap<>();
opt.put("value", val != null ? val.toString() : ""); opt.put("value", val != null ? val.toString() : "");
opt.put("label", disp != null ? disp.toString() : (val != null ? val.toString() : "")); opt.put("label", disp != null ? disp.toString() : (val != null ? val.toString() : ""));
@@ -121,8 +121,8 @@ public class EntityReferenceService extends BaseService {
List<Map<String, Object>> options = new ArrayList<>(); List<Map<String, Object>> options = new ArrayList<>();
for (Map<String, Object> row : rows) { for (Map<String, Object> row : rows) {
Map<String, Object> opt = new LinkedHashMap<>(); Map<String, Object> opt = new LinkedHashMap<>();
opt.put("value", String.valueOf(row.get("codeValue"))); opt.put("value", String.valueOf(row.get("code_value")));
opt.put("label", String.valueOf(row.get("codeName"))); opt.put("label", String.valueOf(row.get("code_name")));
options.add(opt); options.add(opt);
} }
@@ -34,7 +34,7 @@ public class EntitySearchService extends BaseService {
p.put("tableName", tableName); p.put("tableName", tableName);
List<Map<String, Object>> rows = sqlSession.selectList(NS + "getTableColumnList", p); List<Map<String, Object>> rows = sqlSession.selectList(NS + "getTableColumnList", p);
return rows.stream() return rows.stream()
.map(r -> (String) r.get("columnName")) .map(r -> (String) r.get("column_name"))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@@ -239,8 +239,8 @@ public class EntitySearchService extends BaseService {
Map<String, Object> pkp = new HashMap<>(); Map<String, Object> pkp = new HashMap<>();
pkp.put("tableName", tableName); pkp.put("tableName", tableName);
Map<String, Object> pk = sqlSession.selectOne(NS + "getPrimaryKeyInfo", pkp); Map<String, Object> pk = sqlSession.selectOne(NS + "getPrimaryKeyInfo", pkp);
if (pk != null && pk.get("columnName") != null) { if (pk != null && pk.get("column_name") != null) {
orderByColumn = "\"" + sanitize((String) pk.get("columnName")) + "\""; orderByColumn = "\"" + sanitize((String) pk.get("column_name")) + "\"";
} }
} catch (Exception e) { } catch (Exception e) {
log.warn("PK 조회 실패 table={}", tableName); log.warn("PK 조회 실패 table={}", tableName);
@@ -384,7 +384,7 @@ public class EntitySearchService extends BaseService {
cvp.put("companyCode", companyCode); cvp.put("companyCode", companyCode);
List<Map<String, Object>> cvRows = sqlSession.selectList(NS + "getCategoryValueList", cvp); List<Map<String, Object>> cvRows = sqlSession.selectList(NS + "getCategoryValueList", cvp);
for (Map<String, Object> r : cvRows) { for (Map<String, Object> r : cvRows) {
labelMap.put((String) r.get("valueCode"), (String) r.get("valueLabel")); labelMap.put((String) r.get("value_code"), (String) r.get("value_label"));
} }
} catch (Exception e) { } catch (Exception e) {
log.debug("category_values 조회 실패 (무시): {}", e.getMessage()); log.debug("category_values 조회 실패 (무시): {}", e.getMessage());
@@ -395,7 +395,7 @@ public class EntitySearchService extends BaseService {
ttcp.put("tableName", tableName); ttcp.put("tableName", tableName);
ttcp.put("columnName", columnName); ttcp.put("columnName", columnName);
Map<String, Object> ttcRow = sqlSession.selectOne(NS + "getCodeCategoryInfo", ttcp); Map<String, Object> ttcRow = sqlSession.selectOne(NS + "getCodeCategoryInfo", ttcp);
String codeCategory = ttcRow != null ? (String) ttcRow.get("codeCategory") : null; String codeCategory = ttcRow != null ? (String) ttcRow.get("code_category") : null;
if (codeCategory != null) { if (codeCategory != null) {
Map<String, Object> cip = new HashMap<>(); Map<String, Object> cip = new HashMap<>();
@@ -404,9 +404,9 @@ public class EntitySearchService extends BaseService {
cip.put("companyCode", companyCode); cip.put("companyCode", companyCode);
List<Map<String, Object>> ciRows = sqlSession.selectList(NS + "getCodeInfoList", cip); List<Map<String, Object>> ciRows = sqlSession.selectList(NS + "getCodeInfoList", cip);
for (Map<String, Object> r : ciRows) { for (Map<String, Object> r : ciRows) {
String codeValue = (String) r.get("codeValue"); String codeValue = (String) r.get("code_value");
if (!labelMap.containsKey(codeValue)) { if (!labelMap.containsKey(codeValue)) {
labelMap.put(codeValue, (String) r.get("codeName")); labelMap.put(codeValue, (String) r.get("code_name"));
} }
} }
} }
@@ -46,9 +46,9 @@ public class ExternalCallConfigService extends BaseService {
parseConfigData(config); parseConfigData(config);
Map<String, Object> simplified = new LinkedHashMap<>(); Map<String, Object> simplified = new LinkedHashMap<>();
simplified.put("id", config.get("id") != null ? config.get("id").toString() : null); simplified.put("id", config.get("id") != null ? config.get("id").toString() : null);
simplified.put("name", config.get("configName") != null ? config.get("configName") : config.get("config_name")); simplified.put("name", config.get("config_name"));
simplified.put("description", config.get("description")); simplified.put("description", config.get("description"));
Object configData = config.get("configData") != null ? config.get("configData") : config.get("config_data"); Object configData = config.get("config_data");
if (configData instanceof Map) { if (configData instanceof Map) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, Object> cd = (Map<String, Object>) configData; Map<String, Object> cd = (Map<String, Object>) configData;
@@ -150,17 +150,15 @@ public class ExternalCallConfigService extends BaseService {
return resultMap(false, "외부 호출 설정을 찾을 수 없습니다: ID " + id); return resultMap(false, "외부 호출 설정을 찾을 수 없습니다: ID " + id);
} }
Object configDataRaw = config.get("configData") != null ? config.get("configData") : config.get("config_data"); Object configDataRaw = config.get("config_data");
if (!(configDataRaw instanceof Map)) { if (!(configDataRaw instanceof Map)) {
return resultMap(false, "config_data가 유효하지 않습니다."); return resultMap(false, "config_data가 유효하지 않습니다.");
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, Object> configData = (Map<String, Object>) configDataRaw; Map<String, Object> configData = (Map<String, Object>) configDataRaw;
String apiType = str(config, "apiType"); String apiType = str(config, "api_type");
if (apiType == null) apiType = str(config, "api_type"); String callType = str(config, "call_type");
String callType = str(config, "callType");
if (callType == null) callType = str(config, "call_type");
// Node.js와 동일한 검증 로직 // Node.js와 동일한 검증 로직
if ("discord".equals(apiType) || "slack".equals(apiType)) { if ("discord".equals(apiType) || "slack".equals(apiType)) {
@@ -196,7 +194,7 @@ public class ExternalCallConfigService extends BaseService {
return r; return r;
} }
Object configDataRaw = config.get("configData") != null ? config.get("configData") : config.get("config_data"); Object configDataRaw = config.get("config_data");
if (!(configDataRaw instanceof Map)) { if (!(configDataRaw instanceof Map)) {
Map<String, Object> r = resultMap(false, "config_data가 유효하지 않습니다."); Map<String, Object> r = resultMap(false, "config_data가 유효하지 않습니다.");
r.put("executionTime", System.currentTimeMillis() - startTime); r.put("executionTime", System.currentTimeMillis() - startTime);
@@ -248,7 +246,7 @@ public class ExternalCallConfigService extends BaseService {
Map<String, Object> result = new LinkedHashMap<>(); Map<String, Object> result = new LinkedHashMap<>();
result.put("success", success); result.put("success", success);
result.put("message", success ? "외부호출 '" + config.get("configName") + "' 실행 완료" : "외부호출 실행 실패"); result.put("message", success ? "외부호출 '" + config.get("config_name") + "' 실행 완료" : "외부호출 실행 실패");
result.put("data", responseData); result.put("data", responseData);
result.put("executionTime", executionTime); result.put("executionTime", executionTime);
return result; return result;
@@ -266,7 +264,7 @@ public class ExternalCallConfigService extends BaseService {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void parseConfigData(Map<String, Object> row) { private void parseConfigData(Map<String, Object> row) {
String key = row.containsKey("configData") ? "configData" : "config_data"; String key = "config_data";
Object raw = row.get(key); Object raw = row.get(key);
if (raw instanceof String s && !s.isBlank()) { if (raw instanceof String s && !s.isBlank()) {
try { try {
@@ -105,8 +105,7 @@ public class ExternalDbConnectionService extends BaseService {
// 카테고리 초기화 // 카테고리 초기화
Map<String, Map<String, Object>> grouped = new LinkedHashMap<>(); Map<String, Map<String, Object>> grouped = new LinkedHashMap<>();
for (Map<String, Object> cat : categories) { for (Map<String, Object> cat : categories) {
String typeCode = str(cat, "typeCode"); String typeCode = str(cat, "type_code");
if (typeCode == null) typeCode = str(cat, "type_code");
if (typeCode == null) continue; if (typeCode == null) continue;
Map<String, Object> entry = new LinkedHashMap<>(); Map<String, Object> entry = new LinkedHashMap<>();
entry.put("category", cat); entry.put("category", cat);
@@ -116,8 +115,7 @@ public class ExternalDbConnectionService extends BaseService {
// 연결을 타입 그룹에 배치 // 연결을 타입 그룹에 배치
for (Map<String, Object> conn : connections) { for (Map<String, Object> conn : connections) {
String dbType = str(conn, "dbType"); String dbType = str(conn, "db_type");
if (dbType == null) dbType = str(conn, "db_type");
if (dbType == null) continue; if (dbType == null) continue;
if (grouped.containsKey(dbType)) { if (grouped.containsKey(dbType)) {
@@ -291,8 +289,7 @@ public class ExternalDbConnectionService extends BaseService {
} }
} }
String dbType = str(conn, "dbType"); String dbType = str(conn, "db_type");
if (dbType == null) dbType = str(conn, "db_type");
return executeConnectionTest(dbType, conn, password); return executeConnectionTest(dbType, conn, password);
} }
@@ -302,12 +299,10 @@ public class ExternalDbConnectionService extends BaseService {
String host = str(conn, "host"); String host = str(conn, "host");
int port = toInt(conn, "port", 5432); int port = toInt(conn, "port", 5432);
String database = str(conn, "databaseName"); String database = str(conn, "database_name");
if (database == null) database = str(conn, "database_name");
String username = str(conn, "username"); String username = str(conn, "username");
String sslEnabled = str(conn, "sslEnabled"); String sslEnabled = str(conn, "ssl_enabled");
if (sslEnabled == null) sslEnabled = str(conn, "ssl_enabled"); int connTimeout = toInt(conn, "connection_timeout", 30);
int connTimeout = toInt(conn, "connectionTimeout", toInt(conn, "connection_timeout", 30));
if (!"postgresql".equalsIgnoreCase(dbType)) { if (!"postgresql".equalsIgnoreCase(dbType)) {
Map<String, Object> result = new LinkedHashMap<>(); Map<String, Object> result = new LinkedHashMap<>();
@@ -369,8 +364,7 @@ public class ExternalDbConnectionService extends BaseService {
throw new NoSuchElementException("연결 정보를 찾을 수 없습니다."); throw new NoSuchElementException("연결 정보를 찾을 수 없습니다.");
} }
String dbType = str(conn, "dbType"); String dbType = str(conn, "db_type");
if (dbType == null) dbType = str(conn, "db_type");
if (!"postgresql".equalsIgnoreCase(dbType)) { if (!"postgresql".equalsIgnoreCase(dbType)) {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
@@ -414,8 +408,7 @@ public class ExternalDbConnectionService extends BaseService {
throw new NoSuchElementException("연결 정보를 찾을 수 없습니다."); throw new NoSuchElementException("연결 정보를 찾을 수 없습니다.");
} }
String dbType = str(conn, "dbType"); String dbType = str(conn, "db_type");
if (dbType == null) dbType = str(conn, "db_type");
if (!"postgresql".equalsIgnoreCase(dbType)) { if (!"postgresql".equalsIgnoreCase(dbType)) {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -455,8 +448,7 @@ public class ExternalDbConnectionService extends BaseService {
throw new NoSuchElementException("연결 정보를 찾을 수 없습니다."); throw new NoSuchElementException("연결 정보를 찾을 수 없습니다.");
} }
String dbType = str(conn, "dbType"); String dbType = str(conn, "db_type");
if (dbType == null) dbType = str(conn, "db_type");
if (!"postgresql".equalsIgnoreCase(dbType)) { if (!"postgresql".equalsIgnoreCase(dbType)) {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -554,8 +546,7 @@ public class ExternalDbConnectionService extends BaseService {
private String buildJdbcUrl(Map<String, Object> conn) { private String buildJdbcUrl(Map<String, Object> conn) {
String host = str(conn, "host"); String host = str(conn, "host");
int port = toInt(conn, "port", 5432); int port = toInt(conn, "port", 5432);
String database = str(conn, "databaseName"); String database = str(conn, "database_name");
if (database == null) database = str(conn, "database_name");
return String.format("jdbc:postgresql://%s:%d/%s", host, port, database); return String.format("jdbc:postgresql://%s:%d/%s", host, port, database);
} }
@@ -564,12 +555,10 @@ public class ExternalDbConnectionService extends BaseService {
String username = str(conn, "username"); String username = str(conn, "username");
props.setProperty("user", username != null ? username : ""); props.setProperty("user", username != null ? username : "");
props.setProperty("password", password != null ? password : ""); props.setProperty("password", password != null ? password : "");
int connTimeout = toInt(conn, "connectionTimeout", int connTimeout = toInt(conn, "connection_timeout", 30);
toInt(conn, "connection_timeout", 30));
props.setProperty("connectTimeout", String.valueOf(connTimeout)); props.setProperty("connectTimeout", String.valueOf(connTimeout));
props.setProperty("socketTimeout", "60"); props.setProperty("socketTimeout", "60");
String ssl = str(conn, "sslEnabled"); String ssl = str(conn, "ssl_enabled");
if (ssl == null) ssl = str(conn, "ssl_enabled");
if ("Y".equalsIgnoreCase(ssl)) { if ("Y".equalsIgnoreCase(ssl)) {
props.setProperty("ssl", "true"); props.setProperty("ssl", "true");
props.setProperty("sslmode", "require"); props.setProperty("sslmode", "require");
@@ -580,7 +569,7 @@ public class ExternalDbConnectionService extends BaseService {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void parseConnectionOptions(Map<String, Object> conn) { private void parseConnectionOptions(Map<String, Object> conn) {
// connection_options 가 JSON 문자열이면 Map으로 파싱 // connection_options 가 JSON 문자열이면 Map으로 파싱
String key = conn.containsKey("connectionOptions") ? "connectionOptions" : "connection_options"; String key = "connection_options";
Object raw = conn.get(key); Object raw = conn.get(key);
if (raw instanceof String s && !s.isBlank()) { if (raw instanceof String s && !s.isBlank()) {
try { try {
@@ -216,19 +216,19 @@ public class ExternalRestApiConnectionService extends BaseService {
decryptAuthConfig(conn); decryptAuthConfig(conn);
String effectiveEndpoint = endpoint != null ? endpoint String effectiveEndpoint = endpoint != null ? endpoint
: (String) conn.get("endpointPath"); : (String) conn.get("endpoint_path");
Map<String, Object> testRequest = new LinkedHashMap<>(); Map<String, Object> testRequest = new LinkedHashMap<>();
testRequest.put("base_url", conn.get("baseUrl")); testRequest.put("base_url", conn.get("base_url"));
testRequest.put("endpoint", effectiveEndpoint); testRequest.put("endpoint", effectiveEndpoint);
testRequest.put("method", conn.getOrDefault("defaultMethod", "GET")); testRequest.put("method", conn.getOrDefault("default_method", "GET"));
testRequest.put("headers", conn.get("defaultHeaders")); testRequest.put("headers", conn.get("default_headers"));
testRequest.put("body", conn.get("defaultBody")); testRequest.put("body", conn.get("default_body"));
testRequest.put("auth_type", conn.get("authType")); testRequest.put("auth_type", conn.get("auth_type"));
testRequest.put("auth_config", conn.get("authConfig")); testRequest.put("auth_config", conn.get("auth_config"));
testRequest.put("timeout", conn.get("timeout")); testRequest.put("timeout", conn.get("timeout"));
String companyCode = (String) conn.get("companyCode"); String companyCode = (String) conn.get("company_code");
Map<String, Object> result = testConnection(testRequest, companyCode); Map<String, Object> result = testConnection(testRequest, companyCode);
try { try {
@@ -257,24 +257,24 @@ public class ExternalRestApiConnectionService extends BaseService {
parseJsonFields(conn); parseJsonFields(conn);
decryptAuthConfig(conn); decryptAuthConfig(conn);
if (!"Y".equals(conn.get("isActive"))) { if (!"Y".equals(conn.get("is_active"))) {
return Map.of("success", false, "message", "비활성화된 REST API 연결입니다."); return Map.of("success", false, "message", "비활성화된 REST API 연결입니다.");
} }
String effectiveEndpoint = endpoint != null ? endpoint String effectiveEndpoint = endpoint != null ? endpoint
: (String) conn.getOrDefault("endpointPath", ""); : (String) conn.getOrDefault("endpoint_path", "");
Map<String, Object> testRequest = new LinkedHashMap<>(); Map<String, Object> testRequest = new LinkedHashMap<>();
testRequest.put("base_url", conn.get("baseUrl")); testRequest.put("base_url", conn.get("base_url"));
testRequest.put("endpoint", effectiveEndpoint); testRequest.put("endpoint", effectiveEndpoint);
testRequest.put("method", conn.getOrDefault("defaultMethod", "GET")); testRequest.put("method", conn.getOrDefault("default_method", "GET"));
testRequest.put("headers", conn.get("defaultHeaders")); testRequest.put("headers", conn.get("default_headers"));
testRequest.put("body", conn.get("defaultBody")); testRequest.put("body", conn.get("default_body"));
testRequest.put("auth_type", conn.get("authType")); testRequest.put("auth_type", conn.get("auth_type"));
testRequest.put("auth_config", conn.get("authConfig")); testRequest.put("auth_config", conn.get("auth_config"));
testRequest.put("timeout", conn.get("timeout")); testRequest.put("timeout", conn.get("timeout"));
String companyCode = (String) conn.get("companyCode"); String companyCode = (String) conn.get("company_code");
Map<String, Object> testResult = testConnection(testRequest, companyCode); Map<String, Object> testResult = testConnection(testRequest, companyCode);
if (!Boolean.TRUE.equals(testResult.get("success"))) { if (!Boolean.TRUE.equals(testResult.get("success"))) {
@@ -309,8 +309,8 @@ public class ExternalRestApiConnectionService extends BaseService {
Map<String, Object> connectionInfo = new LinkedHashMap<>(); Map<String, Object> connectionInfo = new LinkedHashMap<>();
connectionInfo.put("connectionId", conn.get("id")); connectionInfo.put("connectionId", conn.get("id"));
connectionInfo.put("connectionName", conn.get("connectionName")); connectionInfo.put("connectionName", conn.get("connection_name"));
connectionInfo.put("baseUrl", conn.get("baseUrl")); connectionInfo.put("baseUrl", conn.get("base_url"));
connectionInfo.put("endpoint", effectiveEndpoint); connectionInfo.put("endpoint", effectiveEndpoint);
Map<String, Object> data = new LinkedHashMap<>(); Map<String, Object> data = new LinkedHashMap<>();
@@ -401,8 +401,8 @@ public class ExternalRestApiConnectionService extends BaseService {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void parseJsonFields(Map<String, Object> row) { private void parseJsonFields(Map<String, Object> row) {
parseJsonField(row, "defaultHeaders"); parseJsonField(row, "default_headers");
parseJsonField(row, "authConfig"); parseJsonField(row, "auth_config");
} }
private void parseJsonField(Map<String, Object> row, String key) { private void parseJsonField(Map<String, Object> row, String key) {
@@ -463,7 +463,7 @@ public class ExternalRestApiConnectionService extends BaseService {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void decryptAuthConfig(Map<String, Object> row) { private void decryptAuthConfig(Map<String, Object> row) {
Object authConfigObj = row.get("authConfig"); Object authConfigObj = row.get("auth_config");
if (authConfigObj == null) return; if (authConfigObj == null) return;
Map<String, Object> authConfig; Map<String, Object> authConfig;
@@ -478,7 +478,7 @@ public class ExternalRestApiConnectionService extends BaseService {
decryptField(authConfig, "token"); decryptField(authConfig, "token");
decryptField(authConfig, "password"); decryptField(authConfig, "password");
decryptField(authConfig, "clientSecret"); decryptField(authConfig, "clientSecret");
row.put("authConfig", authConfig); row.put("auth_config", authConfig);
} catch (Exception e) { } catch (Exception e) {
log.warn("민감 정보 복호화 실패 (암호화되지 않은 데이터일 수 있음)"); log.warn("민감 정보 복호화 실패 (암호화되지 않은 데이터일 수 있음)");
} }
@@ -142,7 +142,7 @@ public class FlowExternalDbConnectionService extends BaseService {
Map<String, Object> conn = findById(id); Map<String, Object> conn = findById(id);
if (conn == null) return result(false, "연결 정보를 찾을 수 없습니다."); if (conn == null) return result(false, "연결 정보를 찾을 수 없습니다.");
String dbType = strOf(conn.get("dbType")); String dbType = strOf(conn.get("db_type"));
String query; String query;
switch (dbType) { switch (dbType) {
case "postgresql": case "postgresql":
@@ -176,7 +176,7 @@ public class FlowExternalDbConnectionService extends BaseService {
Map<String, Object> conn = findById(id); Map<String, Object> conn = findById(id);
if (conn == null) return result(false, "연결 정보를 찾을 수 없습니다."); if (conn == null) return result(false, "연결 정보를 찾을 수 없습니다.");
String dbType = strOf(conn.get("dbType")); String dbType = strOf(conn.get("db_type"));
String sql; String sql;
Object[] args; Object[] args;
switch (dbType) { switch (dbType) {
@@ -218,10 +218,10 @@ public class FlowExternalDbConnectionService extends BaseService {
/** DB row의 JSONB 컬럼(connection_options) 파싱 */ /** DB row의 JSONB 컬럼(connection_options) 파싱 */
private void parseJsonFields(Map<String, Object> row) { private void parseJsonFields(Map<String, Object> row) {
Object opts = row.get("connectionOptions"); Object opts = row.get("connection_options");
if (opts instanceof String) { if (opts instanceof String) {
try { try {
row.put("connectionOptions", objectMapper.readValue((String) opts, Object.class)); row.put("connection_options", objectMapper.readValue((String) opts, Object.class));
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
} }
@@ -257,17 +257,17 @@ public class FlowExternalDbConnectionService extends BaseService {
/** 외부 DB JDBC 연결 생성 (PostgreSQL, MySQL 지원) */ /** 외부 DB JDBC 연결 생성 (PostgreSQL, MySQL 지원) */
private Connection openJdbc(Map<String, Object> conn) throws Exception { private Connection openJdbc(Map<String, Object> conn) throws Exception {
String dbType = strOf(conn.get("dbType")); String dbType = strOf(conn.get("db_type"));
String host = strOf(conn.get("host")); String host = strOf(conn.get("host"));
int port = ((Number) conn.get("port")).intValue(); int port = ((Number) conn.get("port")).intValue();
String dbName = strOf(conn.get("databaseName")); String dbName = strOf(conn.get("database_name"));
String user = strOf(conn.get("username")); String user = strOf(conn.get("username"));
String encPwd = strOf(conn.get("passwordEncrypted")); String encPwd = strOf(conn.get("password_encrypted"));
String password; String password;
try { password = encryption.decrypt(encPwd); } try { password = encryption.decrypt(encPwd); }
catch (Exception e) { password = encPwd; /* fallback */ } catch (Exception e) { password = encPwd; /* fallback */ }
boolean ssl = Boolean.TRUE.equals(conn.get("sslEnabled")); boolean ssl = Boolean.TRUE.equals(conn.get("ssl_enabled"));
String jdbcUrl; String jdbcUrl;
switch (dbType) { switch (dbType) {
@@ -65,8 +65,8 @@ public class MailReceiveBasicService extends BaseService {
result.put("message", "메일 계정을 찾을 수 없습니다."); result.put("message", "메일 계정을 찾을 수 없습니다.");
return result; return result;
} }
String host = (String) account.get("imapHost"); String host = (String) account.get("imap_host");
Object portObj = account.get("imapPort"); Object portObj = account.get("imap_port");
int port = portObj != null ? ((Number) portObj).intValue() : 993; int port = portObj != null ? ((Number) portObj).intValue() : 993;
try (Socket socket = new Socket()) { try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), 5000); socket.connect(new InetSocketAddress(host, port), 5000);
@@ -98,7 +98,7 @@ public class MailSendSimpleService extends BaseService {
if (htmlContent.isBlank()) throw new IllegalArgumentException("메일 내용이 없습니다."); if (htmlContent.isBlank()) throw new IllegalArgumentException("메일 내용이 없습니다.");
// 비밀번호 복호화 // 비밀번호 복호화
String decryptedPassword = passwordEncryption.decrypt(str(account.get("smtpPassword"))); String decryptedPassword = passwordEncryption.decrypt(str(account.get("smtp_password")));
// JavaMailSender 동적 생성 및 발송 // JavaMailSender 동적 생성 및 발송
JavaMailSenderImpl sender = createMailSender(account, decryptedPassword); JavaMailSenderImpl sender = createMailSender(account, decryptedPassword);
@@ -263,7 +263,7 @@ public class MailSendSimpleService extends BaseService {
return r; return r;
} }
try { try {
String decryptedPassword = passwordEncryption.decrypt(str(account.get("smtpPassword"))); String decryptedPassword = passwordEncryption.decrypt(str(account.get("smtp_password")));
JavaMailSenderImpl sender = createMailSender(account, decryptedPassword); JavaMailSenderImpl sender = createMailSender(account, decryptedPassword);
sender.testConnection(); sender.testConnection();
Map<String, Object> r = new LinkedHashMap<>(); Map<String, Object> r = new LinkedHashMap<>();
@@ -283,19 +283,19 @@ public class MailSendSimpleService extends BaseService {
private JavaMailSenderImpl createMailSender(Map<String, Object> account, String decryptedPassword) { private JavaMailSenderImpl createMailSender(Map<String, Object> account, String decryptedPassword) {
JavaMailSenderImpl sender = new JavaMailSenderImpl(); JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost(str(account.get("smtpHost"))); sender.setHost(str(account.get("smtp_host")));
Object portObj = account.get("smtpPort"); Object portObj = account.get("smtp_port");
int port = portObj != null ? ((Number) portObj).intValue() : 587; int port = portObj != null ? ((Number) portObj).intValue() : 587;
sender.setPort(port); sender.setPort(port);
sender.setUsername(str(account.get("smtpUsername"))); sender.setUsername(str(account.get("smtp_username")));
sender.setPassword(decryptedPassword); sender.setPassword(decryptedPassword);
sender.setDefaultEncoding("UTF-8"); sender.setDefaultEncoding("UTF-8");
Properties props = sender.getJavaMailProperties(); Properties props = sender.getJavaMailProperties();
boolean secure = (port == 465); boolean secure = (port == 465);
if (!secure) { if (!secure) {
Object smtpSecureObj = account.get("smtpSecure"); Object smtpSecureObj = account.get("smtp_secure");
secure = Boolean.TRUE.equals(smtpSecureObj) secure = Boolean.TRUE.equals(smtpSecureObj)
|| "true".equalsIgnoreCase(str(smtpSecureObj)); || "true".equalsIgnoreCase(str(smtpSecureObj));
} }
@@ -139,8 +139,8 @@ public class MailSentHistoryService extends BaseService {
Map<String, Object> stats = sqlSession.selectOne(NS + "getMailSentHistoryStatistics", params); Map<String, Object> stats = sqlSession.selectOne(NS + "getMailSentHistoryStatistics", params);
if (stats == null) stats = new HashMap<>(); if (stats == null) stats = new HashMap<>();
long totalSent = toLong(stats.get("totalSent")); long totalSent = toLong(stats.get("total_sent"));
long successCount = toLong(stats.get("successCount")); long successCount = toLong(stats.get("success_count"));
long successRate = totalSent > 0 ? Math.round((double) successCount / totalSent * 100) : 0; long successRate = totalSent > 0 ? Math.round((double) successCount / totalSent * 100) : 0;
stats.put("successRate", successRate); stats.put("successRate", successRate);
return stats; return stats;
@@ -302,8 +302,7 @@ public class MultiConnectionService extends BaseService {
private Connection openExtConn(Map<String, Object> connInfo) throws SQLException { private Connection openExtConn(Map<String, Object> connInfo) throws SQLException {
String host = str(connInfo, "host"); String host = str(connInfo, "host");
int port = toIntMap(connInfo, "port", 5432); int port = toIntMap(connInfo, "port", 5432);
String database = str(connInfo, "databaseName"); String database = str(connInfo, "database_name");
if (database == null) database = str(connInfo, "database_name");
String url = String.format("jdbc:postgresql://%s:%d/%s", host, port, database); String url = String.format("jdbc:postgresql://%s:%d/%s", host, port, database);
Properties props = new Properties(); Properties props = new Properties();
@@ -45,7 +45,7 @@ public class MultilangService extends BaseService {
if (current == null) { if (current == null) {
throw new IllegalArgumentException("언어를 찾을 수 없습니다: " + langCode); throw new IllegalArgumentException("언어를 찾을 수 없습니다: " + langCode);
} }
String newStatus = "Y".equals(current.get("isActive")) ? "N" : "Y"; String newStatus = "Y".equals(current.get("is_active")) ? "N" : "Y";
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("langCode", langCode); params.put("langCode", langCode);
params.put("newStatus", newStatus); params.put("newStatus", newStatus);
@@ -119,7 +119,7 @@ public class MultilangService extends BaseService {
if (current == null) { if (current == null) {
throw new IllegalArgumentException("다국어 키를 찾을 수 없습니다: " + keyId); throw new IllegalArgumentException("다국어 키를 찾을 수 없습니다: " + keyId);
} }
String newStatus = "Y".equals(current.get("isActive")) ? "N" : "Y"; String newStatus = "Y".equals(current.get("is_active")) ? "N" : "Y";
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("keyId", keyId); params.put("keyId", keyId);
params.put("newStatus", newStatus); params.put("newStatus", newStatus);
@@ -147,14 +147,14 @@ public class MultilangService extends BaseService {
"companyCode", companyCode, "menuCode", menuCode, "companyCode", companyCode, "menuCode", menuCode,
"langKey", langKey, "userLang", userLang); "langKey", langKey, "userLang", userLang);
Map<String, Object> result = sqlSession.selectOne(NS + "getMultilangUserText", params); Map<String, Object> result = sqlSession.selectOne(NS + "getMultilangUserText", params);
return result != null ? str(result.get("langText")) : langKey; return result != null ? str(result.get("lang_text")) : langKey;
} }
public String getLangText(String companyCode, String langKey, String langCode) { public String getLangText(String companyCode, String langKey, String langCode) {
Map<String, Object> params = Map.of( Map<String, Object> params = Map.of(
"companyCode", companyCode, "langKey", langKey, "langCode", langCode); "companyCode", companyCode, "langKey", langKey, "langCode", langCode);
Map<String, Object> result = sqlSession.selectOne(NS + "getMultilangSingleText", params); Map<String, Object> result = sqlSession.selectOne(NS + "getMultilangSingleText", params);
return result != null ? str(result.get("langText")) : langKey; return result != null ? str(result.get("lang_text")) : langKey;
} }
public Map<String, String> getBatchTranslations(String companyCode, String menuCode, public Map<String, String> getBatchTranslations(String companyCode, String menuCode,
@@ -169,9 +169,9 @@ public class MultilangService extends BaseService {
Map<String, String> result = new LinkedHashMap<>(); Map<String, String> result = new LinkedHashMap<>();
Set<String> processed = new HashSet<>(); Set<String> processed = new HashSet<>();
for (Map<String, Object> t : translations) { for (Map<String, Object> t : translations) {
String key = str(t.get("langKey")); String key = str(t.get("lang_key"));
if (langKeys.contains(key) && !processed.contains(key)) { if (langKeys.contains(key) && !processed.contains(key)) {
result.put(key, str(t.get("langText"))); result.put(key, str(t.get("lang_text")));
processed.add(key); processed.add(key);
} }
} }
@@ -183,9 +183,9 @@ public class MultilangService extends BaseService {
List<Map<String, Object>> fallback = sqlSession.selectList(NS + "getMultilangFallbackTranslationList", fallbackParams); List<Map<String, Object>> fallback = sqlSession.selectList(NS + "getMultilangFallbackTranslationList", fallbackParams);
Set<String> fbProcessed = new HashSet<>(); Set<String> fbProcessed = new HashSet<>();
for (Map<String, Object> t : fallback) { for (Map<String, Object> t : fallback) {
String key = str(t.get("langKey")); String key = str(t.get("lang_key"));
if (!result.containsKey(key) && !fbProcessed.contains(key)) { if (!result.containsKey(key) && !fbProcessed.contains(key)) {
result.put(key, str(t.get("langText"))); result.put(key, str(t.get("lang_text")));
fbProcessed.add(key); fbProcessed.add(key);
} }
} }
@@ -212,11 +212,11 @@ public class MultilangService extends BaseService {
for (Map<String, Object> cat : flat) { for (Map<String, Object> cat : flat) {
Map<String, Object> node = new LinkedHashMap<>(cat); Map<String, Object> node = new LinkedHashMap<>(cat);
node.put("children", new ArrayList<>()); node.put("children", new ArrayList<>());
byId.put(toInt(cat.get("categoryId")), node); byId.put(toInt(cat.get("category_id")), node);
} }
List<Map<String, Object>> roots = new ArrayList<>(); List<Map<String, Object>> roots = new ArrayList<>();
for (Map<String, Object> node : byId.values()) { for (Map<String, Object> node : byId.values()) {
Object parentIdObj = node.get("parentId"); Object parentIdObj = node.get("parent_id");
if (parentIdObj == null) { if (parentIdObj == null) {
roots.add(node); roots.add(node);
} else { } else {
@@ -280,7 +280,7 @@ public class MultilangService extends BaseService {
result.put("langKey", langKey); result.put("langKey", langKey);
result.put("exists", companyKey != null); result.put("exists", companyKey != null);
result.put("isOverride", commonKey != null && companyKey == null); result.put("isOverride", commonKey != null && companyKey == null);
if (commonKey != null) result.put("baseKeyId", toInt(commonKey.get("keyId"))); if (commonKey != null) result.put("baseKeyId", toInt(commonKey.get("key_id")));
return result; return result;
} }
@@ -290,16 +290,16 @@ public class MultilangService extends BaseService {
String companyCode = str(params.get("companyCode")); String companyCode = str(params.get("companyCode"));
Map<String, Object> baseKey = sqlSession.selectOne(NS + "getMultilangBaseKeyInfo", Map.of("keyId", baseKeyId)); Map<String, Object> baseKey = sqlSession.selectOne(NS + "getMultilangBaseKeyInfo", Map.of("keyId", baseKeyId));
if (baseKey == null) throw new IllegalArgumentException("원본 키를 찾을 수 없습니다"); if (baseKey == null) throw new IllegalArgumentException("원본 키를 찾을 수 없습니다");
if (!"*".equals(str(baseKey.get("companyCode")))) throw new IllegalArgumentException("공통 키(*)만 오버라이드 할 수 있습니다"); if (!"*".equals(str(baseKey.get("company_code")))) throw new IllegalArgumentException("공통 키(*)만 오버라이드 할 수 있습니다");
String langKey = str(baseKey.get("langKey")); String langKey = str(baseKey.get("lang_key"));
if (sqlSession.selectOne(NS + "getMultilangKeyByCompanyAndKey", Map.of("companyCode", companyCode, "langKey", langKey)) != null) { if (sqlSession.selectOne(NS + "getMultilangKeyByCompanyAndKey", Map.of("companyCode", companyCode, "langKey", langKey)) != null) {
throw new IllegalArgumentException("이미 해당 회사의 오버라이드 키가 존재합니다"); throw new IllegalArgumentException("이미 해당 회사의 오버라이드 키가 존재합니다");
} }
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
insertParams.put("companyCode", companyCode); insertParams.put("companyCode", companyCode);
insertParams.put("langKey", langKey); insertParams.put("langKey", langKey);
insertParams.put("categoryId", baseKey.get("categoryId")); insertParams.put("categoryId", baseKey.get("category_id"));
insertParams.put("keyMeaning", baseKey.get("keyMeaning")); insertParams.put("keyMeaning", baseKey.get("key_meaning"));
insertParams.put("baseKeyId", baseKeyId); insertParams.put("baseKeyId", baseKeyId);
insertParams.put("createdBy", params.getOrDefault("createdBy", "system")); insertParams.put("createdBy", params.getOrDefault("createdBy", "system"));
sqlSession.insert(NS + "insertMultilangOverrideKey", insertParams); sqlSession.insert(NS + "insertMultilangOverrideKey", insertParams);
@@ -327,20 +327,20 @@ public class MultilangService extends BaseService {
public List<Map<String, Object>> generateScreenLabelKeys(Map<String, Object> params) { public List<Map<String, Object>> generateScreenLabelKeys(Map<String, Object> params) {
int screenId = toInt(params.get("screenId")); int screenId = toInt(params.get("screenId"));
Map<String, Object> screenInfo = sqlSession.selectOne(NS + "getMultilangScreenCompanyCode", Map.of("screenId", screenId)); Map<String, Object> screenInfo = sqlSession.selectOne(NS + "getMultilangScreenCompanyCode", Map.of("screenId", screenId));
String companyCode = (screenInfo != null && !str(screenInfo.get("companyCode")).isEmpty()) String companyCode = (screenInfo != null && !str(screenInfo.get("company_code")).isEmpty())
? str(screenInfo.get("companyCode")) : str(params.getOrDefault("companyCode", "*")); ? str(screenInfo.get("company_code")) : str(params.getOrDefault("companyCode", "*"));
String companyName; String companyName;
if ("*".equals(companyCode)) { if ("*".equals(companyCode)) {
companyName = "공통"; companyName = "공통";
} else { } else {
Map<String, Object> companyInfo = sqlSession.selectOne(NS + "getMultilangCompanyName", Map.of("companyCode", companyCode)); Map<String, Object> companyInfo = sqlSession.selectOne(NS + "getMultilangCompanyName", Map.of("companyCode", companyCode));
companyName = (companyInfo != null) ? str(companyInfo.get("companyName")) : companyCode; companyName = (companyInfo != null) ? str(companyInfo.get("company_name")) : companyCode;
} }
List<String> groupPath = getScreenGroupPath(screenId); List<String> groupPath = getScreenGroupPath(screenId);
int categoryId = ensureScreenGroupCategory(companyCode, companyName, groupPath); int categoryId = ensureScreenGroupCategory(companyCode, companyName, groupPath);
List<Map<String, Object>> categoryPath = getCategoryPath(categoryId); List<Map<String, Object>> categoryPath = getCategoryPath(categoryId);
List<String> keyPrefixParts = new ArrayList<>(); List<String> keyPrefixParts = new ArrayList<>();
for (Map<String, Object> c : categoryPath) keyPrefixParts.add(str(c.get("keyPrefix"))); for (Map<String, Object> c : categoryPath) keyPrefixParts.add(str(c.get("key_prefix")));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Map<String, Object>> labels = (List<Map<String, Object>>) params.get("labels"); List<Map<String, Object>> labels = (List<Map<String, Object>>) params.get("labels");
List<Map<String, Object>> results = new ArrayList<>(); List<Map<String, Object>> results = new ArrayList<>();
@@ -354,7 +354,7 @@ public class MultilangService extends BaseService {
Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangKeyByCompanyAndKey", Map.of("companyCode", companyCode, "langKey", langKey)); Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangKeyByCompanyAndKey", Map.of("companyCode", companyCode, "langKey", langKey));
int keyId; int keyId;
if (existing != null) { if (existing != null) {
keyId = toInt(existing.get("keyId")); keyId = toInt(existing.get("key_id"));
} else { } else {
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
insertParams.put("companyCode", companyCode); insertParams.put("companyCode", companyCode);
@@ -379,10 +379,10 @@ public class MultilangService extends BaseService {
private List<String> getScreenGroupPath(int screenId) { private List<String> getScreenGroupPath(int screenId) {
Map<String, Object> groupRow = sqlSession.selectOne(NS + "getMultilangScreenGroupId", Map.of("screenId", screenId)); Map<String, Object> groupRow = sqlSession.selectOne(NS + "getMultilangScreenGroupId", Map.of("screenId", screenId));
if (groupRow == null) return Collections.emptyList(); if (groupRow == null) return Collections.emptyList();
int groupId = toInt(groupRow.get("groupId")); int groupId = toInt(groupRow.get("group_id"));
List<Map<String, Object>> groups = sqlSession.selectList(NS + "getMultilangScreenGroupPath", Map.of("groupId", groupId)); List<Map<String, Object>> groups = sqlSession.selectList(NS + "getMultilangScreenGroupPath", Map.of("groupId", groupId));
List<String> path = new ArrayList<>(); List<String> path = new ArrayList<>();
for (Map<String, Object> g : groups) path.add(str(g.get("groupName"))); for (Map<String, Object> g : groups) path.add(str(g.get("group_name")));
return path; return path;
} }
@@ -393,7 +393,7 @@ public class MultilangService extends BaseService {
for (String groupName : groupPath) { for (String groupName : groupPath) {
Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangCategoryByNameAndParent", Map.of("categoryName", groupName, "parentId", parentId)); Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangCategoryByNameAndParent", Map.of("categoryName", groupName, "parentId", parentId));
if (existing != null) { if (existing != null) {
parentId = toInt(existing.get("categoryId")); parentId = toInt(existing.get("category_id"));
} else { } else {
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
insertParams.put("categoryCode", (companyCode + "_GROUP_" + groupName).replace("\\s+", "_")); insertParams.put("categoryCode", (companyCode + "_GROUP_" + groupName).replace("\\s+", "_"));
@@ -414,7 +414,7 @@ public class MultilangService extends BaseService {
private int ensureCompanyCategory(String companyCode, String companyName) { private int ensureCompanyCategory(String companyCode, String companyName) {
int screenRootId = ensureScreenRootCategory(); int screenRootId = ensureScreenRootCategory();
Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangCategoryByCodeAndParent", Map.of("categoryCode", companyCode, "parentId", screenRootId)); Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangCategoryByCodeAndParent", Map.of("categoryCode", companyCode, "parentId", screenRootId));
if (existing != null) return toInt(existing.get("categoryId")); if (existing != null) return toInt(existing.get("category_id"));
String displayName = "*".equals(companyCode) ? "공통" : companyName; String displayName = "*".equals(companyCode) ? "공통" : companyName;
String keyPrefix = "*".equals(companyCode) ? "common" : companyCode.toLowerCase(); String keyPrefix = "*".equals(companyCode) ? "common" : companyCode.toLowerCase();
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
@@ -431,7 +431,7 @@ public class MultilangService extends BaseService {
private int ensureScreenRootCategory() { private int ensureScreenRootCategory() {
Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangRootCategoryByCode", Map.of("categoryCode", "screen")); Map<String, Object> existing = sqlSession.selectOne(NS + "getMultilangRootCategoryByCode", Map.of("categoryCode", "screen"));
if (existing != null) return toInt(existing.get("categoryId")); if (existing != null) return toInt(existing.get("category_id"));
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
insertParams.put("categoryCode", "screen"); insertParams.put("categoryCode", "screen");
insertParams.put("categoryName", "화면"); insertParams.put("categoryName", "화면");
@@ -446,7 +446,7 @@ public class MultilangService extends BaseService {
private String buildLangKey(List<Map<String, Object>> categoryPath, String keyMeaning) { private String buildLangKey(List<Map<String, Object>> categoryPath, String keyMeaning) {
List<String> parts = new ArrayList<>(); List<String> parts = new ArrayList<>();
for (Map<String, Object> c : categoryPath) parts.add(str(c.get("keyPrefix"))); for (Map<String, Object> c : categoryPath) parts.add(str(c.get("key_prefix")));
parts.add(keyMeaning); parts.add(keyMeaning);
return String.join(".", parts); return String.join(".", parts);
} }
@@ -59,7 +59,7 @@ public class NodeExternalConnectionService extends BaseService {
.orTimeout(TIMEOUT_SEC, TimeUnit.SECONDS) .orTimeout(TIMEOUT_SEC, TimeUnit.SECONDS)
.exceptionally(e -> { .exceptionally(e -> {
log.warn("커넥션 테스트 타임아웃/오류 ({}): {}", log.warn("커넥션 테스트 타임아웃/오류 ({}): {}",
conn.get("connectionName"), e.getMessage()); conn.get("connection_name"), e.getMessage());
return null; return null;
})) }))
.toList(); .toList();
@@ -87,7 +87,7 @@ public class NodeExternalConnectionService extends BaseService {
Map<String, Object> conn = loadConnection(id); Map<String, Object> conn = loadConnection(id);
if (conn == null) return fail("연결 ID " + id + "를 찾을 수 없습니다."); if (conn == null) return fail("연결 ID " + id + "를 찾을 수 없습니다.");
String dbType = str(conn.get("dbType")).toLowerCase(); String dbType = str(conn.get("db_type")).toLowerCase();
String sql; String sql;
switch (dbType) { switch (dbType) {
case "postgresql": case "postgresql":
@@ -129,7 +129,7 @@ public class NodeExternalConnectionService extends BaseService {
Map<String, Object> conn = loadConnection(id); Map<String, Object> conn = loadConnection(id);
if (conn == null) return fail("연결 ID " + id + "를 찾을 수 없습니다."); if (conn == null) return fail("연결 ID " + id + "를 찾을 수 없습니다.");
String dbType = str(conn.get("dbType")).toLowerCase(); String dbType = str(conn.get("db_type")).toLowerCase();
String sql; String sql;
switch (dbType) { switch (dbType) {
case "postgresql": case "postgresql":
@@ -179,15 +179,15 @@ public class NodeExternalConnectionService extends BaseService {
Map<String, Object> entry = new LinkedHashMap<>(); Map<String, Object> entry = new LinkedHashMap<>();
entry.put("id", conn.get("id")); entry.put("id", conn.get("id"));
entry.put("connection_name", conn.get("connectionName")); entry.put("connection_name", conn.get("connection_name"));
entry.put("description", conn.get("description")); entry.put("description", conn.get("description"));
entry.put("db_type", conn.get("dbType")); entry.put("db_type", conn.get("db_type"));
entry.put("host", conn.get("host")); entry.put("host", conn.get("host"));
entry.put("port", conn.get("port")); entry.put("port", conn.get("port"));
entry.put("database_name", conn.get("databaseName")); entry.put("database_name", conn.get("database_name"));
return entry; return entry;
} catch (Exception e) { } catch (Exception e) {
log.warn("연결 테스트 실패 ({}): {}", conn.get("connectionName"), e.getMessage()); log.warn("연결 테스트 실패 ({}): {}", conn.get("connection_name"), e.getMessage());
return null; return null;
} }
} }
@@ -203,13 +203,13 @@ public class NodeExternalConnectionService extends BaseService {
* ssl_enabled = 'Y'/'N' 문자열 처리 (Node.js 저장 형식과 동일). * ssl_enabled = 'Y'/'N' 문자열 처리 (Node.js 저장 형식과 동일).
*/ */
private Connection openJdbc(Map<String, Object> conn) throws Exception { private Connection openJdbc(Map<String, Object> conn) throws Exception {
String dbType = str(conn.get("dbType")).toLowerCase(); String dbType = str(conn.get("db_type")).toLowerCase();
String host = str(conn.get("host")); String host = str(conn.get("host"));
int port = ((Number) conn.get("port")).intValue(); int port = ((Number) conn.get("port")).intValue();
String dbName = str(conn.get("databaseName")); String dbName = str(conn.get("database_name"));
String user = str(conn.get("username")); String user = str(conn.get("username"));
String encPwd = str(conn.get("password")); String encPwd = str(conn.get("password"));
boolean ssl = "Y".equalsIgnoreCase(str(conn.get("sslEnabled"))); boolean ssl = "Y".equalsIgnoreCase(str(conn.get("ssl_enabled")));
String password; String password;
try { try {
@@ -58,7 +58,7 @@ public class NodeFlowService extends BaseService {
if (flow == null) return null; if (flow == null) return null;
// flowData JSONB Java 객체 // flowData JSONB Java 객체
parseFlowDataField(flow, "flowData"); parseFlowDataField(flow, "flow_data");
return flow; return flow;
} }
@@ -130,8 +130,8 @@ public class NodeFlowService extends BaseService {
String companyCode = (String) params.get("companyCode"); String companyCode = (String) params.get("companyCode");
Map<String, Object> changes = new LinkedHashMap<>(); Map<String, Object> changes = new LinkedHashMap<>();
if (oldFlow != null) changes.put("before", Map.of( if (oldFlow != null) changes.put("before", Map.of(
"flowName", oldFlow.getOrDefault("flowName", ""), "flowName", oldFlow.getOrDefault("flow_name", ""),
"flowDescription", oldFlow.getOrDefault("flowDescription", ""))); "flowDescription", oldFlow.getOrDefault("flow_description", "")));
changes.put("after", Map.of("flowName", flowName, changes.put("after", Map.of("flowName", flowName,
"flowDescription", params.getOrDefault("flowDescription", ""))); "flowDescription", params.getOrDefault("flowDescription", "")));
@@ -158,13 +158,13 @@ public class NodeFlowService extends BaseService {
log.info("플로우 삭제 성공: {}", flowId); log.info("플로우 삭제 성공: {}", flowId);
String flowName = oldFlow != null String flowName = oldFlow != null
? (String) oldFlow.getOrDefault("flowName", "ID:" + flowId) ? (String) oldFlow.getOrDefault("flow_name", "ID:" + flowId)
: "ID:" + flowId; : "ID:" + flowId;
Map<String, Object> changes = new LinkedHashMap<>(); Map<String, Object> changes = new LinkedHashMap<>();
if (oldFlow != null) changes.put("before", Map.of( if (oldFlow != null) changes.put("before", Map.of(
"flowName", oldFlow.getOrDefault("flowName", ""), "flowName", oldFlow.getOrDefault("flow_name", ""),
"flowDescription", oldFlow.getOrDefault("flowDescription", ""))); "flowDescription", oldFlow.getOrDefault("flow_description", "")));
insertAuditLog(companyCode, userId, userName, insertAuditLog(companyCode, userId, userName,
"DELETE", String.valueOf(flowId), flowName, "DELETE", String.valueOf(flowId), flowName,
@@ -179,7 +179,7 @@ public class NodeFlowService extends BaseService {
Map<String, Object> row = sqlSession.selectOne("nodeFlow.getNodeFlowData", Map.of("flowId", flowId)); Map<String, Object> row = sqlSession.selectOne("nodeFlow.getNodeFlowData", Map.of("flowId", flowId));
if (row == null) return null; if (row == null) return null;
Map<String, Object> flowData = parseJsonToMap(row.get("flowData")); Map<String, Object> flowData = parseJsonToMap(row.get("flow_data"));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Map<String, Object>> nodes = (List<Map<String, Object>>) flowData.getOrDefault("nodes", List.of()); List<Map<String, Object>> nodes = (List<Map<String, Object>>) flowData.getOrDefault("nodes", List.of());
@@ -229,7 +229,7 @@ public class NodeFlowService extends BaseService {
Map<String, Object> row = sqlSession.selectOne("nodeFlow.getNodeFlowData", Map.of("flowId", flowId)); Map<String, Object> row = sqlSession.selectOne("nodeFlow.getNodeFlowData", Map.of("flowId", flowId));
if (row == null) throw new IllegalArgumentException("플로우를 찾을 수 없습니다: flowId=" + flowId); if (row == null) throw new IllegalArgumentException("플로우를 찾을 수 없습니다: flowId=" + flowId);
Map<String, Object> flowData = parseJsonToMap(row.get("flowData")); Map<String, Object> flowData = parseJsonToMap(row.get("flow_data"));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Map<String, Object>> nodes = (List<Map<String, Object>>) flowData.getOrDefault("nodes", List.of()); List<Map<String, Object>> nodes = (List<Map<String, Object>>) flowData.getOrDefault("nodes", List.of());
@@ -237,7 +237,7 @@ public class NodeFlowService extends BaseService {
List<Map<String, Object>> edges = (List<Map<String, Object>>) flowData.getOrDefault("edges", List.of()); List<Map<String, Object>> edges = (List<Map<String, Object>>) flowData.getOrDefault("edges", List.of());
log.info("플로우 정보: flowName={}, nodes={}, edges={}", log.info("플로우 정보: flowName={}, nodes={}, edges={}",
row.get("flowName"), nodes.size(), edges.size()); row.get("flow_name"), nodes.size(), edges.size());
// 위상 정렬 (레벨별) // 위상 정렬 (레벨별)
List<List<String>> levels = topologicalSort(nodes, edges); List<List<String>> levels = topologicalSort(nodes, edges);
@@ -153,7 +153,7 @@ public class NumberingRuleService extends BaseService {
// 수동 추출 // 수동 추출
List<String> extractedManualValues = new ArrayList<>(); List<String> extractedManualValues = new ArrayList<>();
boolean hasManualPart = sortedParts.stream() boolean hasManualPart = sortedParts.stream()
.anyMatch(p -> "manual".equals(p.get("generationMethod"))); .anyMatch(p -> "manual".equals(p.get("generation_method")));
if (hasManualPart && userInputCode != null) { if (hasManualPart && userInputCode != null) {
extractedManualValues = extractManualValues(rule, sortedParts, userInputCode, formData); extractedManualValues = extractManualValues(rule, sortedParts, userInputCode, formData);
} }
@@ -162,7 +162,7 @@ public class NumberingRuleService extends BaseService {
String prefixKey = buildPrefixKey(rule, formData, String prefixKey = buildPrefixKey(rule, formData,
extractedManualValues.isEmpty() ? null : extractedManualValues); extractedManualValues.isEmpty() ? null : extractedManualValues);
boolean hasSequence = sortedParts.stream() boolean hasSequence = sortedParts.stream()
.anyMatch(p -> "sequence".equals(p.get("partType"))); .anyMatch(p -> "sequence".equals(p.get("part_type")));
long allocatedSequence = 0; long allocatedSequence = 0;
if (hasSequence) { if (hasSequence) {
@@ -246,7 +246,7 @@ public class NumberingRuleService extends BaseService {
if (rule != null) { if (rule != null) {
// column_name 자동 업데이트 (레거시 마이그레이션) // column_name 자동 업데이트 (레거시 마이그레이션)
Map<String, Object> upParams = new HashMap<>(); Map<String, Object> upParams = new HashMap<>();
upParams.put("ruleId", rule.get("ruleId")); upParams.put("ruleId", rule.get("rule_id"));
upParams.put("companyCode", companyCode); upParams.put("companyCode", companyCode);
upParams.put("columnName", columnName); upParams.put("columnName", columnName);
sqlSession.update(NS + "updateRuleColumnName", upParams); sqlSession.update(NS + "updateRuleColumnName", upParams);
@@ -326,7 +326,7 @@ public class NumberingRuleService extends BaseService {
int skipped = 0; int skipped = 0;
for (Map<String, Object> rule : sourceRules) { for (Map<String, Object> rule : sourceRules) {
String ruleId = (String) rule.get("ruleId"); String ruleId = (String) rule.get("rule_id");
// 대상 회사에 이미 존재하는지 확인 // 대상 회사에 이미 존재하는지 확인
Map<String, Object> checkParams = new HashMap<>(); Map<String, Object> checkParams = new HashMap<>();
@@ -374,7 +374,7 @@ public class NumberingRuleService extends BaseService {
partParams.put("companyCode", companyCode); partParams.put("companyCode", companyCode);
// auto_config: separatorAfter 통합 // auto_config: separatorAfter 통합
Map<String, Object> autoConfig = parseAutoConfig(part.get("autoConfig")); Map<String, Object> autoConfig = parseAutoConfig(part.get("auto_config"));
Object sepAfter = part.getOrDefault("separatorAfter", "-"); Object sepAfter = part.getOrDefault("separatorAfter", "-");
autoConfig.put("separatorAfter", sepAfter); autoConfig.put("separatorAfter", sepAfter);
partParams.put("autoConfig", toJsonString(autoConfig)); partParams.put("autoConfig", toJsonString(autoConfig));
@@ -393,14 +393,14 @@ public class NumberingRuleService extends BaseService {
} }
private void loadPartsForRule(Map<String, Object> rule, String companyCode) { private void loadPartsForRule(Map<String, Object> rule, String companyCode) {
String ruleId = (String) rule.get("ruleId"); String ruleId = (String) rule.get("rule_id");
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("ruleId", ruleId); params.put("ruleId", ruleId);
params.put("companyCode", companyCode); params.put("companyCode", companyCode);
List<Map<String, Object>> parts = sqlSession.selectList(NS + "getRulePartsByRuleId", params); List<Map<String, Object>> parts = sqlSession.selectList(NS + "getRulePartsByRuleId", params);
// autoConfig에서 separatorAfter 추출 // autoConfig에서 separatorAfter 추출
for (Map<String, Object> part : parts) { for (Map<String, Object> part : parts) {
Map<String, Object> ac = parseAutoConfig(part.get("autoConfig")); Map<String, Object> ac = parseAutoConfig(part.get("auto_config"));
if (ac.containsKey("separatorAfter")) { if (ac.containsKey("separatorAfter")) {
part.put("separatorAfter", ac.get("separatorAfter")); part.put("separatorAfter", ac.get("separatorAfter"));
} }
@@ -422,7 +422,7 @@ public class NumberingRuleService extends BaseService {
params.put("prefixKey", prefixKey); params.put("prefixKey", prefixKey);
Map<String, Object> row = sqlSession.selectOne(NS + "getSequenceForPrefix", params); Map<String, Object> row = sqlSession.selectOne(NS + "getSequenceForPrefix", params);
if (row == null) return 0L; if (row == null) return 0L;
Object seq = row.get("currentSequence"); Object seq = row.get("current_sequence");
return seq == null ? 0L : ((Number) seq).longValue(); return seq == null ? 0L : ((Number) seq).longValue();
} }
@@ -455,8 +455,8 @@ public class NumberingRuleService extends BaseService {
int manualIndex = 0; int manualIndex = 0;
for (Map<String, Object> part : sortedParts) { for (Map<String, Object> part : sortedParts) {
String partType = (String) part.get("partType"); String partType = (String) part.get("part_type");
String generationMethod = (String) part.get("generationMethod"); String generationMethod = (String) part.get("generation_method");
if ("sequence".equals(partType)) continue; if ("sequence".equals(partType)) continue;
@@ -468,7 +468,7 @@ public class NumberingRuleService extends BaseService {
continue; continue;
} }
Map<String, Object> ac = parseAutoConfig(part.get("autoConfig")); Map<String, Object> ac = parseAutoConfig(part.get("auto_config"));
String computed = computeSinglePartValue(partType, ac, formData); String computed = computeSinglePartValue(partType, ac, formData);
if (computed != null && !computed.isEmpty()) { if (computed != null && !computed.isEmpty()) {
prefixParts.add(computed); prefixParts.add(computed);
@@ -485,9 +485,9 @@ public class NumberingRuleService extends BaseService {
boolean isPreview) { boolean isPreview) {
List<String> values = new ArrayList<>(); List<String> values = new ArrayList<>();
for (Map<String, Object> part : sortedParts) { for (Map<String, Object> part : sortedParts) {
String partType = (String) part.get("partType"); String partType = (String) part.get("part_type");
String generationMethod = (String) part.get("generationMethod"); String generationMethod = (String) part.get("generation_method");
Map<String, Object> ac = parseAutoConfig(part.get("autoConfig")); Map<String, Object> ac = parseAutoConfig(part.get("auto_config"));
if ("manual".equals(generationMethod)) { if ("manual".equals(generationMethod)) {
values.add(isPreview ? "____" : ""); values.add(isPreview ? "____" : "");
@@ -512,9 +512,9 @@ public class NumberingRuleService extends BaseService {
int manualIndex = 0; int manualIndex = 0;
for (Map<String, Object> part : sortedParts) { for (Map<String, Object> part : sortedParts) {
String partType = (String) part.get("partType"); String partType = (String) part.get("part_type");
String generationMethod = (String) part.get("generationMethod"); String generationMethod = (String) part.get("generation_method");
Map<String, Object> ac = parseAutoConfig(part.get("autoConfig")); Map<String, Object> ac = parseAutoConfig(part.get("auto_config"));
if ("manual".equals(generationMethod)) { if ("manual".equals(generationMethod)) {
String val = (manualValues != null && manualIndex < manualValues.size()) String val = (manualValues != null && manualIndex < manualValues.size())
@@ -630,7 +630,7 @@ public class NumberingRuleService extends BaseService {
sb.append(values.get(i)); sb.append(values.get(i));
if (i < values.size() - 1) { if (i < values.size() - 1) {
Map<String, Object> part = sortedParts.get(i); Map<String, Object> part = sortedParts.get(i);
Map<String, Object> ac = parseAutoConfig(part.get("autoConfig")); Map<String, Object> ac = parseAutoConfig(part.get("auto_config"));
Object sep = part.containsKey("separatorAfter") ? part.get("separatorAfter") Object sep = part.containsKey("separatorAfter") ? part.get("separatorAfter")
: ac.getOrDefault("separatorAfter", globalSeparator != null ? globalSeparator : ""); : ac.getOrDefault("separatorAfter", globalSeparator != null ? globalSeparator : "");
sb.append(sep != null ? sep.toString() : ""); sb.append(sep != null ? sep.toString() : "");
@@ -648,7 +648,7 @@ public class NumberingRuleService extends BaseService {
String userInputCode, String userInputCode,
Map<String, Object> formData) { Map<String, Object> formData) {
List<Map<String, Object>> manualParts = sortedParts.stream() List<Map<String, Object>> manualParts = sortedParts.stream()
.filter(p -> "manual".equals(p.get("generationMethod"))) .filter(p -> "manual".equals(p.get("generation_method")))
.toList(); .toList();
if (manualParts.isEmpty() || userInputCode == null) return new ArrayList<>(); if (manualParts.isEmpty() || userInputCode == null) return new ArrayList<>();
@@ -48,7 +48,7 @@ public class ReportService extends BaseService {
List<Object> menuObjids = new ArrayList<>(); List<Object> menuObjids = new ArrayList<>();
if (menuMappings != null) { if (menuMappings != null) {
for (Map<String, Object> m : menuMappings) { for (Map<String, Object> m : menuMappings) {
menuObjids.add(m.get("menuObjid") != null ? m.get("menuObjid") : m.get("menu_objid")); menuObjids.add(m.get("menu_objid"));
} }
} }
@@ -87,7 +87,7 @@ public class RoleService extends BaseService {
findParams.put("masterObjid", masterObjid); findParams.put("masterObjid", masterObjid);
List<Map<String, Object>> existingMembers = sqlSession.selectList("role.getRoleMemberList", findParams); List<Map<String, Object>> existingMembers = sqlSession.selectList("role.getRoleMemberList", findParams);
List<String> existingIds = existingMembers.stream() List<String> existingIds = existingMembers.stream()
.map(m -> (String) m.get("userId")) .map(m -> (String) m.get("user_id"))
.collect(Collectors.toList()); .collect(Collectors.toList());
// 추가할 멤버 // 추가할 멤버
@@ -197,7 +197,7 @@ public class ScheduleService extends BaseService {
if (deleteExisting && !toDelete.isEmpty()) { if (deleteExisting && !toDelete.isEmpty()) {
List<Integer> deleteIds = toDelete.stream() List<Integer> deleteIds = toDelete.stream()
.map(s -> { .map(s -> {
Object id = s.get("scheduleId") != null ? s.get("scheduleId") : s.get("schedule_id"); Object id = s.get("schedule_id");
return id != null ? ((Number) id).intValue() : null; return id != null ? ((Number) id).intValue() : null;
}) })
.filter(Objects::nonNull).collect(Collectors.toList()); .filter(Objects::nonNull).collect(Collectors.toList());
@@ -197,7 +197,7 @@ public class ScreenManagementService extends BaseService {
layoutParams.put("companyCode", companyCode); layoutParams.put("companyCode", companyCode);
List<Map<String, Object>> layouts = sqlSession.selectList(NS + "selectLayoutsV2ForFlowCleanup", layoutParams); List<Map<String, Object>> layouts = sqlSession.selectList(NS + "selectLayoutsV2ForFlowCleanup", layoutParams);
if (!layouts.isEmpty()) { if (!layouts.isEmpty()) {
Object layoutDataRaw = layouts.get(0).get("layoutData"); Object layoutDataRaw = layouts.get(0).get("layout_data");
Set<Integer> flowIds = collectFlowIds(layoutDataRaw); Set<Integer> flowIds = collectFlowIds(layoutDataRaw);
for (Integer flowId : flowIds) { for (Integer flowId : flowIds) {
Map<String, Object> usageParams = new HashMap<>(); Map<String, Object> usageParams = new HashMap<>();
@@ -274,7 +274,7 @@ public class ScreenManagementService extends BaseService {
if (screen == null) throw new IllegalArgumentException("화면을 찾을 수 없습니다."); if (screen == null) throw new IllegalArgumentException("화면을 찾을 수 없습니다.");
// 동일 screen_code가 이미 활성인지 체크 // 동일 screen_code가 이미 활성인지 체크
String screenCode = (String) screen.get("screenCode"); String screenCode = (String) screen.get("screen_code");
if (screenCode != null) { if (screenCode != null) {
Map<String, Object> ckParams = new HashMap<>(); Map<String, Object> ckParams = new HashMap<>();
ckParams.put("screenCode", screenCode); ckParams.put("screenCode", screenCode);
@@ -341,7 +341,7 @@ public class ScreenManagementService extends BaseService {
Pattern numPattern = Pattern.compile("^" + Pattern.quote(companyCode) + "_(\\d+)$"); Pattern numPattern = Pattern.compile("^" + Pattern.quote(companyCode) + "_(\\d+)$");
int maxNumber = existing.stream() int maxNumber = existing.stream()
.map(row -> String.valueOf(row.get("screenCode"))) .map(row -> String.valueOf(row.get("screen_code")))
.mapToInt(code -> { .mapToInt(code -> {
Matcher m = numPattern.matcher(code); Matcher m = numPattern.matcher(code);
return m.matches() ? Integer.parseInt(m.group(1)) : 0; return m.matches() ? Integer.parseInt(m.group(1)) : 0;
@@ -370,21 +370,21 @@ public class ScreenManagementService extends BaseService {
String newCode = generateScreenCode(companyCode); String newCode = generateScreenCode(companyCode);
Map<String, Object> insertParams = new HashMap<>(); Map<String, Object> insertParams = new HashMap<>();
insertParams.put("screenName", newName != null ? newName : original.get("screenName") + " Copy"); insertParams.put("screenName", newName != null ? newName : original.get("screen_name") + " Copy");
insertParams.put("screenCode", newCode); insertParams.put("screenCode", newCode);
insertParams.put("tableName", original.get("tableName")); insertParams.put("tableName", original.get("table_name"));
insertParams.put("companyCode", companyCode); insertParams.put("companyCode", companyCode);
insertParams.put("description", original.get("description")); insertParams.put("description", original.get("description"));
insertParams.put("createdBy", userId); insertParams.put("createdBy", userId);
insertParams.put("dbSourceType", original.get("dbSourceType")); insertParams.put("dbSourceType", original.get("db_source_type"));
insertParams.put("dbConnectionId", original.get("dbConnectionId")); insertParams.put("dbConnectionId", original.get("db_connection_id"));
insertParams.put("dataSourceType", original.get("dataSourceType")); insertParams.put("dataSourceType", original.get("data_source_type"));
insertParams.put("restApiConnectionId", original.get("restApiConnectionId")); insertParams.put("restApiConnectionId", original.get("rest_api_connection_id"));
insertParams.put("restApiEndpoint", original.get("restApiEndpoint")); insertParams.put("restApiEndpoint", original.get("rest_api_endpoint"));
insertParams.put("restApiJsonPath", original.get("restApiJsonPath")); insertParams.put("restApiJsonPath", original.get("rest_api_json_path"));
Map<String, Object> newScreen = sqlSession.selectOne(NS + "insertScreenCopy", insertParams); Map<String, Object> newScreen = sqlSession.selectOne(NS + "insertScreenCopy", insertParams);
Integer newScreenId = toInteger(newScreen.get("screenId")); Integer newScreenId = toInteger(newScreen.get("screen_id"));
// Layout V1 복사 // Layout V1 복사
List<Map<String, Object>> v1Rows = sqlSession.selectList(NS + "selectLayoutV1ForCopy", Map.of("screenId", screenId)); List<Map<String, Object>> v1Rows = sqlSession.selectList(NS + "selectLayoutV1ForCopy", Map.of("screenId", screenId));
@@ -414,7 +414,7 @@ public class ScreenManagementService extends BaseService {
// 메인 화면 복사 // 메인 화면 복사
Map<String, Object> mainScreen = copyScreen(screenId, newBaseName, companyCode, userId); Map<String, Object> mainScreen = copyScreen(screenId, newBaseName, companyCode, userId);
Integer newMainScreenId = toInteger(mainScreen.get("screenId")); Integer newMainScreenId = toInteger(mainScreen.get("screen_id"));
// 연결된 모달 화면들 탐색 복사 // 연결된 모달 화면들 탐색 복사
List<Map<String, Object>> linkedScreens = detectLinkedScreensInternal(screenId, companyCode); List<Map<String, Object>> linkedScreens = detectLinkedScreensInternal(screenId, companyCode);
@@ -423,10 +423,10 @@ public class ScreenManagementService extends BaseService {
List<Map<String, Object>> copiedScreens = new ArrayList<>(); List<Map<String, Object>> copiedScreens = new ArrayList<>();
for (Map<String, Object> linked : linkedScreens) { for (Map<String, Object> linked : linkedScreens) {
Integer linkedId = toInteger(linked.get("screenId")); Integer linkedId = toInteger(linked.get("screen_id"));
String linkedName = (String) linked.get("screenName"); String linkedName = (String) linked.get("screen_name");
Map<String, Object> copied = copyScreen(linkedId, linkedName + " Copy", companyCode, userId); Map<String, Object> copied = copyScreen(linkedId, linkedName + " Copy", companyCode, userId);
idMapping.put(linkedId, toInteger(copied.get("screenId"))); idMapping.put(linkedId, toInteger(copied.get("screen_id")));
copiedScreens.add(copied); copiedScreens.add(copied);
} }
@@ -730,10 +730,10 @@ public class ScreenManagementService extends BaseService {
// screen_code 조회 menu_info 업데이트 // screen_code 조회 menu_info 업데이트
Map<String, Object> screenCodeRow = sqlSession.selectOne(NS + "selectScreenCode", Map.of("screenId", screenId)); Map<String, Object> screenCodeRow = sqlSession.selectOne(NS + "selectScreenCode", Map.of("screenId", screenId));
String screenCode = screenCodeRow != null ? (String) screenCodeRow.get("screenCode") : null; String screenCode = screenCodeRow != null ? (String) screenCodeRow.get("screen_code") : null;
Map<String, Object> menuTypeRow = sqlSession.selectOne(NS + "selectMenuType", Map.of("menuObjid", menuObjid)); Map<String, Object> menuTypeRow = sqlSession.selectOne(NS + "selectMenuType", Map.of("menuObjid", menuObjid));
String menuType = menuTypeRow != null ? (String) menuTypeRow.get("menuType") : null; String menuType = menuTypeRow != null ? (String) menuTypeRow.get("menu_type") : null;
if (screenCode != null) { if (screenCode != null) {
String menuUrl = "/screen/" + screenCode; String menuUrl = "/screen/" + screenCode;
@@ -816,10 +816,10 @@ public class ScreenManagementService extends BaseService {
int count = 0; int count = 0;
for (Map<String, Object> a : assignments) { for (Map<String, Object> a : assignments) {
Map<String, Object> ip = new HashMap<>(); Map<String, Object> ip = new HashMap<>();
ip.put("screenId", a.get("screenId")); ip.put("screenId", a.get("screen_id"));
ip.put("menuObjid", a.get("menuObjid")); ip.put("menuObjid", a.get("menu_objid"));
ip.put("companyCode", targetCompanyCode); ip.put("companyCode", targetCompanyCode);
ip.put("displayOrder", a.get("displayOrder")); ip.put("displayOrder", a.get("display_order"));
ip.put("createdBy", userId); ip.put("createdBy", userId);
sqlSession.insert(NS + "insertMenuAssignmentCopy", ip); sqlSession.insert(NS + "insertMenuAssignmentCopy", ip);
count++; count++;
@@ -845,7 +845,7 @@ public class ScreenManagementService extends BaseService {
Map<String, Object> codeParams = new HashMap<>(); Map<String, Object> codeParams = new HashMap<>();
codeParams.put("sourceCompanyCode", sourceCompanyCode); codeParams.put("sourceCompanyCode", sourceCompanyCode);
codeParams.put("codeCategory", cat.get("categoryCode")); codeParams.put("codeCategory", cat.get("category_code"));
List<Map<String, Object>> codes = sqlSession.selectList(NS + "selectCodeInfoForCopy", codeParams); List<Map<String, Object>> codes = sqlSession.selectList(NS + "selectCodeInfoForCopy", codeParams);
for (Map<String, Object> code : codes) { for (Map<String, Object> code : codes) {
Map<String, Object> cop = new HashMap<>(code); Map<String, Object> cop = new HashMap<>(code);
@@ -927,7 +927,7 @@ public class ScreenManagementService extends BaseService {
List<Integer> linkedScreenIds = new ArrayList<>(); List<Integer> linkedScreenIds = new ArrayList<>();
if (popLayout != null) { if (popLayout != null) {
Object layoutDataRaw = popLayout.get("layoutData"); Object layoutDataRaw = popLayout.get("layout_data");
linkedScreenIds = extractScreenIdsFromLayout(layoutDataRaw); linkedScreenIds = extractScreenIdsFromLayout(layoutDataRaw);
} }
@@ -974,9 +974,9 @@ public class ScreenManagementService extends BaseService {
insertParams.put("dbSourceType", screenDef.get("dbSourceType")); insertParams.put("dbSourceType", screenDef.get("dbSourceType"));
insertParams.put("dataSourceType", screenDef.get("dataSourceType")); insertParams.put("dataSourceType", screenDef.get("dataSourceType"));
Map<String, Object> created = sqlSession.selectOne(NS + "insertScreenForDeploy", insertParams); Map<String, Object> created = sqlSession.selectOne(NS + "insertScreenForDeploy", insertParams);
targetScreenId = toInteger(created.get("screenId")); targetScreenId = toInteger(created.get("screen_id"));
} else { } else {
targetScreenId = toInteger(existing.get("screenId")); targetScreenId = toInteger(existing.get("screen_id"));
} }
// POP 레이아웃 복사 // POP 레이아웃 복사
@@ -989,7 +989,7 @@ public class ScreenManagementService extends BaseService {
Map<String, Object> deployParams = new HashMap<>(); Map<String, Object> deployParams = new HashMap<>();
deployParams.put("screenId", targetScreenId); deployParams.put("screenId", targetScreenId);
deployParams.put("companyCode", targetCompanyCode); deployParams.put("companyCode", targetCompanyCode);
deployParams.put("layoutData", toJsonString(sourceLayout.get("layoutData"))); deployParams.put("layoutData", toJsonString(sourceLayout.get("layout_data")));
deployParams.put("userId", userId); deployParams.put("userId", userId);
sqlSession.insert(NS + "upsertPopLayoutDeploy", deployParams); sqlSession.insert(NS + "upsertPopLayoutDeploy", deployParams);
} }
@@ -1136,7 +1136,7 @@ public class ScreenManagementService extends BaseService {
String updated = replaceScreenIdsInJson(propsRaw.toString(), idMapping); String updated = replaceScreenIdsInJson(propsRaw.toString(), idMapping);
if (updated != null) { if (updated != null) {
Map<String, Object> up = new HashMap<>(); Map<String, Object> up = new HashMap<>();
up.put("layoutId", layout.get("layoutId")); up.put("layoutId", layout.get("layout_id"));
up.put("properties", updated); up.put("properties", updated);
sqlSession.update(NS + "updateLayoutV1Properties", up); sqlSession.update(NS + "updateLayoutV1Properties", up);
} }
@@ -1145,14 +1145,14 @@ public class ScreenManagementService extends BaseService {
// V2 // V2
List<Map<String, Object>> v2Layouts = sqlSession.selectList(NS + "selectLayoutsV2ForScreen", p); List<Map<String, Object>> v2Layouts = sqlSession.selectList(NS + "selectLayoutsV2ForScreen", p);
for (Map<String, Object> layout : v2Layouts) { for (Map<String, Object> layout : v2Layouts) {
Object dataRaw = layout.get("layoutData"); Object dataRaw = layout.get("layout_data");
if (dataRaw == null) continue; if (dataRaw == null) continue;
String updated = replaceScreenIdsInJson(dataRaw.toString(), idMapping); String updated = replaceScreenIdsInJson(dataRaw.toString(), idMapping);
if (updated != null) { if (updated != null) {
Map<String, Object> up = new HashMap<>(); Map<String, Object> up = new HashMap<>();
up.put("screenId", layout.get("screenId")); up.put("screenId", layout.get("screen_id"));
up.put("layerId", layout.get("layerId")); up.put("layerId", layout.get("layer_id"));
up.put("companyCode", layout.get("companyCode")); up.put("companyCode", layout.get("company_code"));
up.put("layoutData", updated); up.put("layoutData", updated);
sqlSession.update(NS + "updateLayoutV2Data", up); sqlSession.update(NS + "updateLayoutV2Data", up);
} }
@@ -1179,7 +1179,7 @@ public class ScreenManagementService extends BaseService {
private void enrichWithTableLabels(List<Map<String, Object>> screens) { private void enrichWithTableLabels(List<Map<String, Object>> screens) {
Set<String> tableNames = new LinkedHashSet<>(); Set<String> tableNames = new LinkedHashSet<>();
for (Map<String, Object> s : screens) { for (Map<String, Object> s : screens) {
Object tn = s.get("tableName"); Object tn = s.get("table_name");
if (tn != null && !tn.toString().isBlank()) tableNames.add(tn.toString()); if (tn != null && !tn.toString().isBlank()) tableNames.add(tn.toString());
} }
if (tableNames.isEmpty()) return; if (tableNames.isEmpty()) return;
@@ -1190,10 +1190,10 @@ public class ScreenManagementService extends BaseService {
List<Map<String, Object>> labels = sqlSession.selectList(NS + "selectTableLabelsByNames", params); List<Map<String, Object>> labels = sqlSession.selectList(NS + "selectTableLabelsByNames", params);
Map<String, String> labelMap = new HashMap<>(); Map<String, String> labelMap = new HashMap<>();
for (Map<String, Object> row : labels) { for (Map<String, Object> row : labels) {
labelMap.put((String) row.get("tableName"), (String) row.get("tableLabel")); labelMap.put((String) row.get("table_name"), (String) row.get("table_label"));
} }
for (Map<String, Object> s : screens) { for (Map<String, Object> s : screens) {
Object tn = s.get("tableName"); Object tn = s.get("table_name");
if (tn != null) s.put("tableLabel", labelMap.get(tn.toString())); if (tn != null) s.put("tableLabel", labelMap.get(tn.toString()));
} }
} catch (Exception ignored) {} } catch (Exception ignored) {}
@@ -1207,7 +1207,7 @@ public class ScreenManagementService extends BaseService {
Pattern numPattern = Pattern.compile("^" + Pattern.quote(companyCode) + "_(\\d+)$"); Pattern numPattern = Pattern.compile("^" + Pattern.quote(companyCode) + "_(\\d+)$");
int maxNumber = existing.stream() int maxNumber = existing.stream()
.map(row -> String.valueOf(row.get("screenCode"))) .map(row -> String.valueOf(row.get("screen_code")))
.mapToInt(code -> { .mapToInt(code -> {
Matcher m = numPattern.matcher(code); Matcher m = numPattern.matcher(code);
return m.matches() ? Integer.parseInt(m.group(1)) : 0; return m.matches() ? Integer.parseInt(m.group(1)) : 0;
@@ -1224,7 +1224,7 @@ public class ScreenManagementService extends BaseService {
params.put("screenId", screenId); params.put("screenId", screenId);
params.put("companyCode", companyCode); params.put("companyCode", companyCode);
Map<String, Object> row = sqlSession.selectOne(NS + "selectMaxLayerId", params); Map<String, Object> row = sqlSession.selectOne(NS + "selectMaxLayerId", params);
int maxId = row != null ? toInt(row.getOrDefault("maxId", 1), 1) : 1; int maxId = row != null ? toInt(row.getOrDefault("max_id", 1), 1) : 1;
return maxId + 1; return maxId + 1;
} }
@@ -97,9 +97,9 @@ public class TableCategoryValueService extends BaseService {
Map.of("valueId", valueId)); Map.of("valueId", valueId));
if (current != null) { if (current != null) {
Map<String, Object> labelP = new HashMap<>(); Map<String, Object> labelP = new HashMap<>();
labelP.put("tableName", current.get("tableName")); labelP.put("tableName", current.get("table_name"));
labelP.put("columnName", current.get("columnName")); labelP.put("columnName", current.get("column_name"));
labelP.put("companyCode", current.get("companyCode")); labelP.put("companyCode", current.get("company_code"));
labelP.put("valueLabel", params.get("valueLabel")); labelP.put("valueLabel", params.get("valueLabel"));
labelP.put("valueId", valueId); labelP.put("valueId", valueId);
Integer dup = sqlSession.selectOne(NS + "countDuplicateLabelExcludeSelf", labelP); Integer dup = sqlSession.selectOne(NS + "countDuplicateLabelExcludeSelf", labelP);
@@ -137,7 +137,7 @@ public class TableCategoryValueService extends BaseService {
List<Map<String, Object>> childRows = sqlSession.selectList(NS + "getChildValueIdList", params); List<Map<String, Object>> childRows = sqlSession.selectList(NS + "getChildValueIdList", params);
List<Long> allIds = new ArrayList<>(); List<Long> allIds = new ArrayList<>();
allIds.add(valueId); allIds.add(valueId);
childRows.forEach(r -> allIds.add(toLong(r.get("valueId")))); childRows.forEach(r -> allIds.add(toLong(r.get("value_id"))));
log.info("삭제 대상 카테고리 값 수집 완료: 자신={}, 하위={}", valueId, childRows.size()); log.info("삭제 대상 카테고리 값 수집 완료: 자신={}, 하위={}", valueId, childRows.size());
@@ -192,8 +192,8 @@ public class TableCategoryValueService extends BaseService {
Map<String, Object> mapping = new LinkedHashMap<>(); Map<String, Object> mapping = new LinkedHashMap<>();
for (Map<String, Object> row : rows) { for (Map<String, Object> row : rows) {
mapping.put(String.valueOf(row.get("logicalColumnName")), mapping.put(String.valueOf(row.get("logical_column_name")),
String.valueOf(row.get("physicalColumnName"))); String.valueOf(row.get("physical_column_name")));
} }
log.info("컬럼 매핑 {}개 조회 완료", mapping.size()); log.info("컬럼 매핑 {}개 조회 완료", mapping.size());
return mapping; return mapping;
@@ -261,9 +261,9 @@ public class TableCategoryValueService extends BaseService {
Map<String, Object> labels = new LinkedHashMap<>(); Map<String, Object> labels = new LinkedHashMap<>();
for (Map<String, Object> row : rows) { for (Map<String, Object> row : rows) {
String code = String.valueOf(row.get("valueCode")); String code = String.valueOf(row.get("value_code"));
if (!labels.containsKey(code)) { if (!labels.containsKey(code)) {
labels.put(code, row.get("valueLabel")); labels.put(code, row.get("value_label"));
} }
} }
log.info("카테고리 라벨 {}개 조회 완료", labels.size()); log.info("카테고리 라벨 {}개 조회 완료", labels.size());
@@ -300,10 +300,10 @@ public class TableCategoryValueService extends BaseService {
throw new IllegalArgumentException("카테고리 값을 찾을 수 없습니다"); throw new IllegalArgumentException("카테고리 값을 찾을 수 없습니다");
} }
String tableName = String.valueOf(valueInfo.get("tableName")); String tableName = String.valueOf(valueInfo.get("table_name"));
String columnName = String.valueOf(valueInfo.get("columnName")); String columnName = String.valueOf(valueInfo.get("column_name"));
String valueCode = String.valueOf(valueInfo.get("valueCode")); String valueCode = String.valueOf(valueInfo.get("value_code"));
String valueLabel = String.valueOf(valueInfo.get("valueLabel")); String valueLabel = String.valueOf(valueInfo.get("value_label"));
String safeTable = sanitize(tableName); String safeTable = sanitize(tableName);
String safeColumn = sanitize(columnName); String safeColumn = sanitize(columnName);
@@ -331,7 +331,7 @@ public class TableCategoryValueService extends BaseService {
if (!menus.isEmpty()) { if (!menus.isEmpty()) {
String menuNames = menus.stream() String menuNames = menus.stream()
.map(m -> String.valueOf(m.get("menuName"))) .map(m -> String.valueOf(m.get("menu_name")))
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
msg.append("\n\n다음 메뉴에서 사용 중입니다:\n").append(menuNames); msg.append("\n\n다음 메뉴에서 사용 중입니다:\n").append(menuNames);
} }
@@ -345,9 +345,9 @@ public class TableCategoryValueService extends BaseService {
List<Map<String, Object>> values, Object parentId) { List<Map<String, Object>> values, Object parentId) {
List<Map<String, Object>> result = new ArrayList<>(); List<Map<String, Object>> result = new ArrayList<>();
for (Map<String, Object> v : values) { for (Map<String, Object> v : values) {
Object pid = v.get("parentValueId"); Object pid = v.get("parent_value_id");
if (Objects.equals(pid, parentId)) { if (Objects.equals(pid, parentId)) {
List<Map<String, Object>> children = buildHierarchy(values, v.get("valueId")); List<Map<String, Object>> children = buildHierarchy(values, v.get("value_id"));
v.put("children", children); v.put("children", children);
result.add(v); result.add(v);
} }
@@ -32,10 +32,10 @@ public class TableManagementService extends BaseService {
public List<Map<String, Object>> getTableList() { public List<Map<String, Object>> getTableList() {
List<Map<String, Object>> tables = sqlSession.selectList(NS + "getTableList"); List<Map<String, Object>> tables = sqlSession.selectList(NS + "getTableList");
// columnCount BigInt Integer 변환 // column_count BigInt Integer 변환
for (Map<String, Object> t : tables) { for (Map<String, Object> t : tables) {
Object cnt = t.get("columnCount"); Object cnt = t.get("column_count");
if (cnt instanceof Number) t.put("columnCount", ((Number) cnt).intValue()); if (cnt instanceof Number) t.put("column_count", ((Number) cnt).intValue());
} }
return tables; return tables;
} }
@@ -234,7 +234,7 @@ public class TableManagementService extends BaseService {
Map<String, Object> primaryKey = new HashMap<>(); Map<String, Object> primaryKey = new HashMap<>();
if (!pkResult.isEmpty()) { if (!pkResult.isEmpty()) {
Map<String, Object> pk = pkResult.get(0); Map<String, Object> pk = pkResult.get(0);
primaryKey.put("name", pk.get("constraintName")); primaryKey.put("name", pk.get("constraint_name"));
primaryKey.put("columns", parseColumnArray(pk.get("columns"))); primaryKey.put("columns", parseColumnArray(pk.get("columns")));
} else { } else {
primaryKey.put("name", ""); primaryKey.put("name", "");
@@ -244,9 +244,9 @@ public class TableManagementService extends BaseService {
List<Map<String, Object>> indexResult = sqlSession.selectList(NS + "getTableIndexList", params); List<Map<String, Object>> indexResult = sqlSession.selectList(NS + "getTableIndexList", params);
List<Map<String, Object>> indexes = indexResult.stream().map(row -> { List<Map<String, Object>> indexes = indexResult.stream().map(row -> {
Map<String, Object> idx = new HashMap<>(); Map<String, Object> idx = new HashMap<>();
idx.put("name", row.get("indexName")); idx.put("name", row.get("index_name"));
idx.put("columns", parseColumnArray(row.get("columns"))); idx.put("columns", parseColumnArray(row.get("columns")));
idx.put("isUnique", row.get("isUnique")); idx.put("isUnique", row.get("is_unique"));
return idx; return idx;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@@ -264,7 +264,7 @@ public class TableManagementService extends BaseService {
params.put("tableName", safeTable); params.put("tableName", safeTable);
List<Map<String, Object>> existingPk = sqlSession.selectList(NS + "getTablePrimaryKeyList", params); List<Map<String, Object>> existingPk = sqlSession.selectList(NS + "getTablePrimaryKeyList", params);
if (!existingPk.isEmpty()) { if (!existingPk.isEmpty()) {
String constraintName = (String) existingPk.get(0).get("constraintName"); String constraintName = (String) existingPk.get(0).get("constraint_name");
jdbcTemplate.execute( jdbcTemplate.execute(
String.format("ALTER TABLE \"public\".\"%s\" DROP CONSTRAINT \"%s\"", String.format("ALTER TABLE \"public\".\"%s\" DROP CONSTRAINT \"%s\"",
safeTable, sanitize(constraintName))); safeTable, sanitize(constraintName)));
@@ -343,7 +343,7 @@ public class TableManagementService extends BaseService {
List<String> violations = new ArrayList<>(); List<String> violations = new ArrayList<>();
for (Map<String, Object> col : notNullCols) { for (Map<String, Object> col : notNullCols) {
String colName = (String) col.get("columnName"); String colName = (String) col.get("column_name");
Object val = data.get(colName); Object val = data.get(colName);
if (val == null || val.toString().isBlank()) { if (val == null || val.toString().isBlank()) {
violations.add(colName); violations.add(colName);
@@ -365,7 +365,7 @@ public class TableManagementService extends BaseService {
List<String> violations = new ArrayList<>(); List<String> violations = new ArrayList<>();
for (Map<String, Object> col : uniqueCols) { for (Map<String, Object> col : uniqueCols) {
String colName = (String) col.get("columnName"); String colName = (String) col.get("column_name");
Object val = data.get(colName); Object val = data.get(colName);
if (val == null) continue; if (val == null) continue;

Some files were not shown because too many files have changed in this diff Show More