0e8c563a9a
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 권한 보강)
48 lines
1.8 KiB
Java
48 lines
1.8 KiB
Java
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;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* SMS / 카카오 알림톡 Mock 구현.
|
|
* <p>
|
|
* 활성 조건: 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
|
|
public MessageResponse send(MessageRequest request) {
|
|
String masked = maskPhone(request.getPhoneNumber());
|
|
String msgId = "MOCK-MSG-" + UUID.randomUUID();
|
|
log.info("[MOCK MSG] send channel={} to={} title={} refType={} refId={} msgId={}",
|
|
request.getChannel(), masked, request.getTitle(),
|
|
request.getRefType(), request.getRefId(), msgId);
|
|
|
|
return MessageResponse.builder()
|
|
.messageId(msgId)
|
|
.sent(true)
|
|
.resultCode("0000")
|
|
.resultMessage("MOCK sent")
|
|
.sentAt(LocalDateTime.now())
|
|
.build();
|
|
}
|
|
|
|
private String maskPhone(String phone) {
|
|
if (phone == null) return null;
|
|
String digits = phone.replaceAll("[^0-9]", "");
|
|
if (digits.length() <= 4) return "****";
|
|
return "***-****-" + digits.substring(digits.length() - 4);
|
|
}
|
|
}
|