- BatchService: insertBatch/updateBatch 가 body.mappings 받아 replace-all 동기화, getBatchInfo 가 batch_mappings 리스트 attach (지금까지는 silently drop) - batch.xml: getBatchMappingsByConfigId / insertBatchMapping / deleteBatchMappingsByConfigId 신규 - batchExecutionLog.xml / batchManagement.xml: batch_config_id 에 ::varchar 캐스팅, 오타 'batch_execution_log' → 'batch_execution_logs' 정정 - batchmngList/page.tsx: 같은 batch ID 가 회사 간 중복될 때 React key 충돌 방지 - notes: vexplor_rps → INVYONE 배치 파이프라인 이식 분석 노트 vexplor_rps → INVYONE 파이프라인 이식의 Phase 0. 구체 분해는 notes/hjjeong/2026-05-12-batch-pipeline-current-state.md 참조. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
배치/파이프라인 이식 작업 분석 (2026-05-12)
작성자: hjjeong
배경: 박창현 팀장님(chpark) 카톡 (2026-05-11)
"그 수집관리 쪽은 파이프라인 쪽 가져와야 하는데. 빠이프. 내가 파이프 커밋해둠." "DB 라던지 restapi 라던지 소스 데이터 가져온뒤에 우리 db에 적재할 때, 원본 소스의 값이 1 인데 우리 시스템은 Y 일경우 → 조건변환을 통해서 변경된 값으로 우리 db에 적재."
한 줄 요약
팀장님이 만들어두신 "파이프" 는 /Users/jhj/vexplor_rps/ (별도 저장소) 에 있는 완성된 ETL 코드. INVYONE 으로 옮기는 작업은 Node.js → Spring 재작성 + 일부 Frontend 보강 + DB 스키마 한 컬럼 추가가 필요하다.
1. 도메인 매트릭스 — INVYONE 의 현재 상태
INVYONE 안에 비슷한 이름의 도메인이 셋이고, 셋 다 데이터 이동 실행 로직이 비어있다.
| 도메인 | 메뉴 | 페이지 | 상태 |
|---|---|---|---|
| 배치관리 (구) | /admin/batch-management |
page.tsx 206줄 | 모달 기반 db-to-db 만 |
| 배치관리 (신) | /admin/automaticMng/batchmngList |
edit/[id]/page.tsx 1850줄 | 매핑 UI 풍부 — 저장도 실행도 안 됨 |
| 수집관리 | /admin/systemMng/collection-managementList |
page.tsx | executeCollection 이 jobs 테이블에 빈 행 INSERT 후 records_processed=0 박고 종료 |
| 제어관리 (파이프라인) | /admin/systemMng/dataflow/... |
DataFlowDesigner.tsx | 노드 그래프 UI. flow_data JSONB 저장만. 실행 엔진 없음 |
→ 팀장님 카톡 의미: 수집관리 + 배치관리 양쪽에 파이프라인(변환/실행) 기능을 가져와야 한다.
2. 진짜 파이프라인 코드 위치 — /Users/jhj/vexplor_rps/
별도 git 저장소. INVYONE 의 _pipeline_backup/ 폴더와는 무관(그건 mcp-agent-orchestrator 실행 기록).
Backend — vexplor_rps/backend-node/ (TypeScript/Node.js)
| 파일 | 역할 |
|---|---|
src/services/batchSchedulerService.ts |
ETL 본체. executeMapping() 함수가 FROM 읽기 → 변환 → TO 저장 3단계 실행 |
src/services/batchManagementService.ts |
외부 DB 커넥터 (PG/MySQL/Oracle/MSSQL 등) |
src/services/erpApiClient.ts (226줄) |
Wehago/Amaranth ERP REST API 호출, HMAC-SHA256 서명 |
src/services/erpBatchSeedService.ts (429줄) |
6종 매칭 배치 자동 시드 |
src/services/erpPresetSeedService.ts (158줄) |
REST API 연결 사전 설정 |
src/services/erpSyncService.ts (539줄) |
동기화 로직 |
src/services/erpTableMigration.ts (172줄) |
Idempotent 마이그레이션 |
executeMapping() 핵심 흐름 (batchSchedulerService.ts)
L291~500 FROM 읽기 — 연결별 테이블 그룹화 후 batch fetch
├ internal: PostgreSQL 직접 쿼리
├ external_db: DatabaseConnectorFactory 동적 커넥터
└ restapi: GET/POST 응답 + dataArrayPath 추출
L550~596 매핑 변환 — row.map() 안에서 mapping_type 분기
├ "direct": row[from] → to (그대로 복사)
├ "fixed": from_column_name 자체가 고정값
└ "conditional": when/then 매칭 + default ← 1→Y 변환
L619~ TO 저장
├ DB: INSERT 또는 UPSERT (save_mode 기반)
└ REST: POST/PUT/DELETE + Request Body 템플릿
Frontend — vexplor_rps/frontend/
| 파일 | 역할 |
|---|---|
app/(main)/admin/batch-management-new/page.tsx (1865줄) |
배치 에디터 UI 본체. 좌우 2패널 + 매핑 그리드 + ConditionalEditor |
lib/api/batch.ts, batchManagement.ts |
API 클라이언트 + 타입 정의 |
INVYONE 의 batchmngList/edit/[id]/page.tsx (1850줄) 가 vexplor_rps 의 그것과 거의 동일 구조 — 팀장님이 INVYONE 으로 한 번 옮긴 흔적. 다만 mapping_type='conditional' 분기와 ConditionalEditor 가 빠져있다.
3. 조건 변환 자료구조
매핑 row 데이터 모델
{
id: string,
batch_config_id: string,
from_connection_type: "internal" | "external_db" | "restapi",
from_table_name: string,
from_column_name: string,
to_connection_type: "internal" | "external_db" | "restapi",
to_table_name: string,
to_column_name: string,
mapping_order: number,
mapping_type: "direct" | "fixed" | "conditional", // ← 핵심
mapping_config: ConditionalConfig | null, // ← 신규 컬럼 필요
// ... API 매핑용 (from_api_url, to_api_body 등)
}
ConditionalConfig (mapping_type='conditional' 일 때)
interface ConditionalConfig {
rules: { when: string; then: string }[];
default: string;
}
평가 알고리즘 (단순 문자열 매칭)
function evaluateConditional(sourceVal: string, cfg: ConditionalConfig): string {
for (const rule of cfg.rules) {
if (rule.when === sourceVal) return rule.then;
}
return cfg.default;
}
표현식 평가(SpEL/JEXL) 안 씀. Java 로 옮길 때 Map<String,String> + getOrDefault 한 줄이면 끝.
예시 (팀장님 카톡: 1 → Y)
{
"mapping_type": "conditional",
"mapping_config": {
"rules": [
{ "when": "1", "then": "Y" },
{ "when": "0", "then": "N" }
],
"default": "?"
}
}
4. chpark 결정적 커밋 목록 (vexplor_rps)
2026-05-12 945b65b8 시퀀스 관리 메뉴 + 테이블 타입관리 코멘트/검증 + 설계 문서
2026-05-11 a61643c2 Merge origin/main
2026-05-08 57509869 배치 편집 conditional 매핑 평가 필드 UX 개선 ⭐
2026-05-08 40070423 ECR · 고객 CS · 결재 + Amaranth + wace_plm 데이터 import
2026-05-07 638543b3 Merge feature/rps-rebrand-pipeline-design ⭐
2026-05-07 97b333dd Amaranth(Wehago) ERP REST API 연계 + 배치 시스템 강화 ⭐
2026-04-30 9a8196a3 RPS 브랜딩 · COMPANY_16 단독 운영 · Pipeline 디자인 채용
결정적 커밋 분석
| 해시 | 일자 | 내용 |
|---|---|---|
| 97b333dd | 5/7 | 배치 시스템 본체 강화 (conditional mapping, row_filter, UPSERT) + ERP 연계 |
| 638543b3 | 5/7 | feature/rps-rebrand-pipeline-design 브랜치 머지 (Pipeline 디자인 반영) |
| 57509869 | 5/8 | conditional 매핑의 "평가 필드" 필수 표기 UX 개선 (1파일 +27/−13) |
→ conditional 매핑 본체 구현은 97b333dd (5/7), 57509869 는 그 위에 UX 보완.
5. INVYONE 이식 작업
5-1. Backend (Spring 재작성)
| vexplor_rps (Node.js) | INVYONE (Spring) 대응 | 분량 |
|---|---|---|
batchSchedulerService.executeMapping() |
신규 BatchExecutor.java (@Service, BaseService 상속) |
~2주 |
| 외부 DB 커넥터 | 이미 일부 있음 (ExternalDbConnectionService) | ~3일 |
| REST API 호출 | 이미 있음 (ExternalRestApiConnectionService) | 통합만 |
evaluateConditional() |
MappingTransformer.java (Map 기반 lookup) |
~반나절 |
| Quartz 스케줄링 | INVYONE 에 이미 Quartz 도입됨 (V012__create_quartz_tables.sql) |
통합만 |
| ERP 사전 시드 / HMAC | 선택적 (Phase 4) | 1주+ |
5-2. Frontend
| 작업 | 위치 | 분량 |
|---|---|---|
ConditionalEditor 컴포넌트 신규 |
components/admin/batch/ConditionalEditor.tsx (신규) |
1일 |
매핑 row 에 sourceType='conditional' 옵션 + mapping_config 필드 |
batchmngList/edit/[id]/page.tsx |
1일 |
| API 타입 확장 | lib/api/batch.ts |
0.5일 |
5-3. DB 스키마 변경
| 컬럼 | 필요 여부 |
|---|---|
batch_mappings.mapping_type |
이미 있음 (현재 'direct' 값만 사용) |
batch_mappings.mapping_config JSONB |
추가 필요 (conditional_config 저장) |
batch_mappings.row_filter JSONB |
(선택) row 단위 필터링 룰. vexplor_rps 에 있음 |
마이그레이션: Flyway V021 + StartupSchemaMigrator 양쪽에.
5-4. INVYONE 측 선결과제 (Phase 0)
vexplor_rps 의 이식 외에도 INVYONE 자체의 매핑 path 가 비어있는 문제 가 별도. 이 Phase 0 가 없으면 conditional 룰을 만들어도 저장 안 됨.
| 작업 | 비고 |
|---|---|
batch_mappings INSERT/UPDATE/DELETE 매퍼 작성 |
현재 0건 |
getBatchInfo 응답에 batch_mappings 포함 (LEFT JOIN 또는 별도 query) |
현재 BATCH_CONFIGS 만 SELECT |
BatchManagementService.updateBatchConfig 가 body 의 mappings 받아 batch_mappings 동기화 |
현재 silently drop |
executeBatchConfig 가 BatchExecutor 호출 |
현재 stub, 0건 응답 |
6. Phase 분해 (재추정)
| Phase | 작업 | 분량 |
|---|---|---|
| 0 | INVYONE 의 batch_mappings CRUD path 구현 + GET 응답 포함 + PUT 동기화 |
3일 |
| 1 | mapping_config JSONB 컬럼 추가 (Flyway V021 + StartupSchemaMigrator) |
0.5일 |
| 2 | Frontend ConditionalEditor + sourceType='conditional' 분기 + API 타입 확장 |
2일 |
| 3 | Backend MappingTransformer (lookup 엔진) |
0.5일 |
| 4 | Backend BatchExecutor 작성 — vexplor_rps executeMapping 알고리즘 1:1 이식 (FROM→Transform→TO 3단계, 내부/외부 DB/REST 모두 지원) |
2주 |
| 5 | executeBatchConfig 가 BatchExecutor 호출, 실행 로그 (batch_execution_logs) 기록 |
3일 |
| 6 | (선택) ERP 사전 시드, HMAC 서명, 6종 배치 자동 부팅 | 1주+ |
합계 (Phase 05): 약 **34주** (1인 기준, 테스트·QA 제외). Phase 6 는 별도.
7. 팀장님께 확인하면 좋을 항목
- vexplor_rps 의
batchSchedulerService.ts알고리즘을 1:1 이식하는 게 맞나 — 아니면 더 단순화/확장된 버전을 원하시는지 - conditional 외에 다른 mapping_type 도 필요한가 — row_filter, expression eval 등
- ERP 시드 (Phase 6) 도 이번 스프린트 범위인가 — 아니면 Phase 0~5 만
- 수집관리(
collection-managementList) 와 배치관리(batchmngList) 가 같은 코드 공유해도 되는지 — UI 두 군데에 둘 다 노출인지 mapping_config컬럼명 선호 — 다른 컨벤션이 있다면
부록 A. 분석 시 사용한 주요 파일
INVYONE 측
BatchController.javaBatchManagementController.javaBatchService.javaBatchManagementService.javaCollectionService.javaNodeFlowService.javamapper/batch.xmlmapper/collection.xmlmapper/batchManagement.xmlmapper/nodeFlow.xmlfrontend/app/(main)/admin/automaticMng/batchmngList/frontend/app/(main)/admin/systemMng/collection-managementList/frontend/app/(main)/admin/systemMng/dataflow/frontend/components/dataflow/DataFlowDesigner.tsx
vexplor_rps 측 (별도 저장소)
/Users/jhj/vexplor_rps/backend-node/src/services/batchSchedulerService.ts/Users/jhj/vexplor_rps/backend-node/src/services/batchManagementService.ts/Users/jhj/vexplor_rps/backend-node/src/services/erp*.ts/Users/jhj/vexplor_rps/frontend/app/(main)/admin/batch-management-new/page.tsx
운영 DB
batch_configs,batch_mappings(스키마 ok / 운영 데이터 ok / backend 처리 없음),batch_execution_logs,node_flow,data_collection_configs
부록 B. INVYONE batch_mappings 운영 데이터 현황
batch_config_id | count
----------------+------
5 | 5
10 | 4
18 | 4
20 | 2
21 | 4
28 | 1
30 | 1
31 | 2
32 | 2
37 | 4
created_date 가 2025-09 등으로 오래된 행 다수. 현 backend 코드는 이 데이터를 읽지도 쓰지도 못함 — 사실상 dead data. vexplor_rps 시절 또는 옛 Node.js 시절의 흔적으로 추정.