- 내부/외부 VMIS 모드 통합 및 외부 REST URL 동적 구성
- VehicleInfoService로 서비스 계층 역할 재구성
- BasicResponse 및 LedgerResponse 단독 조회 기능 추가
- VMIS 통합 속성 구조 변경 및 application-{profile}.yml 수정
- 컨트롤러 메서드 간결화 및 모드 기반 분기 로직 추가
- 중복 모델 제거 및 Envelope 구조 통일
- Swagger 테스트 컨트롤러 보강
- ExternalVehicleApiServiceImpl: 외부 VMIS API 호출 구현
- 차량 기본정보 및 등록원부 조회 로직 추가
- 오류 처리 및 실패 응답 객체 생성 로직 포함
- VmisCarBassMatterInqireServiceImpl/VmisCarLedgerFrmbkServiceImpl:
- 내부 서비스 관계와 API 호출 보강, 응답 로그 저장 로직 추가
- 오류 시 트랜잭션 독립적 로그 작성 보장
- 관련 로그 서비스 구현체 (VmisCarBassMatterInqireLogServiceImpl, VmisCarLedgerFrmbkLogServiceImpl): 요청/응답 로그 저장 및 오류 로그 추가
- 기존 인터페이스 및 클래스 위치 이동 (VehicleInfoService 등)
- VMIS RestTemplate 설정을 내부/외부 모드로 분리
- Internal Mode: 정부 API 호출 설정(빠른 타임아웃)
- External Mode: 외부 API 호출 설정(완화된 타임아웃)
- application-{profile}.yml에 환경별 VMIS 설정 추가
- RestTemplateProperties -> VmisProperties로 대체하여 설정 통합
- 타임아웃, 연결 풀, Rate Limit 설정을 모드별로 분기
- 기존 regionCode -> sigunguCode로 수정하여 의미 명확화
- 로그 포맷 개선 및 나열 정보 추가
## 효과
- 환경 구성 단순화 및 명확화
- RestTemplate 설정 관리 용이성 향상
- 코드 유지보수성 및 가독성 개선
✅ BUILD SUCCESSFUL
중복 VO 제거 및 응답 모델 단순화
## 제거된 파일
- ❌ VehicleBasicInfoVO.java
- ❌ VehicleLedgerVO.java
- ❌ VehicleResponseMapper.java (변환 로직 제거)
## 변경된 사용처
- VehicleApiResponseVO: BasicResponse, LedgerResponse 직접 사용
- InternalVehicleInfoServiceImpl: Mapper 제거하고 BasicResponse/LedgerResponse 직접 반환
- ExternalVehicleApiService: 동일하게 BasicResponse/LedgerResponse 사용
## 최종 모델 구조 (9개)
```
api/model/
├── Envelope.java # 공통 Envelope
├── VehicleApiResponseVO.java # 최상위 응답
├── request/ # 요청 (2개)
│ ├── BasicRequest.java
│ └── LedgerRequest.java
└── response/ # 응답 (5개)
├── BasicResponse.java ⭐ 클라이언트 응답용
├── LedgerResponse.java ⭐ 클라이언트 응답용
├── VmisCarBassMatterInqireVO.java # DB 저장용
├── VmisCarLedgerFrmbkVO.java # DB 저장용
└── VmisCarLedgerFrmbkDtlVO.java # DB 저장용
```
## 효과
- 중복 모델 제거 (3개 파일 삭제)
- 변환 레이어 제거 (VehicleResponseMapper 삭제)
- Internal/External 모두 동일한 응답 모델 사용
- 코드 간소화 및 유지보수성 향상
## 빌드 결과
✅ BUILD SUCCESSFUL
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
이름만 다르고 필드가 동일한 클래스 통합
## 통합된 클래스
### 1. Envelope (완전히 동일)
- ❌ api/internal/model/common/Envelope.java (삭제)
- ✅ api/vo/Envelope.java (유지)
- 변경: internal 패키지 전체에서 import 경로 수정
### 2. BasicRequest (더 완전한 버전 사용)
- ❌ api/vo/VehicleBasicRequestVO.java (삭제)
- ✅ api/internal/model/basic/BasicRequest.java (유지)
- 변경: ExternalVehicleApiService에서 BasicRequest 사용
### 3. LedgerRequest (더 완전한 버전 사용)
- ❌ api/vo/VehicleLedgerRequestVO.java (삭제)
- ✅ api/internal/model/ledger/LedgerRequest.java (유지)
- 변경: ExternalVehicleApiService에서 LedgerRequest 사용
## 효과
- 중복 클래스 3개 제거
- Internal/External 모두 동일한 모델 사용
- 코드 일관성 및 유지보수성 향상
## 빌드 결과
✅ BUILD SUCCESSFUL
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
API 패키지 구조, Internal/External 패턴, 데이터 흐름 상세 설명
## 문서 내용
- API 패키지 전체 구조 및 각 구성요소 설명
- Strategy Pattern을 통한 Internal/External 모드 전환
- 각 모드별 상세 동작 원리 및 데이터 흐름
- 설정 가이드 및 사용 예제
- 트러블슈팅 및 성능 최적화 가이드
## 주요 섹션
1. 개요 및 설계 원칙
2. 패키지 구조 (디렉토리 트리)
3. 아키텍처 패턴 (Strategy, DI, 계층화)
4. Internal Mode 상세 (GPKI, 정부 API 연동)
5. External Mode 상세 (REST API 호출)
6. 공통 구성요소 (VO, Properties, Config)
7. 데이터 흐름 다이어그램
8. 설정 가이드 (개발/운영 환경)
9. 사용 예제 (Controller, Service)
10. 모드 전환 시나리오
11. 트러블슈팅
12. 성능 최적화
13. 보안 고려사항
14. 확장 가능성
## 파일 위치
docs/API_ARCHITECTURE.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Mapper 중복 스캔 경고 해결 및 용도별 명확한 분리
## 문제
- DatabaseConfig에서 중복 패턴으로 Mapper 스캔
- "Bean already defined with the same name!" 경고 발생
- go.kr.project.**.mapper가 api.internal.mapper 포함하여 중복
## 해결
- DatabaseConfig → ApiMapperConfig로 변경 (API 전용)
- ProjectMapperConfig 신규 생성 (일반 프로젝트용)
## 변경사항
- ApiMapperConfig: go.kr.project.api.internal.mapper만 스캔
- ProjectMapperConfig: 일반 프로젝트 및 egovframework mapper 스캔
- carInspectionPenalty.**.mapper
- common.mapper
- login.mapper
- system.**.mapper
- egovframework.**.mapper
## 최종 구조
- API 전용: ApiMapperConfig
- 일반 프로젝트: ProjectMapperConfig
- 중복 없이 명확하게 분리
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
DatabaseConfig에서 중복 TransactionManager Bean 제거
## 문제
- DatabaseConfig.transactionManager와 EgovConfigTransaction.txManager 충돌
- "expected single matching bean but found 2" 에러 발생
## 해결
- DatabaseConfig에서 transactionManager Bean 제거
- egovframework의 txManager Bean 사용
- DatabaseConfig는 MapperScan만 담당
## 최종 설정
- DataSource: egovframework.config.DataSourceProxyConfig
- TransactionManager: egovframework.config.EgovConfigTransaction.txManager
- MapperScan: DatabaseConfig
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
패키지 리팩토링 후 Mapper 스캔 경로 수정
## 변경사항
- @MapperScan 경로 업데이트
- 기존: go.kr.project.vmis.mapper
- 변경: go.kr.project.api.internal.mapper 포함 전체 mapper 패키지
## 수정 파일
- DatabaseConfig.java
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
VO 중복 해결 및 패키지 구조 명확화
## 주요 변경사항
### 패키지 구조 재구성
- `go.kr.project.vmis` → `go.kr.project.api.internal`
- `go.kr.project.externalApi` → `go.kr.project.api.external`
- 공통 모델: `go.kr.project.api.model`
- 공통 VO: `go.kr.project.api.vo`
- 공통 설정: `go.kr.project.api.config`
### 새로운 구조
```
go.kr.project.api/
├── model/ # 공통 모델
│ ├── basic/ (BasicRequest, BasicResponse)
│ ├── ledger/ (LedgerRequest, LedgerResponse)
│ └── common/ (Envelope)
├── vo/ # 공통 API 응답 VO
│ ├── VehicleApiResponseVO
│ ├── VehicleBasicInfoVO
│ └── VehicleLedgerVO 등
├── config/ # 공통 설정
│ ├── properties/ (VmisProperties)
│ ├── ApiConstant
│ ├── VmisIntegrationConfig
│ └── DatabaseConfig
├── VehicleInfoService # 공통 인터페이스
├── internal/ # 내부 모드 (기존 vmis)
│ ├── client/
│ ├── config/
│ ├── controller/
│ ├── gpki/
│ ├── mapper/
│ ├── model/ # 내부 전용 DB VO
│ ├── service/
│ └── util/
└── external/ # 외부 모드 (기존 externalApi)
└── service/
```
### VO 중복 제거
- ✅ history 패키지와 api.internal 패키지의 VO 명확히 구분
- ✅ 공통 모델은 api.model에서 공유
- ✅ Bean 충돌 완전 해결
### MyBatis 업데이트
- mapper 디렉토리: `mybatis/mapper/vmis` → `mybatis/mapper/api-internal`
- namespace: `go.kr.project.vmis` → `go.kr.project.api.internal`
### application.yml 업데이트
- mapper-locations: `api-internal/**/*_maria.xml`
## 장점
✅ 패키지 구조 명확화 (internal/external 구분)
✅ 공통 모델 공유로 중복 제거
✅ 더 나은 아키텍처
✅ 모드별 책임 명확
## 빌드 성공 확인 ✅🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
VO, Service, Mapper 클래스 이름 충돌 문제 해결
## 문제
- history 패키지와 vmis 패키지에 동일한 이름의 VO 클래스 존재
- CarBassMatterInqireVO, CarLedgerFrmbkVO, CarLedgerFrmbkDtlVO 충돌
- Bean 생성 오류 발생
## 해결
모든 VMIS 패키지 클래스에 Vmis prefix 추가:
### VO 클래스 (충돌 해결)
- CarBassMatterInqireVO → VmisCarBassMatterInqireVO
- CarLedgerFrmbkVO → VmisCarLedgerFrmbkVO
- CarLedgerFrmbkDtlVO → VmisCarLedgerFrmbkDtlVO
### Service 클래스
- CarBassMatterInqireService → VmisCarBassMatterInqireService
- CarBassMatterInqireLogService → VmisCarBassMatterInqireLogService
- CarLedgerFrmbkService → VmisCarLedgerFrmbkService
- CarLedgerFrmbkLogService → VmisCarLedgerFrmbkLogService
- RequestEnricher → VmisRequestEnricher
### Mapper 클래스
- CarBassMatterInqireMapper → VmisCarBassMatterInqireMapper
- CarLedgerFrmbkMapper → VmisCarLedgerFrmbkMapper
### MyBatis XML 업데이트
- mapper namespace 및 resultType 변경
- CarBassMatterInqireMapper_maria.xml
- CarLedgerFrmbkMapper_maria.xml
## 빌드 성공 확인 ✅
- Bean 충돌 완전 해결
- 전체 컴파일 성공
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
내부/외부 API 호출을 YAML 설정으로 전환할 수 있는 Strategy Pattern 구현
## 주요 변경사항
### 1. Strategy Pattern 구현
- VehicleInfoService 인터페이스 생성 (공통 추상화)
- InternalVehicleInfoServiceImpl: 내부 VMIS 모듈 직접 호출
- ExternalVehicleInfoServiceImpl: 외부 REST API 호출
- @ConditionalOnProperty로 mode에 따라 Bean 자동 선택
### 2. Bean 충돌 해결
- HttpClientConfig의 restTemplate → vmisRestTemplate으로 변경
- GovernmentApiClient에 @Qualifier("vmisRestTemplate") 추가
- 기존 RestTemplateConfig와 충돌 방지
### 3. 설정 확장
- VmisProperties에 integration, external 속성 추가
- vmis.integration.mode: internal/external 설정 지원
- vmis.external.api.url: 외부 API 서버 URL 설정
### 4. 모델 변환 유틸리티
- VehicleResponseMapper 생성
- 내부 모델(BasicResponse, LedgerResponse) → 외부 VO 변환
### 5. 모니터링 및 로깅
- VmisIntegrationConfig: 시작 시 활성 모드 출력
- 각 구현체에 [Internal Mode]/[External Mode] 로그 추가
## 사용 방법
### Internal Mode (내부 모듈 직접 호출)
```yaml
vmis:
integration:
mode: internal
```
### External Mode (외부 REST API 호출)
```yaml
vmis:
integration:
mode: external
external:
api:
url: http://localhost:8081/api/v1/vehicles
```
## 빌드 성공 확인 ✅
- Bean 충돌 해결 완료
- 전체 컴파일 성공
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- VMIS-interface 전체 코드 이식 (33개 Java 파일, 2개 XML)
- 패키지 변경: com.vmis.interfaceapp → go.kr.project.vmis
- Spring Boot 3 → 2 호환: jakarta → javax
- Java 17 → 8 호환: Text Blocks, List.of() 제거
- HttpClient 5 → 4 변환
- GPKI 라이브러리 추가
- application.yml에 VMIS 설정 통합
- MyBatis 매퍼 경로 추가
빌드 성공 확인 ✅
Co-Authored-By: Claude <noreply@anthropic.com>