# 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 브랜치 전략 **저장소 정보:** - 기본 저장소: `ssh://git@192.168.240.178:18081/eapim/eapim-portal.git` - 대체 저장소: `https://git.eactive.synology.me:8090/kjb-eapim/eapim-portal.git` **브랜치:** - **jenkins_with_weblogic**: Jenkins 빌드와 WebLogic 테스트를 위한 브랜치 (기본 개발 브랜치) - Jenkins CI/CD 파이프라인 설정 포함 - WebLogic 배포 및 테스트 환경 설정 - 일상적인 개발 작업은 이 브랜치에서 수행 - 기능 개발, 버그 수정, 테스트 등 모든 개발 활동의 기본 브랜치 - **master**: 완벽히 동작하는 검증된 코드 저장소 (안정 브랜치) - 프로덕션 배포 가능한 안정적인 코드만 포함 - jenkins_with_weblogic 브랜치에서 충분히 테스트된 코드만 병합 - 직접 커밋 금지, Pull Request를 통한 병합만 허용 **브랜치 사용 가이드:** ```bash # 개발 시작 시 jenkins_with_weblogic 브랜치에서 작업 git checkout jenkins_with_weblogic # 기능 개발 후 커밋 git add . git commit -m "기능 설명" # jenkins_with_weblogic 브랜치에 푸시 git push origin jenkins_with_weblogic # 충분한 테스트 완료 후 master로 병합 (Pull Request 사용) ``` ## 빌드 명령어 ### 애플리케이션 실행 - gradlew 사용 금지 - offline gradle 단독 실행 - JDK/Gradle 환경 변수는 저장소 루트의 `.envrc`(direnv)로 자동 설정됨 (JAVA_HOME → Zulu JDK 8, GRADLE_USER_HOME → 격리 디렉터리) ```bash # dev 프로파일로 실행 (기본값) gradle bootRun # 특정 프로파일로 실행 gradle bootRun --args='--spring.profiles.active=stage' ``` ### 빌드 ```bash # Spring Boot 실행 가능 WAR 빌드 gradle bootWar # 출력: build/libs/eapim-portal-boot.war # 애플리케이션 서버용 표준 WAR 빌드 (JEUS/WebLogic) gradle war # 출력: build/libs/eapim-portal.war # 클린 후 빌드 gradle clean build ``` ### 테스트 ```bash # 모든 테스트 실행 gradle test # 커버리지와 함께 테스트 실행 gradle test --info # 특정 테스트 클래스 실행 gradle test --tests "com.eactive.apim.portal.apps.user.AccountControllerTest" # 패턴에 매칭되는 테스트 실행 gradle test --tests "*Controller*" ``` ### 개발 ```bash # 현재 프로파일 확인 gradle printProfile # 소스 세트 설정 확인 gradle printSourceSets # Docker 이미지 빌드 ./build_docker.sh ``` ## 아키텍처 ### 멀티 모듈 구조 이 프로젝트는 Gradle composite build를 통해 3개의 외부 모듈에 의존합니다: 1. **elink-online-core-jpa** (`../eapim-online/elink-online-core-jpa`) - Gateway 데이터 모델 및 JPA 엔티티 - API 명세 엔티티 및 리포지토리 제공 - 패키지: `com.eactive.eai.data.entity.onl.*` 2. **elink-portal-common** (`../elink-portal-common`) - 공유 포털 유틸리티 및 공통 컴포넌트 - 기본 리포지토리 구현, QueryDSL 지원 - 공통 예외 핸들러 및 보안 유틸리티 3. **kjb-safedb** (`../kjb-safedb`) - 광주은행 SafeDB 암호화 라이브러리 - 데이터베이스 레벨 민감 데이터 암호화 - 암호화 컬럼(사용자 비밀번호, API 키 등)에 필수 ### 패키지 구조 코드는 기술 계층이 아닌 **기능 모듈**(수직 분할) 방식으로 구성됩니다: ``` com.eactive.apim.portal/ ├── apps/ # 기능 모듈 │ ├── agreements/ # API 약관 │ ├── apis/ # API 카탈로그 & 문서 │ ├── apiservice/ # API 서비스 그룹핑 │ ├── app/ # API 키 관리 │ ├── approval/ # 승인 워크플로우 │ ├── auth/ # 인증 │ ├── community/ # FAQ, 공지사항, Q&A, 제휴문의 │ ├── dashboard/ # 통계 & 분석 │ ├── file/ # 파일 업로드/다운로드 │ ├── login/ # 로그인/로그아웃 │ ├── proxy/ # API 테스트용 Forward Proxy │ ├── sample/ # 샘플 코드 생성 │ └── user/ # 사용자 관리 ├── common/ # 공통 관심사 ├── config/ # Spring 설정 └── gateway/ # Gateway DB 직접 접근 └── data/ # Gateway 리포지토리 ``` 각 기능 모듈은 일반적으로 다음을 포함합니다: - `controller/` - Spring MVC 컨트롤러 (@Controller) - `service/` - 비즈니스 로직 (@Service, @Transactional) - `repository/` - Spring Data JPA 리포지토리 - `dto/` - 데이터 전송 객체 (Lombok @Data) - `mapper/` - MapStruct 인터페이스 (entity ↔ DTO 변환) ### 이중 데이터베이스 아키텍처 애플리케이션은 두 개의 Oracle 데이터베이스를 사용합니다: 1. **EMS Database** (Portal/Admin) - JNDI: `jdbc/dsOBP_EMS` - Schema: `EMSAPP` - Entities: `com.eactive.apim.portal.apps.*` - 목적: 포털 사용자, 조직, API 키, 승인 2. **Gateway Database** (API Specs) - JNDI: `jdbc/dsOBP_AGW` - Schema: `AGWAPP` - Entities: `com.eactive.eai.data.entity.onl.*` - 목적: API 명세, 서비스, 메시지 설정: `config/PortalDatasourceConfiguration.java` - 각 데이터베이스별 별도 EntityManager - Atomikos JTA를 통한 분산 트랜잭션 - 트랜잭션 로그: `/Log/eapim/portal/` ### 설정 프로파일 환경별 설정 파일: `src/main/resources/application-{profile}.yml` - **dev**: 개발 환경 (Oracle at 192.168.240.177:1599, DevTools 활성화, SQL 로깅) - **stage**: 스테이징 환경 (JNDI 데이터소스, proxy to inter-dapiwas01) - **prod**: 운영 환경 (JNDI 데이터소스, proxy to inter-apiwas00, 캐싱 활성화) - **gf63**: 개인 개발 환경 - **kjb_rinjae**: 개인 개발 환경 주요 설정: - 세션 타임아웃: 15분 - 파일 업로드 최대: 8MB - 비밀번호 만료: 90일 - 인증 토큰 TTL: 5분 (300초) - 사용자 승인 필수: true ## 주요 기능 및 비즈니스 로직 ### 사용자 관리 (`apps/user/`) 두 가지 사용자 유형: 1. **내부 사용자 (Staff)**: 포털 관리자 및 운영자 2. **기업 사용자 (Enterprise)**: 외부 API 소비자 사용자 라이프사이클: - 가입 → 이메일 인증 → 관리자 승인 → 활성화 - 비밀번호 정책 적용 (90일 만료, 복잡도 규칙) - 로그인 실패 시 계정 잠금 - 휴면 계정 관리 ### API 키 관리 (`apps/app/`) API 키는 승인 워크플로우와 함께 관리됩니다: - 기업 관리자가 `AppRequestController`를 통해 키 요청 - 관리자가 `ApprovalController`를 통해 승인/반려 - 키는 개발/운영 환경 지원 - 키는 eLink Gateway ClientID/ClientSecret과 연결 ### 승인 워크플로우 (`apps/approval/`) 다음 항목에 대한 범용 승인 시스템: - 사용자 등록 승인 - API 키 생성/수정 - 제휴 신청 엔티티: `Approval`, `Approver`, `ApprovalStatus` (WAITING, APPROVED, REJECTED) ### API 테스트 (`apps/proxy/`, `apps/sample/`) - Gateway 서버로의 Forward Proxy - 요청/응답 로깅이 있는 API 테스터 - 여러 언어의 샘플 코드 생성 - API 문서를 위한 Swagger UI 통합 ### 감사 추적 (Hibernate Envers) 모든 엔티티는 자동 감사를 위해 `AbstractAuditingEntity`를 확장합니다: - `createdBy`, `createdDate` - `lastModifiedBy`, `lastModifiedDate` - `@Audited` 어노테이션으로 변경 이력 관리 - Spring Data Envers를 통한 이력 조회 ## 공통 개발 패턴 ### 새 기능 모듈 추가하기 1. `apps/` 하위에 패키지 생성 (예: `apps/newfeature/`) 2. `controller/`, `service/`, `repository/`, `dto/`, `mapper/`로 구조화 3. `repository/entity/`에 JPA 엔티티 생성 (`AbstractAuditingEntity` 확장) 4. `dto/`에 Lombok `@Data`를 사용한 DTO 생성 5. `mapper/`에 MapStruct 매퍼 인터페이스 생성 6. `@Service`와 `@Transactional`을 사용한 서비스 계층 구현 7. `@Controller`와 `@RequestMapping`을 사용한 컨트롤러 생성 8. `src/main/resources/templates/views/newfeature/`에 Thymeleaf 템플릿 추가 9. `application.yml`의 `pages` 섹션에 라우트 설정 (또는 `@GetMapping`/`@PostMapping`으로 직접 매핑) ### MapStruct DTO 매핑 타입 안전한 DTO 변환을 위해 MapStruct 사용: ```java @Mapper(componentModel = "spring") public interface UserMapper { PortalUserDto toDto(PortalUser entity); PortalUser toEntity(PortalUserDto dto); List toDtoList(List entities); } ``` 생성된 구현체는 `build/generated/sources/annotationProcessor/java/main/`에 위치 ### 보안 및 인증 보안 설정: `config/PortalConfigSecurity.java` - 커스텀 인증 관리자: `PortalAuthenticationManager` - `changeSessionId()`를 통한 세션 고정 공격 방어 - 쿠키 기반 토큰을 사용한 CSRF 방어 - Lucy 필터를 통한 XSS 방어 역할 계층: ``` ROLE_USER → [ROLE_INQUIRY, ROLE_ACCOUNT] ROLE_CORP_USER → [ROLE_INQUIRY, ROLE_APP, ROLE_ACCOUNT] ROLE_CORP_MANAGER → [ROLE_API_KEY_REQUEST, ROLE_INQUIRY, ROLE_APP, ROLE_ACCOUNT, ROLE_CORP_API, ROLE_DASHBOARD, ROLE_USER_MANAGER] ``` ### 데이터베이스 쿼리 Spring Data JPA 리포지토리 메서드 사용 권장: ```java public interface PortalUserRepository extends JpaRepository { Optional findByEmail(String email); @Query("SELECT u FROM PortalUser u WHERE u.status = :status") List findByStatus(@Param("status") UserStatus status); } ``` 복잡한 쿼리는 QueryDSL 사용: ```java 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)` - 다중 데이터베이스: Atomikos JTA가 자동으로 분산 트랜잭션 처리 ### 에러 처리 `common/exception/`의 글로벌 예외 처리: - `@ControllerAdvice`가 적용된 `GlobalExceptionHandler` - 커스텀 예외는 `RuntimeException` 확장 - Thymeleaf 에러 뷰 또는 AJAX 요청에는 JSON 반환 ### 로깅 `application.yml`의 로깅 설정: ```yaml logging: file: path: /Log/App/eapim/ level: com.eactive.apim.portal: DEBUG org.hibernate.SQL: DEBUG (개발 환경만) ``` Lombok의 `@Slf4j`와 함께 SLF4J 사용: ```java @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` 사용 ### 일반적인 테스트 패턴 ```java @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 암호화가 비활성화됩니다. 필요한 경우: ```bash gradle test -Dsafedb=/path/to/safedb ``` ## 중요 사항 ### 한글 지원 이 포털은 한글을 광범위하게 사용합니다: - Thymeleaf 템플릿은 한글 레이블 사용 - 데이터베이스는 한글 데이터 포함 (UTF-8) - 한글 메시지 프로퍼티 (`messages_ko.properties`) - 한글 사용자 가이드 (`개발자포탈.md`) ### Forward Proxy 설정 API 테스트는 Gateway로의 Forward Proxy 사용: - Dev: `http://localhost:10000` - Stage: `http://inter-dapiwas01:10000` - Prod: `http://inter-apiwas00:10000` 설정: `apps/proxy/service/ProxyService.java` ### 비밀번호 정책 `PortalUserValidator`에서 적용: - 최소 8자 - 대문자, 소문자, 숫자, 특수문자 포함 필수 - 연속된 문자 사용 불가 - 최근 3개 비밀번호 재사용 불가 - 90일 후 만료 ### 세션 관리 - 사용자당 단일 세션 강제 - 세션 타임아웃: 15분 - 로그인 시 세션 고정 공격 방어 - Redis/Ehcache를 통한 세션 클러스터링 (스테이징/운영) ### 파일 업로드 제한 - 최대 파일 크기: 8MB - `FileService`에서 허용 확장자 설정 - 파일 저장 위치: `/Log/App/eapim/files/` - 업로드 시 XSS 스캐닝 ## 배포 ### 애플리케이션 서버 지원 WAR 파일 호환 서버: - **JEUS** (`jeus-web-dd.xml` 필요) - **WebLogic** (`weblogic.xml` 필요) - **Tomcat** (Spring Boot 내장) ### JNDI 설정 필수 스테이징/운영 환경에서 JNDI 리소스 설정: - `jdbc/dsOBP_EMS` → Portal 데이터베이스 - `jdbc/dsOBP_AGW` → Gateway 데이터베이스 ### 환경 변수 ```bash # 선택사항: 기본 설정 오버라이드 JAVA_OPTS="-Xmx2g -Xms1g -Dspring.profiles.active=prod" ``` ### Docker 배포 ```bash # WAR 빌드 gradle bootWar # Docker 이미지 빌드 ./build_docker.sh # 컨테이너 실행 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` - 빌드 스크립트: `build-gf63.sh`, `deploy_portal.sh`, `deploy_portal2.sh` - Docker: `Dockerfile`, `build_docker.sh` - SQL 스크립트: `../kjb-eapim-sql/`