style(rolesList): 다른 메뉴 톤에 맞춰 사이즈/글씨 축소 #12
Reference in New Issue
Block a user
Delete Branch "hjjeong"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
- V021 Flyway: ALTER TABLE BATCH_MAPPINGS ADD COLUMN MAPPING_CONFIG JSONB - StartupSchemaMigrator: 같은 ALTER 를 idempotent 항목으로 추가 (모든 활성 테넌트 DB 부팅 시 동기화) - batch.xml: getBatchMappingsByConfigId SELECT 에 MAPPING_CONFIG::TEXT cast, insertBatchMapping VALUES 에 #{mapping_config,jdbcType=OTHER}::jsonb - BatchService: ObjectMapper 주입, parseJsonField/stringifyJsonField 유틸, syncMappings 는 INSERT 전 직렬화, attachMappings 는 SELECT 후 Map 으로 역직렬화 - RUN_087_MIGRATION.md: 운영용 마이그레이션 runbook (사전 점검/사후 검증/롤백) conditional 매핑(when/then/default) 룰을 행 단위 저장하는 컬럼. direct/fixed 는 NULL. Phase 2~3 에서 프런트/엔진이 이 컬럼을 읽고 쓴다. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>- batch.ts: ConditionalRule / ConditionalConfig 타입 추가, BatchMapping 에 mapping_type ('direct'|'fixed'|'conditional') + mapping_config 필드 - ConditionalEditor.tsx: 평가 필드 선택 + when/then 룰 add/remove + default 입력 컴포넌트. emptyConditionalConfig / normalizeConditionalConfig 헬퍼 동봉. vexplor_rps 1:1 포팅 - batchmngList/edit/[id]/page.tsx: · MappingItem.sourceType 에 'conditional' 추가 + conditionalConfig 필드 · 소스타입 Select 에 "조건 변환" 옵션 · Load: mapping_type=conditional 인 매핑은 mapping_config JSON 파싱 후 복원 · Save: sourceType=conditional 매핑은 mapping_config 객체와 함께 전송 저장된 룰: {"rules":[{"when":"1","then":"Y"}],"default":"?"} 형태. Phase 1 의 BatchService 직렬화 경로로 JSONB 에 저장된다. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>vexplor_rps batchSchedulerService.executeBatchMappings 의 1:1 이식. 흐름: 1. mappings 를 fixed/non-fixed 로 partition 2. non-fixed 를 (from_connection_type, from_connection_id, from_table_name) 으로 그룹화 3. 그룹별 FROM 읽기 → MappingTransformer.transformRow → TO 저장 4. (totalRecords, successRecords, failedRecords) 집계 FROM 소스: - internal : sqlSession.getConnection() 의 동적 SELECT (식별자 화이트리스트 escape) - external_db : ExternalDbConnectionService.executeQuery (SELECT-only) - restapi : ExternalRestApiConnectionService.fetchData (등록된 연결 + dataArrayPath) TO 대상: - internal : INSERT / UPSERT(save_mode + conflict_key, ON CONFLICT DO UPDATE/NOTHING) updated_date 컬럼 있으면 자동으로 NOW() 갱신 - restapi : 행 단위 POST/PUT/DELETE — testConnection 으로 호출 - external_db : 미지원 (보안 정책: ExternalDbConnectionService 가 SELECT-only) vexplor_rps 대비 단순화 항목 (필요 시 후속 Phase 로 분리): - to_api_body 템플릿 기반 일괄 전송 - URL_PATH_PARAM 컬럼 처리 - auth_tokens 자동 조회 (inline-mode REST API: from_connection_id 없이 from_api_url 직접 호출) - row_filter_config Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>기존 stub(0 만 리턴) 였던 BatchManagementService.executeBatchConfig 를 실제 ETL 실행 + 로그 기록 흐름으로 교체. 흐름: 1. RUNNING 상태로 batch_execution_logs INSERT (도중 비정상 종료 추적용) 2. BatchExecutor.execute(batchConfig) 호출 - 정상: failedRecords > 0 면 PARTIAL/FAILED, 아니면 SUCCESS - 예외: FAILED 로 마킹, error_message 기록 3. 로그 UPDATE — execution_status, end_time, duration_ms, total/success/failed_records, error_message 4. controller 응답에 execution_status + error_message 동봉 server_name 은 InetAddress.getLocalHost(), process_id 는 ProcessHandle.current().pid(). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>검증 전 선제 보강 2건. 1) BatchExecutor.writeTo 의 @Transactional 제거 - 같은 클래스 내부 호출(execute → writeTo)이라 Spring AOP 가 우회되어 어차피 안 걸림 - batch 의 정상 동작은 row 단위 독립 commit (일부 실패해도 다른 row 는 살아야 함). vexplor_rps 도 동일 패턴 2) BatchManagementService.executeBatchConfig 의 end_time 을 Timestamp 객체로 직접 전달 - 기존: Timestamp.toString() 으로 변환 후 #{end_time}::timestamp 캐스트 - 신규: Timestamp 객체 그대로 → PostgreSQL JDBC 가 timestamp 자동 변환, mapper 의 ::timestamp 캐스트는 noop Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>vexplor_rps 알고리즘 1:1 이식이 정상 동작하는지 검증. 검증 항목: - evaluateConditional: 단순 매칭 / null cfg / 빈 rules - parseConditionalConfig: Map / String(JSON) / null / 손상 JSON 모두 안전 - getValueByPath: 단순 키 / 중첩 경로 / 없는 경로 / null obj - partitionFixed: fixed / non-fixed 분리 - transformRow: direct / conditional("1"→"Y") / conditional default 폴백 / fixed 적용 / 점 표기법 ("user.profile.name") / company_code 자동주입 조건 18 tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>외부 커넥션 관리에서 연결 테스트 시 500 발생. 원인: 운영 DB 의 external_rest_api_connections.id 가 V001 legacy 마이그레이션으로 character varying 인데 mapper 의 WHERE ID = #{id} 가 controller 의 int id 를 그대로 받아 PgJDBC 가 보내는 BIND 가 정수. PostgreSQL 이 "operator does not exist: character varying = integer" 거부 → SQLException → ApiResponse 500 ("서버 내부 오류"). 수정: 4곳 모두 #{id}::varchar 캐스팅 추가. - getExternalRestApiConnectionInfo (SELECT) - updateExternalRestApiConnection (UPDATE) - deleteExternalRestApiConnection (DELETE) - updateExternalRestApiConnectionTestResult (UPDATE) 배치 작업의 batch_config_id 패턴과 동일. 같은 V001 영향을 받은 다른 mapper (externalDbConnection.xml / externalCallConfig.xml / booking.xml / delivery.xml / multiConnection.xml / taxInvoice.xml 등) 도 같은 수정이 필요할 가능성 — 별도 작업으로 분리. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>새 배치 (REST API → DB) 진입 시 매번 사용자가 "데이터베이스 커넥션 선택" 셀렉트에서 "내부 DB" 를 직접 골라야 했음. 대부분의 배치가 internal 적재라 디폴트 채움이 자연스러움. 1) TO DB 자동 선택 useEffect 로 batchType === "restapi-to-db" + connections 로드 + toConnection 비어있음 조건 만족 시 handleToConnectionChange("internal") 자동 호출. 사용자가 외부 DB 로 변경하면 toConnection != null 이 되어 더 이상 자동 동작 안 함. 2) Select controlled 화 DB 커넥션/테이블 Select 가 value prop 없는 uncontrolled 상태였음. setToConnection/setToTable state 가 바뀌어도 Select UI 가 placeholder 그대로 → programmatic 자동 선택이 시각적으로 반영 안 됨. → value prop 추가: - DB 커넥션: toConnection.type === "internal" ? "internal" : String(toConnection.id) - 테이블: toTable Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>