Files
eapim-portal/CLAUDE.md
T
2025-11-21 21:48:07 +09:00

15 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 (targetCompatibility: 1.8)
  • Gradle 8.7 빌드 시스템
  • Oracle 19c 데이터베이스 (JNDI를 통한 이중 데이터소스)
  • Spring Security (커스텀 인증)
  • JPA/Hibernate 5.6.15 with Envers (감사 추적)
  • MapStruct (DTO 매핑), Lombok (보일러플레이트 제거)

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를 통한 병합만 허용

브랜치 사용 가이드:

# 개발 시작 시 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 단독 실행
  • msi-gf63 컴퓨터에서는 /c/eactive/workspaces/shell-scripts/kjb-gradle.sh 로 gradle 실행 (jdk, gradle 등 환경 변수 세팅 후 gradle 실행하는 스크립트)
# dev 프로파일로 실행 (기본값)
gradle bootRun

# 특정 프로파일로 실행
gradle bootRun --args='--spring.profiles.active=stage'

빌드

# Spring Boot 실행 가능 WAR 빌드
gradle bootWar
# 출력: build/libs/eapim-portal-boot.war

# 애플리케이션 서버용 표준 WAR 빌드 (JEUS/WebLogic)
gradle war
# 출력: build/libs/eapim-portal.war

# 클린 후 빌드
gradle clean build

테스트

# 모든 테스트 실행
gradle test

# 커버리지와 함께 테스트 실행
gradle test --info

# 특정 테스트 클래스 실행
gradle test --tests "com.eactive.apim.portal.apps.user.AccountControllerTest"

# 패턴에 매칭되는 테스트 실행
gradle test --tests "*Controller*"

개발

# 현재 프로파일 확인
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: EMSADM
    • Entities: com.eactive.apim.portal.apps.*
    • 목적: 포털 사용자, 조직, API 키, 승인
  2. Gateway Database (API Specs)

    • JNDI: jdbc/dsOBP_AGW
    • Schema: AGWADM
    • 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.ymlpages 섹션에 라우트 설정 (또는 @GetMapping/@PostMapping으로 직접 매핑)

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 방어
  • 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 리포지토리 메서드 사용 권장:

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)
  • 다중 데이터베이스: Atomikos JTA가 자동으로 분산 트랜잭션 처리

에러 처리

common/exception/의 글로벌 예외 처리:

  • @ControllerAdvice가 적용된 GlobalExceptionHandler
  • 커스텀 예외는 RuntimeException 확장
  • Thymeleaf 에러 뷰 또는 AJAX 요청에는 JSON 반환

로깅

application.yml의 로깅 설정:

logging:
  file:
    path: /Log/App/eapim/
  level:
    com.eactive.apim.portal: DEBUG
    org.hibernate.SQL: DEBUG (개발 환경만)

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 암호화가 비활성화됩니다. 필요한 경우:

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 데이터베이스

환경 변수

# 선택사항: 기본 설정 오버라이드
JAVA_OPTS="-Xmx2g -Xms1g -Dspring.profiles.active=prod"

Docker 배포

# WAR 빌드
gradle bootWar

# Docker 이미지 빌드
./build_docker.sh

# 컨테이너 실행
docker run -p 8080:8080 \
  -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/