# AI-Assisted Development Guide 이 문서는 AI 어시스턴트가 이 저장소의 코드를 이해하고 기여하는 데 필요한 가이드를 제공합니다. ## 프로젝트 주요 특징 AI 어시스턴트가 작업을 시작하기 전에 반드시 이해해야 할 핵심적인 특징들입니다. - **하이브리드 데이터 액세스**: 이 프로젝트는 **JPA(Hibernate)와 iBATIS를 함께 사용**합니다. - **신규 기능**: 항상 **JPA**와 Spring Data 리포지토리를 사용해야 합니다. - **레거시 코드**: 기존 iBATIS (`*.xml` 매퍼) 코드를 수정할 때는 해당 패턴을 따라야 합니다. - **멀티 모듈 Gradle 프로젝트**: `settings.gradle`에 정의된 것처럼 여러 하위 모듈(`elink-online-*`, `kjb-*` 등)로 구성되어 있습니다. 특정 기능은 다른 모듈에 위치할 수 있습니다. - **QueryDSL 코드 생성**: 빌드 시 `QueryDSL`을 사용하여 Q-class가 자동으로 생성됩니다. IDE에서 엔티티를 찾을 수 없다고 표시되면, `./gradlew compileJava` 를 먼저 실행하여 코드를 생성해야 합니다. - **고객사별 커스터마이징**: `ext.kjb` 또는 `custom` 패키지는 특정 고객사(광주은행)를 위한 코드를 포함하므로, 일반적인 기능 수정 시에는 주의가 필요합니다. ## 프로젝트 개요 eLink EMS (eLink Management System)는 세 가지 주요 애플리케이션으로 구성된 엔터프라이즈 API 관리 플랫폼입니다: - **eapim-admin**: 구성, 모니터링, 통계를 위한 관리 콘솔 - **eapim-online**: 실시간 트랜잭션 처리를 위한 API 게이트웨이 - **eapim-portal**: API 소비자를 위한 개발자 포털 (Spring Boot 기반) 이 디렉토리(`eapim-admin`)는 Spring 5.3과 하이브리드 ORM 방식(JPA + iBATIS)으로 구축된 관리 콘솔을 포함합니다. ## 빌드 및 개발 명령어 ### 애플리케이션 빌드 eLink EMS (eLink Management System)는 eLink의 웹 기반 관리 서비스로, 구성, 모니터링 및 통계 기능을 제공합니다. Tomcat 또는 WebLogic에 배포되는 Spring 기반 Java 웹 애플리케이션입니다. ### 주요 기능 - 사용자 및 권한 관리 - 트랜잭션 로그 조회 (온라인/배치/대량) - 통계 및 대시보드 모니터링 - 인터페이스, 레이아웃, 어댑터, 라우팅 관리 - 외부 시스템 연동 (UMS, EAI 배치) ## 빌드 및 개발 명령어 ### 빌드 명령어 프로젝트 루트의 Gradle wrapper(`./gradlew`)를 사용합니다. JDK 8 toolchain 위치는 `.envrc` 등으로 잡습니다(아래 "기술 스택" 섹션 참조). ```bash # 표준 빌드 ./gradlew build # Weblogic 배포용 빌드 (테스트 제외) ./gradlew build -x test -Pprofile=weblogic # WAR 파일 빌드 ./gradlew war # 클린 빌드 ./gradlew clean build ``` ### 테스트 실행 ```bash # 모든 테스트 실행 ./gradlew test # 특정 테스트 클래스 실행 ./gradlew test --tests "com.example.ClassName" # 특정 테스트 패키지 실행 (JUnit 플랫폼 사용) ./gradlew test --tests "com.eactive.eai.rms.*" ``` ### 개발 태스크 ```bash # 패키징 없이 클래스만 컴파일 ./gradlew classes # QueryDSL Q-classes 및 기타 애노테이션 생성 ./gradlew compileJava # 의존성 트리 보기 ./gradlew dependencies # 사용 가능한 모든 태스크 목록 ./gradlew tasks --all ``` ## 로컬 개발 빠른 시작 새로운 환경에서 프로젝트를 처음 설정하고 실행하는 권장 절차입니다. 1. **IDE 설정 파일 생성 (최초 1회)** ```bash # Eclipse 사용 시 (기본) ./gradlew eclipse # IntelliJ IDEA 사용 시 (build.gradle.intellij 파일 사용 필요) # 1. build.gradle을 build.gradle.eclipse로 백업 # 2. build.gradle.intellij를 build.gradle로 복사 # 3. ./gradlew idea 실행 ``` 2. **QueryDSL 등 소스 코드 생성** ```bash ./gradlew compileJava ``` 3. **전체 빌드 및 테스트 실행** ```bash ./gradlew build ``` 4. **IDE에서 프로젝트 열기** - Eclipse: `./gradlew eclipse` 실행 후, IDE에서 프로젝트를 엽니다. - IntelliJ: IntelliJ 전용 `build.gradle.intellij`를 `build.gradle`로 교체 후 사용합니다. 5. **실행 구성(Run Configuration) 설정** - 사용하는 WAS(Tomcat 등)에 `eapim-admin` 프로젝트를 배포하도록 설정합니다. - **VM Options**에 위에 명시된 "필수 환경 변수 (Tomcat)"를 모두 추가합니다. 6. **서버 실행** - IDE에서 설정한 실행 구성을 시작하여 서버를 실행합니다. ## 아키텍처 및 모듈 의존성 ### 멀티 모듈 구조 eapim-admin은 settings.gradle을 통해 형제 디렉토리 `eapim-online`의 모듈들을 참조합니다: ``` eapim-admin (root project) ├── elink-online-core # 핵심 인터페이스 및 도메인 모델 ├── elink-online-core-jpa # JPA 엔티티 및 리포지토리 ├── elink-online-transformer # 메시지 변환 로직 ├── elink-online-common # 공통 유틸리티 ├── elink-online-emsclient # EMS 클라이언트 통신 ├── elink-online-adapter # 통신 어댑터 ├── elink-portal-common # 포털 공통 컴포넌트 (JPA 엔티티) ├── kjb-safedb # 커스텀 암호화 라이브러리 └── eapim-admin-kjb # KJB 은행 특화 커스터마이제이션 ``` 모든 모듈 프로젝트는 이 디렉토리 기준으로 `../eapim-online/`, `../elink-portal-common/` 등에 위치합니다. ### 하이브리드 ORM 방식 이 애플리케이션은 **JPA와 iBATIS 모두를 사용**합니다: - **JPA/Hibernate**: `elink-portal-common`을 통한 현대적인 데이터 액세스 (Spring Data repositories) - **iBATIS**: 기존 코드를 위한 레거시 SQL 매핑 (점진적으로 마이그레이션 예정) 데이터 액세스 작업 시: - 새로운 기능은 JPA와 Spring Data repositories를 사용해야 합니다 - 레거시 iBATIS 매퍼는 `src/main/resources/com/eactive/eai/**/*.xml`에 있으며 Spring XML을 통해 설정됩니다 ### 코드 생성 빌드 프로세스에서 생성되는 것들: - **QueryDSL Q-classes**: 타입 안전 쿼리 클래스 - **Lombok**: 애노테이션 프로세싱을 통한 Getters/setters/builders - **MapStruct**: DTO와 엔티티 간의 객체 매퍼 #### Q-Class 생성 위치 Q-classes는 `build/generated/java/` 디렉토리에 생성됩니다. - `./gradlew compileJava` 또는 `./gradlew build` 실행 시 Gradle이 자동으로 생성 - 이 디렉토리는 `.gitignore`에 포함되어 있으며 커밋해서는 안 됩니다 #### 생성된 코드 작업하기 - **Gradle 빌드**: `build/generated/java/`의 Q-classes가 자동으로 classpath에 포함됩니다 - **업데이트 pull 후**: `./gradlew compileJava` 를 실행하여 Q-classes를 재생성합니다 - **Q-classes IDE 오류 시**: `./gradlew clean compileJava` 로 재생성합니다 #### IDE별 빌드 설정 파일 - **`build.gradle`**: Eclipse 전용 (기본, Eclipse APT 플러그인 포함) - **`build.gradle.intellij`**: IntelliJ IDEA 전용 IntelliJ를 사용하려면 `build.gradle.intellij`를 `build.gradle`로 교체해야 합니다. ## 로컬 개발 환경 설정 ### 필수 환경 변수 (Tomcat) 다음은 로컬 Tomcat 환경에서 개발 시 필요한 시스템 프로퍼티(-D)입니다. **설정 방법**: IntelliJ, Eclipse 등 IDE의 실행 구성(Run Configuration)에서 'VM options'에 추가하거나, 사용하는 Tomcat의 `bin` 폴더에 `setenv.bat` (Windows) 또는 `setenv.sh` (Linux/macOS) 파일을 생성하여 아래 내용들을 `CATALINA_OPTS` 또는 `JAVA_OPTS` 환경 변수에 추가합니다. ``` -Deai.datasource.type=DEV -Dinst.Name=emsSvr99 -Deai.tableowner=EMSADM -Deai.systemmode=D -Dfile.encoding=utf-8 -Dlogin.mode=db -DLOGBACK_LOG_LEVEL=DEBUG -Dlogback.configurationFile=classpath:logback-dev.xml -Dhibernate.dialect=org.hibernate.dialect.Oracle12cDialect -Dkjb_safedb.mode=fake ``` ### 개발 환경 설정 애플리케이션은 `WebContent/WEB-INF/properties/`의 환경별 프로퍼티 파일을 통해 설정됩니다: - `env.D.properties` - 개발 환경 - `env.T.properties` - 테스트/스테이징 환경 - `env.P.properties` - 운영 환경 **프로필 설정** - `-Pprofile=weblogic`: `web.xml` 대신 `weblogic-web.xml`을 사용 (DefaultServlet 문제 해결) ### 데이터베이스 설정 애플리케이션은 다음을 지원합니다: - **Oracle**: 운영 데이터베이스 (주) - **PostgreSQL/MariaDB**: 대체 운영 DB - **H2**: 테스트용 인메모리 데이터베이스 데이터베이스 연결은 `eai.datasource.type` 시스템 프로퍼티(DEV/STG/PROD)를 통해 설정됩니다. ### SafeDB 암호화 라이브러리 `kjb-safedb` 모듈은 세 가지 동작 모드를 제공합니다: - **REAL**: 실제 SafeDB 네이티브 라이브러리 사용 - **FAKE**: SHA-256/AES-256을 사용하는 개발 모드 (SafeDB 설치 불필요) - **NONE**: 암호화 우회 (테스트 전용) 개발 시 SafeDB가 로컬에 설치되지 않은 경우 FAKE 모드를 사용합니다. ## 주요 기능 관리 콘솔은 eLink 플랫폼의 모든 측면을 관리합니다: | 기능 | 설명 | |------|------| | 사용자 관리 | 사용자 계정 및 권한 | | 트랜잭션 로그 | 온라인/배치/대량 트랜잭션 이력 조회 | | 통계 및 대시보드 | 실시간 모니터링 및 메트릭 | | 인터페이스 관리 | API 인터페이스 구성 | | 레이아웃 관리 | 메시지 레이아웃 정의 | | 변환 규칙 | 메시지 변환 로직 | | 어댑터 설정 | 프로토콜 어댑터 (HTTP, TCP 등) | | 라우팅 규칙 | 요청 라우팅 및 로드 밸런싱 | | 배치 처리 | 배치 인터페이스 및 어댑터 관리 | | 스케줄러 | Quartz 기반 작업 스케줄링 | ## 배포 대상 애플리케이션은 다음 환경에 배포할 수 있습니다: - **Tomcat** (기본, 개발) - **WebLogic 14.1.2** (운영, `-Pprofile=weblogic` 필요) - **JEUS** (지원) - **JBoss/WildFly** (descriptors와 함께 지원) ### WebLogic 전용 빌드 WebLogic용 빌드 시, DefaultServlet 문제를 해결하기 위해 `web.xml`을 `weblogic-web.xml`로 교체하는 `weblogic` 프로필을 사용합니다: ```bash ./gradlew build -x test -Pprofile=weblogic ``` ## 기술 스택 - **Java 8**: Gradle toolchain을 통해 강제 (`JavaLanguageVersion.of(8)`). 프로젝트의 `gradle.properties` 에는 JDK 경로를 기입하지 않습니다 — 개인 환경별로 `.envrc`(direnv) 또는 셸 rc 파일에서 `JAVA_HOME` 을 JDK 8 위치로 export 하세요. Gradle 8 의 toolchain auto-detect 가 `JAVA_HOME` 도 후보 경로로 인식합니다. ```bash # 예: 프로젝트 루트의 .envrc (Zulu 8 / macOS Apple Silicon) JAVA_HOME=${HOME}/opts/jdks/zulu8.94.0.17-ca-jdk8.0.492-macosx_aarch64 GRADLE_USER_HOME=${HOME}/eactive/djb-eapim/gradle-home export PATH=${JAVA_HOME}/bin:${PATH} ``` Gradle 표준 위치(`/Library/Java/JavaVirtualMachines/...`, Homebrew, SDKMAN 등)에 설치한 경우는 별도 설정 없이도 auto-detect 됩니다. - **Spring Framework 5.3.27**: 코어 프레임워크 (MVC, Data JPA) - **Spring Data JPA 2.5.2**: 리포지토리 추상화 - **Hibernate 5.4.33/5.6.15**: ORM 구현 (JPA/ORM) - **QueryDSL 5.0.0**: 타입 안전 쿼리 - **iBATIS 2.3.4**: 레거시 SQL 매핑 - **Quartz 2.2.1**: 작업 스케줄링 - **Apache POI 3.17**: Excel 내보내기 기능 - **Jackson 2.13.1**: JSON 처리 - **Logback 1.2.10**: 로깅 프레임워크 (SLF4J와 함께) - **AWS SDK 2.20.142**: S3 연동 - **EhCache**: 캐싱, **Lombok**: 코드 생성, **MapStruct**: 객체 매핑 > Kubernetes Client 의존성은 JDK 8 호환 문제로 제거됨(`io.kubernetes:client-java:18.0.1` 은 JDK 11+ 필요). K8s 모드 기능이 필요하면 `≤13.0.2` 로 다운그레이드 후 재도입 검토. ## 프로젝트 규칙 ### 패키지 구조 ``` com.eactive.eai ├── agent/command - 커맨드 패턴 구현 ├── common - 공통 유틸리티, iBatis, JSON 직렬화 ├── custom - 고객사별 커스터마이제이션 ├── rms - 메인 애플리케이션 코드 │ ├── bap - 배치 처리 (BAP) │ │ ├── adaptor - 배치 어댑터 │ │ ├── manage - 배치 관리 (메시지, 서버, 프로퍼티) │ │ └── tansaction - 배치 트랜잭션 추적 │ ├── bat - 추가 배치 기능 │ ├── common - RMS 공통 (필터, 시작, 서비스) │ ├── data - 데이터 엔티티, 리포지토리 │ ├── env - 환경 설정 │ ├── kakao - 카카오 연동 │ ├── onl - 온라인 트랜잭션 관리 │ │ ├── apim - API 관리 (포털 조직, 사용자, 승인) │ │ ├── manage - 리소스 관리 │ │ └── transaction - 트랜잭션 처리 │ └── service - 비즈니스 서비스 └── ext.kjb - 광주은행(KJB) 확장 ``` ### Spring 설정 애플리케이션은 다음을 사용합니다: - **Root context**: `WebContent/WEB-INF/applicationContext.xml` - **Servlet context**: `WebContent/WEB-INF/springapp-servlet.xml` - **환경별 설정**: `${eai.systemmode}` 시스템 프로퍼티 기반 로드 - **컴포넌트 스캔**: 애노테이션 기반 설정 활성화 ### 데이터 액세스 패턴 애플리케이션은 **이중 퍼시스턴스**를 사용합니다: 1. **JPA/Hibernate** - `com.eactive.eai.rms.data.entity`의 최신 엔티티 기반 코드용 2. **iBatis** - `src/main/resources/com/eactive/eai/**/*.xml`의 레거시 SQL 매핑용 리포지토리는 Spring Data JPA 규칙을 사용하며, 서비스는 `@Service`, 컨트롤러는 `@RestController`/`@Controller`를 사용합니다. ### Multi-tenancy (동적 스키마 전환) 애플리케이션은 Hibernate Multi-tenancy를 사용하여 **런타임에 스키마를 동적으로 전환**합니다. **핵심 컴포넌트:** - `DataSourceContextHolder` - ThreadLocal로 현재 데이터소스 타입 관리 - `DataSourceTypeManager` - 데이터소스 타입 상수 정의 (MONITORING, APIGW, EAI, BAT 등) - `TenantIdentifierResolver` - `DataSourceContextHolder`에서 tenant 식별자 반환 - `ConfigurableMultiTenantConnectionProvider` - tenant에 따라 `connection.setSchema()` 호출 - `DataSourceTypeInterceptor` - 요청 파라미터 `serviceType`에서 데이터소스 자동 설정 **동작 흐름:** 1. `DataSourceTypeInterceptor.preHandle()` → `request.getParameter("serviceType")` 읽음 2. `DataSourceContextHolder.setDataSourceType(dataSourceType)` 설정 3. JPA 쿼리 실행 시 `TenantIdentifierResolver` → `DataSourceContextHolder`에서 tenant 반환 4. `ConfigurableMultiTenantConnectionProvider` → `connection.setSchema(schema)` 호출 **사용 방법:** 1. **URL 파라미터 방식** (인터셉터가 자동 처리): ``` /api/endpoint?serviceType=APIGW ``` 2. **Controller에서 명시적 설정** (특정 데이터소스 강제): ```java @Controller public class MyController { @RequestMapping("/my/api.json") public String myApi() { // 서비스 호출 전에 데이터소스 설정 DataSourceContextHolder.setDataSourceType( DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW)); return myService.getData(); } } ``` **주의사항:** - `@PersistenceContext`만 사용 (기본 `entityManagerFactory` 사용, Multi-tenancy 적용됨) - `@PersistenceContext(unitName = "entityManagerFactoryForEMS")`는 **Multi-tenancy 미적용** (MONITORING 스키마 고정) - Controller에서 `DataSourceContextHolder` 설정 후 Service 메서드를 호출해야 트랜잭션 시작 시점에 올바른 스키마가 적용됨 ### 주요 초기화 - `AppInitializer` - 시스템 프로퍼티를 설정하는 메인 애플리케이션 시작 빈 - `CustomizingAppInitializer` - 고객사별 초기화 - 시스템 프로퍼티: `inst.Name`, `eai.tableowner`, `eai.systemmode`, `theme.color` ### 로깅 - **SLF4J**와 **Logback** 구현 사용 - `LOGBACK_LOG_LEVEL` 시스템 프로퍼티를 통한 로그 레벨 제어 - 모든 `log4j` 의존성 제외 (build.gradle에 설정) ## IDE 설정 ### IntelliJ IDEA (권장) ```bash ./gradlew idea ``` 또는 IntelliJ에서 직접 "Import Gradle Project"를 사용합니다. 기본 `build.gradle`은 IntelliJ 전용으로 설정되어 있습니다. ### Eclipse Eclipse를 사용하려면 Eclipse APT 플러그인이 포함된 별도의 빌드 설정 파일을 사용해야 합니다: ```bash # 1. 기존 build.gradle 백업 (필요시) cp build.gradle build.gradle.intellij # 2. Eclipse 전용 설정으로 교체 cp build.gradle.eclipse build.gradle # 3. Eclipse 프로젝트 생성 ./gradlew eclipse ``` Eclipse 전용 설정(`build.gradle.eclipse`)은 다음을 포함합니다: - `com.diffplug.eclipse.apt` 플러그인 (Eclipse APT 지원) - `.project` 및 `.classpath` 파일 생성 - Eclipse WTP 설정 (context path: `/monitoring`) - UTF-8 인코딩 설정 - QueryDSL/Lombok을 위한 애노테이션 프로세서 설정 ## 테스트 테스트에 사용되는 것들: - **JUnit 5 (Jupiter)**: 테스트 프레임워크 - **Spring Boot Test 2.6.15**: 통합 테스트 유틸리티 - **H2 Database**: 테스트용 인메모리 데이터베이스 - **Mockito**: 모킹 프레임워크 (Spring Boot Test를 통해) 테스트 리소스는 H2 호환 설정과 함께 `src/test/resources`에 있습니다. ## KJB (광주은행) 전용 설정 ### 프로퍼티 관리 KJB 전용 프로퍼티는 데이터베이스 테이블 `TSEAIRM24`에 그룹명 `'Monitoring'`으로 저장됩니다. `com.eactive.ext.kjb.common.KjbProperty`에서 관리하는 주요 프로퍼티: **이메일 알림 (EAI Batch를 통해)** - `kjb.eai_batch.url` - 이메일 발송을 위한 EAI 배치 서버 URL - Dev: http://172.31.32.111:10230/BATAppWeb/EaiBatCall - QA: http://172.31.33.111:10430/BATAppWeb/EaiBatCall - Prod: http://172.21.1.40:10860/BATAppWeb/EaiBatCall - `kjb.ums.eai_batch.send_dir` - 이메일 파일 발송 디렉토리 (기본값: `/Data/eapim/portal/sendmail/snd`) - `kjb.ums.eai_batch.backup_dir` - 이메일 백업 디렉토리 (기본값: `/Data/eapim/portal/sendmail/bak`) - `kjb.ums.eai_batch.interface_id` - 고객 이메일용 인터페이스 ID (예: `UAGFF00001UIE`) **UMS (SMS/LMS/카카오톡) 연동** - `kjb.ums.host_url` - UMS API 엔드포인트 - `kjb.ums.api_key` - UMS API 인증 키 - `kjb.ums.connection_timeout` - 연결 타임아웃 (초 단위) - `kjb.ums.response_timeout` - 응답 타임아웃 (초 단위) ### 보안 - 커스텀 패스워드 인코더: SafeDB 연동을 위한 `KjbSafedbPasswordEncoder` - SafeDB 없이 로컬 개발 시 `-Dkjb_safedb.mode=fake` 설정 ## 데이터베이스 벤더 지원 애플리케이션은 벤더별 SQL 매핑 파일을 통해 여러 데이터베이스를 지원합니다: - Oracle: `*-oracle.xml` - MariaDB: `*-mariadb.xml` - PostgreSQL: `*-postgresql.xml` 데이터베이스 벤더는 프로퍼티 파일의 `db.vendor`와 `hibernate.dialect`를 통해 설정됩니다. ## WAR 배포 WAR 파일은 context path `/monitoring`으로 `eapim-admin.war`로 빌드됩니다. **Weblogic 배포**: `weblogic-web.xml` 설정을 포함하려면 `-Pprofile=weblogic`를 사용합니다. ## 중요 사항 - **인코딩**: 시스템은 UTF-8을 사용합니다. CharacterEncodingFilter는 `*.excel` 패턴을 제외한 모든 요청에 UTF-8을 적용합니다. - **XSS 보호**: CrossScriptingFilter가 `com.eactive.eai.rms.common.filter.CrossScriptingFilter`를 통해 모든 요청에 적용됩니다. - **실시간 업데이트**: 모든 관리 변경사항은 DB와 메모리 모두에 즉시 반영됩니다. - **인스턴스 이름**: 클러스터링을 위해 각 배포는 고유한 `inst.Name`을 가져야 합니다. - **테이블 소유자**: Oracle 스키마 소유자는 `eai.tableowner` 프로퍼티를 통해 지정됩니다.