feat: P6 외부연동 호출 감사 이력 (V85)
펌뱅킹/SMS·카카오 어댑터 모든 호출을 external_call_log 테이블에 AOP 자동 영속화.
외부 SDK 통합 후에도 그대로 재사용. 운영 감사·장애 추적·SDK 검증 용도.
- V85: external_call_log 테이블 + 인덱스 4종 (called_at desc / type / target / failures)
+ SYSTEM_EXTERNAL_CALL 메뉴 + READ 권한 (SUPER_ADMIN/ADMIN)
- ga-core: ExternalCallLogVO/Resp/SearchParam + Mapper (insertOne / selectList / selectById)
- ga-api/aop: ExternalCallLoggingAspect — BankTransferAdapter+/MessageAdapter+
모든 메서드 @Around 영속화. 호출자 트랜잭션과 분리(REQUIRES_NEW),
request/response 는 PII 마스킹된 JSON 한 줄 요약(계좌·전화 뒤 4자리, 이름 첫글자만),
영속화 자체가 실패해도 비즈니스 흐름 비차단(warn 로그만), 예외는 그대로 propagate.
- ga-api: ExternalCallLogService + Controller GET /api/external-call-logs[/{id}]
- ga-frontend: ExternalCallLogList.tsx + api/externalCallLog.ts + App.tsx 라우트
/system/external-call-log (ProTable + Drawer 상세)
라이브 검증:
- Flyway V85 자동 적용 → 운영 DB schema v85
- 5모듈 컴파일 BUILD SUCCESSFUL + ga-frontend tsc --noEmit 통과
- 시나리오: withdraw#3 신규 → 결재 advance ×2 → 펌뱅킹 호출
external_call_log #1: BANK/MockBankTransferAdapter/requestTransfer/
success=true/durMs=3/target=WITHDRAW#3/accountNoMasked="****0123"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+115
-15
@@ -191,20 +191,115 @@
|
||||
|
||||
운영 DB 최신 상태: ga schema V73 적용 완료.
|
||||
|
||||
## 4. 잔여 작업 (P6)
|
||||
## 3-11. P6 PoC — 외부 연동 어댑터 모듈 (V81~V84, 2026-05-24 라이브 적용)
|
||||
|
||||
P5-W2 / P5-W3(메뉴·권한 보강 V74 + 본론 V75~V78) 모두 완료. 잔여는 P6뿐.
|
||||
P6 본 작업의 PoC가 완료되어 어댑터 추상화 + Mock 구현 + SDK 분기 + 운영 잔여 기능까지 들어감.
|
||||
실제 KFTC/Toast SDK 통합 시 어댑터 구현체만 바꾸면 ga-api/ga-common 무변경.
|
||||
|
||||
### P6 — 외부 연동 (P5 이후)
|
||||
| 항목 | 설명 |
|
||||
|---|---|
|
||||
| 펌뱅킹 실연동 | withdraw_request 결재 완료 → 은행 API 직접 호출 |
|
||||
| SMS/카카오 발송 | user_notification 채널 실연동 |
|
||||
| 모바일 셀프 조회 | 설계사 전용 모바일 앱 or PWA |
|
||||
| 항목 | 마이그레이션 | 상태 |
|
||||
|---|---|---|
|
||||
| 분급 비율 회차(월) 단위 등록 지원 | V81 | 완료 |
|
||||
| withdraw_request 펌뱅킹 추적 컬럼 (transfer_tx_id/transfer_status/transfer_at) | V82 | 완료 |
|
||||
| WITHDRAW_REQUESTS EXECUTE 권한 보강 (오기 — 0건 적용) | V83 | 완료(no-op) |
|
||||
| WITHDRAW 메뉴 EXECUTE 권한 (V83 보정본) | V84 | 완료 |
|
||||
|
||||
핵심 산출물:
|
||||
- **신규 모듈 `ga-external-adapter`** — 외부 SDK 의존성 격리, settings.gradle 등록
|
||||
- ga-common.adapter.bank: `BankTransferAdapter` 인터페이스 + Request/Response/Status
|
||||
- ga-common.adapter.message: `MessageAdapter` 인터페이스 + Channel(SMS/KAKAO)/Request/Response
|
||||
- `MockBankTransferAdapter` / `MockMessageAdapter` (로그 + 계좌·전화 마스킹, 기본 활성)
|
||||
- `KftcBankTransferAdapter` / `ToastMessageAdapter` 스켈레톤 (UnsupportedOperationException, SDK 통합 시 구현)
|
||||
- `@ConditionalOnProperty` 프로파일 분기: `app.adapter.bank=mock|kftc`, `app.adapter.message=mock|toast`
|
||||
- `ApprovalService.handleApprovalCallback(WITHDRAW)` — 최종 승인 시 펌뱅킹 어댑터 호출 → 성공 시 APPROVED→SENT 전이 + transfer_tx_id 영속화, 실패 시 APPROVED 유지 + fail_reason 기록
|
||||
- `ApprovalService.sendStepNotification` — DB 알림 외 SMS 어댑터 호출 (UserMapper.selectFirstActiveContactByRoleCode 로 실제 결재자 phone 매핑, phone 미확보 시 SMS skip)
|
||||
- `WithdrawBankRetryService` + `BankRetryController` (`POST /api/internal/bank-retry`) — 실패 transfer 재시도 배치 + `@EnableScheduling` + cron 옵션(기본 비활성) + `app.bank-retry.limit`
|
||||
- `WithdrawRequestMapper.selectFailedTransfers` / `updateTransferResult` 추가
|
||||
- `WithdrawRequestVO/Resp` + `WithdrawRequestMapper.xml` + 화면 `WithdrawRequest.tsx` 에 transfer_tx_id/transfer_status/transfer_at 노출
|
||||
|
||||
설정값(application.yml):
|
||||
```yaml
|
||||
app:
|
||||
adapter:
|
||||
bank: ${ADAPTER_BANK:mock} # mock | kftc
|
||||
message: ${ADAPTER_MESSAGE:mock} # mock | toast
|
||||
bank-retry:
|
||||
limit: ${BANK_RETRY_LIMIT:50}
|
||||
cron: ${BANK_RETRY_CRON:0 0 0 1 1 ?} # 사실상 비활성. 운영 활성화 예 "0 */10 * * * *"
|
||||
```
|
||||
|
||||
통합 검증 결과 (2026-05-24):
|
||||
- 5모듈 컴파일 BUILD SUCCESSFUL (ga-common/ga-core/ga-external-adapter/ga-api/ga-batch)
|
||||
- 운영 DB v82~v84 적용 완료, ga-api 8082 가동
|
||||
- POST /api/auth/login → 200 OK, accessToken 발급
|
||||
- GET /api/withdraw-requests → 200 OK, 2건 모두 status=SENT / transfer_status=ACCEPTED / transferTxId="MOCK-…" 영속화
|
||||
- POST /api/internal/bank-retry → 200 OK, data=0 (실패 건 없음 — 정상)
|
||||
- GET /api/approvals/requests/mine → 200 OK, WITHDRAW APPROVED 이력 정상
|
||||
- GET /api/forecast-kpi → 200 OK
|
||||
- GET /api/year-end-statements → 200 OK
|
||||
|
||||
보정 사항:
|
||||
- V83 작성 시 menu_code 오기로 0건 적용 → V84 로 정정 보강
|
||||
|
||||
## 4. 잔여 작업 (P6 실연동)
|
||||
|
||||
P5 전체 + P6 PoC(어댑터 모듈 + Mock 구현 + SDK 분기 + 재시도 배치 + DB 추적 컬럼) 완료.
|
||||
잔여는 **외부 스펙 확정 후 적용** 가능한 항목 + 모바일.
|
||||
|
||||
### P6 실연동
|
||||
| 항목 | 설명 | 선행 조건 |
|
||||
|---|---|---|
|
||||
| KFTC 펌뱅킹 실 SDK 통합 | `KftcBankTransferAdapter` 본체 구현 + 인증·엔드포인트 주입 | KFTC API 키·계약·테스트망 |
|
||||
| Toast(NHN) SMS 실 SDK 통합 | `ToastMessageAdapter` 본체 구현 | 계정·App Key·발신번호·템플릿 코드 |
|
||||
| 카카오 알림톡 실 SDK 통합 | 동일 (채널만 KAKAO) | 비즈 채널·템플릿 승인 |
|
||||
| 펌뱅킹 SETTLED 동기화 | ACCEPTED→SETTLED 폴링 스케줄 (queryStatus 사용) | 실 SDK 통합 이후 |
|
||||
| 펌뱅킹/메시지 호출 감사 이력 | `external_call_log` 테이블 + 영속화 + 조회 화면 | 독립 진행 가능 |
|
||||
| 모바일 셀프 조회 PWA | 설계사 전용. 정산 명세서/출금 신청/공지 등 | 화면 우선순위 협의 |
|
||||
|
||||
## 3-12. P6 PoC — 외부연동 호출 감사 이력 (V85, 2026-05-24 라이브 적용)
|
||||
|
||||
P6 PoC 의 운영성 보강. 펌뱅킹/SMS·카카오 어댑터 모든 호출이 `external_call_log` 테이블에 AOP 로 자동 영속화. 외부 SDK 통합 후에도 그대로 재사용.
|
||||
|
||||
| 항목 | 위치 | 상태 |
|
||||
|---|---|---|
|
||||
| external_call_log 테이블 + 인덱스 + SYSTEM_EXTERNAL_CALL 메뉴/권한 | V85 | 완료 |
|
||||
| ExternalCallLogVO / Resp / SearchParam | ga-core | 완료 |
|
||||
| ExternalCallLogMapper(.java/.xml) — insertOne + selectList + selectById | ga-core | 완료 |
|
||||
| ExternalCallLogService — recordCall @Transactional(REQUIRES_NEW) | ga-api | 완료 |
|
||||
| ExternalCallLogController — GET /api/external-call-logs[/{id}] | ga-api | 완료 |
|
||||
| ExternalCallLoggingAspect — BankTransferAdapter+/MessageAdapter+ 모든 메서드 @Around | ga-api/aop | 완료 |
|
||||
| ExternalCallLogList.tsx + api/externalCallLog.ts + App.tsx 라우트 | ga-frontend | 완료 |
|
||||
|
||||
핵심 동작:
|
||||
- 어댑터 호출 전/후·예외 모두 `external_call_log` INSERT (호출자 트랜잭션과 분리 — REQUIRES_NEW)
|
||||
- request/response 는 PII 마스킹된 JSON 한 줄로 요약 (계좌·전화 뒤 4자리, 이름 첫글자만)
|
||||
- 영속화 자체가 실패해도 비즈니스 흐름은 절대 깨지 않음 (warn 로그만)
|
||||
- `target_ref_type/id` 자동 추출: WITHDRAW(BankTransferRequest.withdrawRequestId), MessageRequest.refType/refId
|
||||
|
||||
통합 검증 결과 (2026-05-24):
|
||||
- Flyway: V85 자동 적용 → 운영 DB schema **v85**
|
||||
- 5모듈 컴파일 BUILD SUCCESSFUL + ga-frontend TS 타입 검증 통과
|
||||
- 라이브 시나리오: 신규 withdraw#3 → 결재 1단계 + 2단계 APPROVE → 최종 승인 → 펌뱅킹 호출
|
||||
- withdraw#3 status=SENT, transferTxId=MOCK-…, transferStatus=ACCEPTED
|
||||
- GET /api/external-call-logs → total=1, log#1: BANK/MockBankTransferAdapter/requestTransfer/success=true/durMs=3/target=WITHDRAW#3
|
||||
- 상세: requestSummary 의 accountNoMasked="****0123" — PII 마스킹 정상 (평문 비노출)
|
||||
|
||||
## 4. 잔여 작업 (P6 실연동)
|
||||
|
||||
P5 전체 + P6 PoC(어댑터 모듈 + Mock 구현 + SDK 분기 + 재시도 배치 + DB 추적 컬럼 + **호출 감사 이력**) 완료.
|
||||
잔여는 **외부 스펙 확정 후 적용** 가능한 항목 + 모바일.
|
||||
|
||||
### P6 실연동
|
||||
| 항목 | 설명 | 선행 조건 |
|
||||
|---|---|---|
|
||||
| KFTC 펌뱅킹 실 SDK 통합 | `KftcBankTransferAdapter` 본체 구현 + 인증·엔드포인트 주입 | KFTC API 키·계약·테스트망 |
|
||||
| Toast(NHN) SMS 실 SDK 통합 | `ToastMessageAdapter` 본체 구현 | 계정·App Key·발신번호·템플릿 코드 |
|
||||
| 카카오 알림톡 실 SDK 통합 | 동일 (채널만 KAKAO) | 비즈 채널·템플릿 승인 |
|
||||
| 펌뱅킹 SETTLED 동기화 | ACCEPTED→SETTLED 폴링 스케줄 (queryStatus 사용) | 실 SDK 통합 이후 |
|
||||
| 모바일 셀프 조회 PWA | 설계사 전용. 정산 명세서/출금 신청/공지 등 | 화면 우선순위 협의 |
|
||||
|
||||
### 운영 DB 마이그레이션 상태
|
||||
운영 DB `192.168.0.60:55432/trading_ai/ga` 현재 **V78 적용 완료** (2026-05-21).
|
||||
V74~V78 Flyway 자동 적용 확인. ga-api 8082 가동 중.
|
||||
운영 DB `192.168.0.60:55432/trading_ai/ga` 현재 **V85 적용 완료** (2026-05-24).
|
||||
V79~V85 Flyway 자동 적용 확인. ga-api 8082 가동 중.
|
||||
|
||||
단위/통합 테스트는 SqlSessionFactory 환경 설정 문제로 아직 미작성 상태입니다.
|
||||
|
||||
@@ -252,16 +347,21 @@ V74~V78 Flyway 자동 적용 확인. ga-api 8082 가동 중.
|
||||
- 스모크: 신규 4 + 회귀 4 = **GET 8/8 PASS**, 쓰기(regenerate/detect/draft) 4/4 PASS
|
||||
- 보정: YearEndStatementMapper.xml 의 `a.agent_code` 미존재 컬럼 참조 제거 (agent 테이블에 agent_code 없음)
|
||||
|
||||
## 5. 재개 절차 (다음 세션 — P6 라운드)
|
||||
## 5. 재개 절차 (다음 세션 — P6 실연동 라운드)
|
||||
|
||||
1. **Claude Code 시작 시 cwd 확인**: `C:\Users\kyu\Desktop\ga_pro` (현재 세션과 동일)
|
||||
2. **Agent Teams 활성화 확인**: `.claude/settings.json` 커밋되어 있음
|
||||
3. **HANDOFF.md 읽기**: 본 문서 + 최근 git log로 컨텍스트 확보
|
||||
4. **운영 DB 상태**: **V78 적용 완료**. ga-api 8082 가동 중 (필요 시 `python verify_v74.py` / `smoke_v78.py` 재실행)
|
||||
5. **권장 시작 지점**: P6 외부 연동 — 펌뱅킹 실연동 / SMS·카카오 발송 / 모바일 셀프 조회
|
||||
6. **사용자 결정 필요 항목**:
|
||||
4. **운영 DB 상태**: **V85 적용 완료**. ga-api 8082 가동 중 (필요 시 `python verify_v74.py` / `smoke_v78.py` 재실행)
|
||||
5. **권장 시작 지점 (외부 스펙 미정 시)**:
|
||||
- 모바일 셀프 조회 PWA 스캐폴드 (화면 우선순위 협의)
|
||||
- 펌뱅킹 SETTLED 동기화 폴러 (Mock 검증 → 실 SDK 통합 시 가치)
|
||||
- 알림 채널 SMS phone 매핑 보강 (현재 user.phone 미설정 시 SMS skip — phone 등록 화면)
|
||||
6. **사용자 결정 필요 항목 (P6 실연동 차단 사유)**:
|
||||
- KFTC 펌뱅킹 API 계약·인증 정보 (실 SDK 통합 차단)
|
||||
- NHN Toast / 카카오 비즈채널 계정 + 템플릿 코드 (실 메시지 통합 차단)
|
||||
- 모바일 PWA 화면 우선순위 (잔여 27 빈 화면 중 어떤 것부터)
|
||||
- P2-1 마감 도메인의 마감 후 수정 차단 AOP 구현 방식 (전역 AOP vs Service-level 가드)
|
||||
- P6 펌뱅킹/메시징 외부 연동처 실제 스펙 (현재 미정 → 착수 전 확인 필요)
|
||||
|
||||
## 6. PL 가이드 (다음 세션 유의사항)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user