25 KiB
CLAUDE.md
이 파일은 Claude Code(claude.ai/code)가 이 저장소의 코드를 작업할 때 참고하는 지침을 제공합니다.
프로젝트 개요
EAPIM Portal은 제주은행을 위한 엔터프라이즈 API 포털 관리 시스템입니다. API 서비스 관리, 사용자 등록, API 키 발급, 문서화, 테스트 기능을 제공하는 웹 기반 플랫폼입니다.
기술 스택:
- Spring Boot 2.7.18 with Spring MVC and Thymeleaf
- Java 8 (sourceCompatibility/targetCompatibility: 1.8)
- Gradle 8.7 빌드 시스템
- Oracle 19c 데이터베이스 (JNDI를 통한 이중 데이터소스)
- Spring Security (커스텀 인증)
- JPA/Hibernate 5.6.15 with Envers (감사 추적)
- MapStruct (DTO 매핑), Lombok (보일러플레이트 제거)
- SASS/SCSS (CSS 전처리기) - 스타일 수정 시 반드시 SASS 파일 수정
CSS/SASS 가이드:
- CSS 파일(
src/main/resources/static/css/main.css)은 SASS에서 컴파일된 결과물 - 스타일 수정 시 반드시 SASS 파일(
src/main/resources/static/sass/)을 수정해야 함 - CSS 파일 직접 수정 금지 - SASS 파일 수정 후 컴파일 필요
- SASS 컴파일:
sass src/main/resources/static/sass/main.scss src/main/resources/static/css/main.css
Git 브랜치 전략
저장소 정보:
- origin:
ssh://git@172.30.1.50:2222/djb-eapim/eapim-portal.git(Gitea, 사내망) - 이 저장소가 유일한 remote다. Jenkins 파이프라인도 같은 주소를 본다.
브랜치:
-
master: 기본 개발 브랜치이자 배포 기준 브랜치
- 일상적인 개발 작업(기능 개발, 버그 수정)을 여기서 직접 수행한다
- Jenkins 4개 파이프라인(
Jenkinsfile.*)이 모두origin/master를 체크아웃한다 Jenkinsfile.security는 pollSCM 으로 master 변경을 감지해 자동 실행된다
-
feats/*, design*, develop: 과거 작업 잔여 브랜치
- 현재 활성 개발에 사용하지 않는다. 참고용으로만 남아 있다
과거 문서에 있던
jenkins_with_weblogic브랜치는 존재하지 않는다. Jenkins/WebLogic 설정은 master 의Jenkinsfile.deploy에 통합되어 있다.
작업 흐름:
# master 에서 바로 작업
git checkout master
git pull origin master
# 커밋 후 푸시 → Jenkins security 파이프라인이 자동 트리거됨
git add .
git commit -m "기능 설명"
git push origin master
빌드 명령어
애플리케이션 실행
- Linux 개발 환경에서는
gradlew대신 설치된gradle(8.7)을 직접 쓴다. Jenkins 노드도/apps/opts/gradle-8.7의gradle을 쓴다. - Windows/Eclipse 환경 기동 절차는
BOOTRUN_SETUP_GUIDE.md참고 (거기서는gradlew.bat bootRun사용). .envrc(direnv)는 없다. JAVA_HOME(JDK 8)/GRADLE_HOME 은 셸에서 직접 맞춰야 한다.
# bootRun 기본 프로파일은 build.gradle 의 bootProfile 기본값(local_rinjaemac)
gradle bootRun
# 다른 프로파일로 기동 (--args 가 아니라 -PbootProfile)
gradle bootRun -PbootProfile=dev
bootRun의 프로파일은-PbootProfile로 넘긴다.-Pprofile은ext.profile='local'이 이미 점유하고 있어 무시된다(build.gradle의 주석 참고). Jenkins 빌드에서 쓰는-Pprofile=weblogic은 스프링 프로파일이 아니라 빌드용 플래그다.
빌드
# Spring Boot 실행 가능 WAR 빌드
gradle bootWar
# 출력: build/libs/eapim-portal-boot.war
# 애플리케이션 서버용 표준 WAR 빌드 (JEUS/WebLogic)
gradle war
# 출력: build/libs/eapim-portal.war
# 클린 후 빌드
gradle clean build
# SBOM(xlsx) 생성 - Jenkins 빌드 파이프라인에서 사용
gradle sbomXlsx
테스트
# 모든 테스트 실행
gradle test
# 로그 상세 출력
gradle test --info
# 특정 테스트 클래스 실행
gradle test --tests "com.eactive.apim.portal.apps.user.AccountControllerTest"
# 패턴에 매칭되는 테스트 실행
gradle test --tests "*Controller*"
커버리지는 측정되지 않는다. JaCoCo 플러그인이
build.gradle에 없고sonar-project.properties에도sonar.coverage.jacoco.xmlReportPaths가 없다. 그래서 SonarQube 의 Coverage 가 항상 0% 로 뜨고 Quality Gate 가 ERROR 가 된다 (Sonar 의 Zero Coverage Sensor 가 리포트 없는 라인을 전부 0 으로 채운다).
CSS/SASS 빌드
npm run sass:build # main.css (expanded)
npm run build # main.css + main.min.css
npm run sass:watch # 변경 감시
./sass-build.sh # sass CLI 직접 호출 (npm 없이)
개발
# 현재 프로파일 확인 (-Pprofile 로 넘긴 값)
gradle printProfile
# 소스 세트 설정 확인
gradle printSourceSets
Docker
build_docker.sh 는 없다. Dockerfile 만 있으므로 직접 빌드한다.
gradle bootWar
docker build -t eapim-portal:latest .
아키텍처
멀티 모듈 구조
이 프로젝트는 settings.gradle 의 멀티 프로젝트 구성으로 2개의 형제 디렉터리 모듈에 의존합니다:
-
elink-online-core-jpa (
../eapim-online/elink-online-core-jpa)- Gateway 데이터 모델 및 JPA 엔티티
- API 명세 엔티티 및 리포지토리 제공
- 패키지:
com.eactive.eai.data.entity.onl.*
-
elink-portal-common (
../elink-portal-common)- 공유 포털 유틸리티 및 공통 컴포넌트
- 기본 리포지토리 구현, QueryDSL 지원
- 공통 예외 핸들러 및 보안 유틸리티
두 모듈은 Jenkins 파이프라인의 Checkout dependencies 스테이지가 같은 Gitea 서버에서
자동으로 clone/reset 한다. 로컬에서도 ../eapim-online/elink-online-core-jpa 와
../elink-portal-common 이 없으면 컴파일 자체가 되지 않는다.
kjb-safedb (SafeDB 암호화 라이브러리)는 현재 빌드에서 빠져 있다.
build.gradle 의 implementation project(':kjb-safedb') 가 주석 처리되어 있고
settings.gradle 에도 등록되어 있지 않으며 ../kjb-safedb 디렉터리도 없다.
다시 붙일 때는 세 곳을 모두 되살려야 한다.
패키지 구조
코드는 기술 계층이 아닌 기능 모듈(수직 분할) 방식으로 구성됩니다:
com.eactive.apim/
├── portal/
│ ├── PortalApplication.java
│ ├── apps/ # 기능 모듈
│ │ ├── HealthCheckController.java
│ │ ├── ReadinessController.java
│ │ ├── agreements/ # API 약관
│ │ ├── apis/ # API 카탈로그 & 문서
│ │ ├── apiservice/ # API 서비스 그룹핑
│ │ ├── app/ # API 키 관리
│ │ ├── approval/ # 승인 워크플로우
│ │ ├── auth/ # 인증
│ │ ├── community/ # FAQ, 공지사항, Q&A, 제휴문의
│ │ ├── dashboard/ # 대시보드
│ │ ├── file/ # 파일 업로드/다운로드
│ │ ├── login/ # 로그인/로그아웃
│ │ ├── main/ # 메인 화면
│ │ ├── sample/ # 샘플 코드 생성
│ │ ├── session/ # 세션 관리 (filter/entity/repository 포함)
│ │ ├── statistics/ # API 통계
│ │ └── user/ # 사용자 관리
│ ├── common/ # 공통 관심사
│ ├── config/ # Spring 설정
│ ├── custom/ # 사이트별 커스터마이징 설정
│ ├── djb/ # 은행 특화 기능
│ │ ├── apistatus/ community/ footer/ guide/ menu/ notitest/
│ ├── spring/ # DatabaseSessionVerifier 등
│ └── tools/ # HibernateSqlGenerator, JpaErrorLoggingAspect
└── gateway/ # Gateway DB 직접 접근 (portal 의 하위가 아님)
apps/proxy/패키지는 더 이상 없다. 과거 문서의 Forward Proxy 모듈 설명은 무효다.
각 기능 모듈은 일반적으로 다음을 포함합니다:
controller/- Spring MVC 컨트롤러 (@Controller)service/- 비즈니스 로직 (@Service, @Transactional)repository/- Spring Data JPA 리포지토리dto/- 데이터 전송 객체 (Lombok @Data)mapper/- MapStruct 인터페이스 (entity ↔ DTO 변환)
이중 데이터베이스 아키텍처
애플리케이션은 두 개의 Oracle 데이터베이스를 사용합니다:
-
EMS Database (Portal/Admin)
- JNDI:
jdbc/dsOBP_EMS - Schema:
EMSAPP - Entities:
com.eactive.apim.portal.apps.* - 목적: 포털 사용자, 조직, API 키, 승인
- JNDI:
-
Gateway Database (API Specs)
- JNDI:
jdbc/dsOBP_AGW - Schema:
AGWAPP - Entities:
com.eactive.eai.data.entity.onl.* - 목적: API 명세, 서비스, 메시지
- JNDI:
두 데이터소스 모두 dev 프로파일에서도 JNDI 로 연결한다(application-dev.yml, application-stage.yml).
직접 JDBC URL 을 쓰는 프로파일은 없다.
설정: config/PortalDatasourceConfiguration.java
- 각 데이터베이스별 별도 EntityManager
- JTA/XA 미사용. EntityManagerFactory 별 로컬 트랜잭션 (
config/PortalConfigTransaction.java)transactionManager(@Primary) → EMSgatewayTransactionManager→ Gateway
설정 프로파일
환경별 설정 파일: src/main/resources/application-{profile}.yml
저장소에 실제로 있는 프로파일은 4개다:
- dev: 개발 환경 (DevTools 활성화, SQL 로깅)
- stage: 스테이징 환경 (JNDI 데이터소스, proxy to inter-dapiwas01)
- prod: 운영 환경 (JNDI 데이터소스, proxy to inter-apiwas00, 캐싱 활성화)
- local_gf63: 개인 로컬 개발 환경
bootRun의 기본값은build.gradle에서local_rinjaemac으로 잡혀 있지만application-local_rinjaemac.yml은 저장소에 없다. 기본값 그대로gradle bootRun을 하면 해당 프로파일 설정 없이 뜨므로, 로컬 기동 시에는-PbootProfile=dev처럼 명시하는 편이 안전하다.
주요 설정 (application.yml):
- 세션 타임아웃: 10분 (
server.servlet.session.timeout: 10m, WebLogic 은weblogic.xml의timeout-secs 600) - 세션 쿠키명:
JSESSIONID_PORTAL - 파일 업로드 최대: 10MB (
portal.file.max-size) - 비밀번호 만료: 90일 (
portal.password-expiration-days) - 인증 토큰 TTL: 5분 (
portal.auth-ttl: 300), 재발송 제한 30초 - 사용자 승인 필수:
portal.user-approval: true - 내부 사용자 판별 도메인:
portal.internal-user.email-domains
주요 기능 및 비즈니스 로직
사용자 관리 (apps/user/)
두 가지 사용자 유형:
- 내부 사용자 (Staff): 포털 관리자 및 운영자
- 기업 사용자 (Enterprise): 외부 API 소비자
사용자 라이프사이클:
- 가입 → 이메일 인증 → 관리자 승인 → 활성화
- 비밀번호 정책 적용 (90일 만료, 복잡도 규칙)
- 로그인 실패 시 계정 잠금
- 휴면 계정 관리
API 키 관리 (apps/app/)
API 키는 승인 워크플로우와 함께 관리됩니다:
- 기업 관리자가
AppRequestController를 통해 키 요청 - 관리자가
ApprovalController를 통해 승인/반려 - 키는 개발/운영 환경 지원
- 키는 eLink Gateway ClientID/ClientSecret과 연결
승인 워크플로우 (apps/approval/)
다음 항목에 대한 범용 승인 시스템:
- 사용자 등록 승인
- API 키 생성/수정
- 제휴 신청
엔티티: Approval, Approver, ApprovalStatus (WAITING, APPROVED, REJECTED)
API 테스트 (apps/apis/)
- API 테스터:
apps/apis/filter/ApiTesterFilter.java - Testbed 스펙 제공:
apps/apis/controller/TestbedSpecController.java - 샘플 코드 템플릿:
application.yml의sample-code-path: classpath:/templates/sample_code
apps/sample/은 샘플 코드 생성기가 아니라 Thymeleaf/Security 데모 컨트롤러 (ThymeleafDemoController,SecurityThymeleafDemoController등) 모음이다.
감사 추적 (Hibernate Envers)
모든 엔티티는 자동 감사를 위해 AbstractAuditingEntity를 확장합니다:
createdBy,createdDatelastModifiedBy,lastModifiedDate@Audited어노테이션으로 변경 이력 관리- Spring Data Envers를 통한 이력 조회
공통 개발 패턴
새 기능 모듈 추가하기
apps/하위에 패키지 생성 (예:apps/newfeature/)controller/,service/,repository/,dto/,mapper/로 구조화repository/entity/에 JPA 엔티티 생성 (AbstractAuditingEntity확장)dto/에 Lombok@Data를 사용한 DTO 생성mapper/에 MapStruct 매퍼 인터페이스 생성@Service와@Transactional을 사용한 서비스 계층 구현@Controller와@RequestMapping을 사용한 컨트롤러 생성src/main/resources/templates/views/newfeature/에 Thymeleaf 템플릿 추가application.yml의pages섹션에 라우트 설정 (또는@GetMapping/@PostMapping으로 직접 매핑)
메뉴/네비게이션 항목 추가하기
중요: 메뉴 정의가 두 곳으로 분리되어 있다. yml 한 곳만 고치면 헤더 드롭다운에 안 보이고, 헤더만 고치면 브레드크럼이 비어 보인다. 메뉴 추가/이름 변경/순서 변경 시 반드시 두 파일을 같이 수정한다.
-
application.yml의page:트리 (브레드크럼·페이지 메타용)PageService가 URL → breadcrumb 매핑에 사용- 부모 메뉴(
service,apis,community등) 아래children:에 새 키를 추가
page: home: children: service: children: oauth2_guide: name: "OAuth2 인증가이드" path: "/service/oauth2-guide" -
templates/views/fragment/djbank/header_container.html(상단 글로벌 네비)<nav class="header-center"><ul class="nav-menu">블록에 정적<li>로 하드코딩되어 있다 — yml 트리를 iterate 하지 않음- 부모 메뉴의
<ul class="sub-menu">에<li><a th:href="@{/...}">메뉴명</a></li>직접 추가
-
라우트도 같이 등록 (
application.yml의portal.pages매핑 섹션, 또는@GetMapping)portal: pages: - path-pattern: /service/oauth2-guide method: GET view-name: apps/service/oauth2-guide -
검증: 변경 후 (a) 헤더 드롭다운에 항목이 보이는지, (b) 새 페이지 진입 시 브레드크럼에 메뉴명이 보이는지 둘 다 확인.
-
재시작:
application.yml변경은PortalPageHandlerMapper가@PostConstruct에서 한 번만 등록하므로 자동 라이브 리로드 안 됨 — 수동 재시작 필요. HTML/CSS만 라이브 반영됨.
MapStruct DTO 매핑
타입 안전한 DTO 변환을 위해 MapStruct 사용:
@Mapper(componentModel = "spring")
public interface UserMapper {
PortalUserDto toDto(PortalUser entity);
PortalUser toEntity(PortalUserDto dto);
List<PortalUserDto> toDtoList(List<PortalUser> entities);
}
생성된 구현체는 build/generated/sources/annotationProcessor/java/main/에 위치
보안 및 인증
보안 설정: config/PortalConfigSecurity.java
- 커스텀 인증 관리자:
PortalAuthenticationManager changeSessionId()를 통한 세션 고정 공격 방어- CSRF:
HttpSessionCsrfTokenRepository(세션 저장), 헤더명X-XSRF-TOKEN고정 — 쿠키 기반(CookieCsrfTokenRepository)이 아니다. 토큰 수명은 세션 타임아웃과 같다 - XSS: Naver Lucy
XssEscapeServletFilter - 비밀번호 전송암호화(RSA-OAEP + AES-GCM):
common/security/passwordcrypto/— 필터 순서상 MultipartFilter 이후, Lucy XSS 필터 이전에 복호화된다
역할 계층 (정의: src/main/resources/roles.yml, 부팅 시 PTL_ROLE / PTL_ROLE_AUTHORITY 에 미러 적재):
ROLE_USER (개인사용자) → [ROLE_INQUIRY, ROLE_ACCOUNT]
ROLE_CORP_USER (법인사용자) → [ROLE_API_KEY_REQUEST, ROLE_API_KEY_REQUEST_VIEW,
ROLE_INQUIRY, ROLE_APP, ROLE_ACCOUNT]
ROLE_CORP_MANAGER (법인관리자) → [ROLE_API_KEY_REQUEST, ROLE_API_KEY_REQUEST_VIEW,
ROLE_WEBHOOK, ROLE_INQUIRY, ROLE_APP, ROLE_ACCOUNT,
ROLE_CORP_API, ROLE_DASHBOARD, ROLE_USER_MANAGER]
데이터베이스 쿼리
Spring Data JPA 리포지토리 메서드 사용 권장:
public interface PortalUserRepository extends JpaRepository<PortalUser, Long> {
Optional<PortalUser> findByEmail(String email);
@Query("SELECT u FROM PortalUser u WHERE u.status = :status")
List<PortalUser> findByStatus(@Param("status") UserStatus status);
}
복잡한 쿼리는 QueryDSL 사용:
QPortalUser user = QPortalUser.portalUser;
return queryFactory.selectFrom(user)
.where(user.email.eq(email)
.and(user.status.eq(UserStatus.ACTIVE)))
.fetchOne();
트랜잭션 관리
적절한 propagation과 함께 @Transactional 사용:
- 기본값:
REQUIRED(기존 트랜잭션에 참여하거나 새로 생성) - 읽기 전용 작업: 최적화를 위해
@Transactional(readOnly = true) - 다중 데이터베이스: 분산 트랜잭션(JTA/XA) 없음. EMS·Gateway 각각 독립 로컬 트랜잭션이다.
- 무지정
@Transactional= EMS(transactionManager) - Gateway 엔티티(
com.eactive.apim.gateway.*,com.eactive.eai.data.entity.onl.*)를 다루는 서비스는@Transactional("gatewayTransactionManager")를 명시한다. 안 하면 게이트웨이 EntityManager 가 리포지토리 호출 단위로 닫혀 지연 로딩에서LazyInitializationException이 난다 (예:ApiServiceService—ApiGroup.apiGroupApiList). - 두 DB 를 한 원자 단위로 묶어야 하는 작업은 만들지 않는다. 현재 Gateway 는 조회 전용이다.
- 무지정
에러 처리
common/exception/의 글로벌 예외 처리:
@ControllerAdvice가 적용된GlobalExceptionHandler- 커스텀 예외는
RuntimeException확장 - Thymeleaf 에러 뷰 또는 AJAX 요청에는 JSON 반환
로깅
로깅은 application.yml 의 logging.file.path 가 아니라 logback 설정으로 제어한다.
- 설정 파일:
src/main/resources/logback-spring.xml(그 외logback-debug.xml,logback-local_gf63.xml) - 로그 디렉터리:
portal.logging.log-pathyml 프로퍼티 + 인스턴스명<springProperty scope="context" name="profileLogPath" source="portal.logging.log-path"/> <property name="LOG_PATH" value="${profileLogPath}/${inst.Name:-devSvr00}"/> application.yml기본값:portal.logging.log-path: /logs/prod/eapim- 산출 파일:
${LOG_PATH}/portal.log,${LOG_PATH}/hibernate.log등 (backup/에 일자 롤링)
Lombok의 @Slf4j와 함께 SLF4J 사용:
@Slf4j
@Service
public class UserService {
public void someMethod() {
log.debug("디버그 메시지");
log.info("정보 메시지");
log.error("에러 메시지", exception);
}
}
테스트 가이드
테스트 구조
src/test/java/com/eactive/apim/portal/의 테스트:
BaseWebTest- Spring Boot 테스트 컨텍스트를 가진 기본 클래스- 컨트롤러 테스트는
BaseWebTest확장 - 통합 테스트는
@SpringBootTest사용 - 독립적인 컨트롤러 테스트는
@WebMvcTest사용
일반적인 테스트 패턴
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest extends BaseWebTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void testUserRegistration() throws Exception {
mockMvc.perform(post("/user/register")
.param("email", "test@example.com")
.with(csrf()))
.andExpect(status().isOk())
.andExpect(view().name("user/register-success"));
}
}
SafeDB
SafeDB 모듈이 현재 빌드에서 빠져 있으므로(위 "멀티 모듈 구조" 참고) 테스트에서
별도로 켜고 끌 것이 없다. -Dsafedb= 옵션은 더 이상 동작하지 않는다.
중요 사항
한글 지원
이 포털은 한글을 광범위하게 사용합니다:
- Thymeleaf 템플릿은 한글 레이블 사용
- 데이터베이스는 한글 데이터 포함 (UTF-8)
- 한글 메시지 프로퍼티 (
messages_ko.properties) - 한글 사용자 가이드 (
개발자포탈.md)
비밀번호 정책
PortalUserValidator에서 적용:
- 최소 8자
- 대문자, 소문자, 숫자, 특수문자 포함 필수
- 연속된 문자 사용 불가
- 최근 3개 비밀번호 재사용 불가
- 90일 후 만료
세션 관리
- 사용자당 단일 세션 강제
- 세션 타임아웃: 10분 (쿠키명
JSESSIONID_PORTAL) - 로그인 시
changeSessionId()로 세션 고정 공격 방어 - 세션 상태는 DB 에 보관하며
apps/session/(filter/entity/repository) 과spring/DatabaseSessionVerifier.java가 담당한다. Redis 는 쓰지 않는다.
파일 업로드 제한
application.yml 의 portal.file 로 제어하고 config/PortalProperties.java 가 바인딩한다:
portal:
file:
max-size: 10MB
allowed-extensions: pdf,doc,docx,xls,xlsx,ppt,pptx,hwp,gif,jpg,jpeg,png
- 적용 지점:
config/MultipartConfig.java(setMaxUploadSize/setMaxUploadSizePerFile) - 초과 시 메시지:
common/exception/PortalGlobalExceptionHandler.java PortalProperties의 코드 기본값은8MB이지만 yml 이10MB로 덮어쓴다- 다운로드는
apps/file/controller/FileDownloadController.java하나뿐이다
배포
애플리케이션 서버 지원
WAR 파일 호환 서버:
- WebLogic (
src/main/resources/weblogic.xml) — 현재 실제 배포 대상 - JEUS (
src/main/resources/jeus-web-dd.xml) - Tomcat (Spring Boot 내장)
실제 배포는 Jenkinsfile.deploy 가 수행한다: djb-vm 노드에서 WAR 를 빌드해 stash 하고,
weblogic 라벨 노드에서 WebLogic 정지 → WAR 교체 → 기동 → readiness 확인 순으로 진행한다.
Jenkins 파이프라인
저장소 루트에 4개의 Jenkinsfile 이 있고 모두 origin/master 를 대상으로 한다:
| 파일 | 용도 |
|---|---|
Jenkinsfile.security |
OWASP Dependency-Check(SCA) + SonarQube(SAST). pollSCM 자동 트리거 |
Jenkinsfile.sonar |
SonarQube 정적 분석 전용 |
Jenkinsfile.test-build |
테스트 + WAR 빌드 + SBOM |
Jenkinsfile.deploy |
빌드 후 WebLogic 배포 |
빌드는 JDK 8(/apps/opts/jdk8), SonarScanner/Dependency-Check 실행은 JDK 17
(/apps/opts/jdk17)로 분리되어 있다. 스캐너 설정은 sonar-project.properties 와
ci/ 디렉터리(sonar-classpath.gradle, dependency-check-classpath.gradle,
dependency-check-suppressions.xml)에 있다.
알려진 CI 이슈 두 가지:
- Coverage 0% → Quality Gate ERROR: JaCoCo 미설정 (위 "테스트" 섹션 참고)
- Dependency-Check NVD 갱신 실패: Jenkins 에
nvd-api-keycredential 이 없다. 폐쇄망/키 부재 시에는UPDATE_NVD=false로 실행해 캐시 DB 로만 검사한다.
JNDI 설정 필수
dev 를 포함한 모든 환경에서 WAS 에 JNDI 리소스가 있어야 한다:
jdbc/dsOBP_EMS→ Portal 데이터베이스jdbc/dsOBP_AGW→ Gateway 데이터베이스
환경 변수
# 선택사항: 기본 설정 오버라이드
JAVA_OPTS="-Xmx2g -Xms1g -Dspring.profiles.active=prod"
Docker 배포
# WAR 빌드
gradle bootWar
# Docker 이미지 빌드 (build_docker.sh 는 없다)
docker build -t eapim-portal:latest .
# 컨테이너 실행
docker run -p 30200:30200 \
-e JAVA_OPTS="-Dspring.profiles.active=prod" \
-v /Log:/Log \
eapim-portal:latest
관련 모듈
다음 항목에 영향을 주는 변경 시:
- Gateway API 명세:
elink-online-core-jpa모듈 확인 - 공통 유틸리티:
elink-portal-common모듈 확인 - 암호화:
kjb-safedb모듈 — 현재 빌드에서 제외됨 (위 "멀티 모듈 구조" 참고) - Admin 포털:
../eapim-admin/관련 프로젝트 - Online 포털:
../eapim-online/관련 프로젝트
추가 자료
- 사용자 가이드 (한글):
개발자포탈.md - 로컬 기동 가이드 (Windows/Eclipse):
BOOTRUN_SETUP_GUIDE.md - 개발환경 준비, OHS 정적리소스 설정:
djb-docs/ - 메뉴 관리 개발 가이드:
readme-docs/메뉴-관리-개발-가이드.md - SASS/프론트 빌드:
package.json,sass-build.sh,tools/forge-entry.js - Docker:
Dockerfile - CI 설정:
Jenkinsfile.*,sonar-project.properties,ci/