feat: P6 어댑터 PoC 보강 — Resp 노출 / phone 매핑 / 재시도 배치 / SDK 분기
1. WithdrawRequestResp / VO / Mapper.xml / 화면에 transfer_tx_id/transfer_status/transfer_at 노출 2. UserMapper.selectFirstActiveContactByRoleCode — step.roleCode → user.phone 1차 매핑 - ApprovalService.sendStepNotification 이 실제 결재자 user_id/phone 사용 (기존 0L 하드코딩 해소) - phone 미확보 시 SMS skip (DB 알림은 유지) 3. 펌뱅킹 재시도 — WithdrawBankRetryService + POST /api/internal/bank-retry - WithdrawRequestMapper.selectFailedTransfers 추가 - @EnableScheduling + cron 옵션(기본 비활성), app.bank-retry.limit 4. 어댑터 프로파일 분기 — @ConditionalOnProperty - app.adapter.bank: mock(기본) | kftc → KftcBankTransferAdapter 스켈레톤 - app.adapter.message: mock(기본) | toast → ToastMessageAdapter 스켈레톤 - 활성화 시 UnsupportedOperationException 명시 5. V83(menu_code 오기로 0건 적용) + V84(실제 WITHDRAW 메뉴에 EXECUTE 권한 보강)
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
package com.ga.external.bank;
|
||||
|
||||
import com.ga.common.adapter.bank.BankTransferAdapter;
|
||||
import com.ga.common.adapter.bank.BankTransferRequest;
|
||||
import com.ga.common.adapter.bank.BankTransferResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* KFTC(금융결제원) 오픈뱅킹 펌뱅킹 어댑터 — <b>스켈레톤</b>.
|
||||
* <p>
|
||||
* 활성 조건: <code>app.adapter.bank=kftc</code>. 실제 SDK / 클라이언트 의존성은 아직 미추가.
|
||||
* 외부 스펙(인증/엔드포인트/응답 코드)이 확정되면 본 클래스의 메서드를 구현한다.
|
||||
* 그 동안은 활성화 시 명시적 예외를 던져 잘못된 운영 적용을 빠르게 감지한다.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "app.adapter", name = "bank", havingValue = "kftc")
|
||||
public class KftcBankTransferAdapter implements BankTransferAdapter {
|
||||
|
||||
@Override
|
||||
public BankTransferResponse requestTransfer(BankTransferRequest request) {
|
||||
throw new UnsupportedOperationException(
|
||||
"KFTC 펌뱅킹 SDK 통합 미구현 — application.yml 의 app.adapter.bank=mock 으로 되돌리거나 본 어댑터를 완성하세요.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BankTransferResponse queryStatus(String txId) {
|
||||
throw new UnsupportedOperationException(
|
||||
"KFTC 펌뱅킹 SDK 통합 미구현 — txId=" + txId);
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -5,6 +5,7 @@ import com.ga.common.adapter.bank.BankTransferRequest;
|
||||
import com.ga.common.adapter.bank.BankTransferResponse;
|
||||
import com.ga.common.adapter.bank.BankTransferStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -13,11 +14,12 @@ import java.util.UUID;
|
||||
/**
|
||||
* 펌뱅킹 Mock 구현.
|
||||
* <p>
|
||||
* 실제 KFTC/은행 SDK 가 들어오기 전까지 사용. 결과는 항상 ACCEPTED 반환 + 로그.
|
||||
* 계좌번호는 뒷 4자리 외 마스킹해 로그에 남긴다.
|
||||
* 활성 조건: app.adapter.bank=mock (기본). 실제 SDK 통합 시 yml 값을 'kftc' 등으로 바꾸면 본 빈은 비활성.
|
||||
* 결과는 항상 ACCEPTED 반환. 계좌번호는 뒷 4자리 외 마스킹해 로그에 남긴다.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "app.adapter", name = "bank", havingValue = "mock", matchIfMissing = true)
|
||||
public class MockBankTransferAdapter implements BankTransferAdapter {
|
||||
|
||||
@Override
|
||||
|
||||
+4
-2
@@ -4,6 +4,7 @@ import com.ga.common.adapter.message.MessageAdapter;
|
||||
import com.ga.common.adapter.message.MessageRequest;
|
||||
import com.ga.common.adapter.message.MessageResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@@ -12,11 +13,12 @@ import java.util.UUID;
|
||||
/**
|
||||
* SMS / 카카오 알림톡 Mock 구현.
|
||||
* <p>
|
||||
* 실제 NHN Toast/알리고/카카오 비즈메시지 SDK 가 들어오기 전까지 사용. 항상 성공 응답.
|
||||
* phoneNumber 는 뒷 4자리 외 마스킹.
|
||||
* 활성 조건: app.adapter.message=mock (기본). 실제 SDK 통합 시 yml 값을 'toast' 등으로 바꾸면 본 빈은 비활성.
|
||||
* 항상 성공 응답. phoneNumber 는 뒷 4자리 외 마스킹.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "app.adapter", name = "message", havingValue = "mock", matchIfMissing = true)
|
||||
public class MockMessageAdapter implements MessageAdapter {
|
||||
|
||||
@Override
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.ga.external.message;
|
||||
|
||||
import com.ga.common.adapter.message.MessageAdapter;
|
||||
import com.ga.common.adapter.message.MessageRequest;
|
||||
import com.ga.common.adapter.message.MessageResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* NHN Toast SMS / 카카오 알림톡 어댑터 — <b>스켈레톤</b>.
|
||||
* <p>
|
||||
* 활성 조건: <code>app.adapter.message=toast</code>. 실제 SDK / API 키 등은 미주입 상태.
|
||||
* 외부 스펙(인증/엔드포인트/템플릿 코드)이 확정되면 본 클래스의 send 를 구현한다.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "app.adapter", name = "message", havingValue = "toast")
|
||||
public class ToastMessageAdapter implements MessageAdapter {
|
||||
|
||||
@Override
|
||||
public MessageResponse send(MessageRequest request) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Toast / 카카오 비즈메시지 SDK 통합 미구현 — application.yml 의 app.adapter.message=mock 으로 되돌리거나 본 어댑터를 완성하세요.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user