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:
@@ -0,0 +1,41 @@
|
||||
import api, { unwrap } from './request';
|
||||
|
||||
export interface ExternalCallLogResp extends Record<string, unknown> {
|
||||
logId: number;
|
||||
callType: string; // BANK / MESSAGE
|
||||
adapterClass: string; // Mock / Kftc / Toast
|
||||
methodName: string; // requestTransfer / queryStatus / send
|
||||
targetRefType?: string;
|
||||
targetRefId?: number;
|
||||
requestSummary?: string;
|
||||
responseSummary?: string;
|
||||
resultCode?: string;
|
||||
resultMessage?: string;
|
||||
success: boolean;
|
||||
durationMs?: number;
|
||||
errorClass?: string;
|
||||
errorMessage?: string;
|
||||
calledAt: string;
|
||||
createdBy?: number;
|
||||
}
|
||||
|
||||
export interface ExternalCallLogSearchParam {
|
||||
callType?: string;
|
||||
methodName?: string;
|
||||
success?: boolean;
|
||||
targetRefType?: string;
|
||||
targetRefId?: number;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
pageNum?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export const externalCallLogApi = {
|
||||
list: (params?: ExternalCallLogSearchParam) =>
|
||||
unwrap<{ list: ExternalCallLogResp[]; total: number }>(
|
||||
api.get('/api/external-call-logs', { params })
|
||||
),
|
||||
detail: (id: number) =>
|
||||
unwrap<ExternalCallLogResp>(api.get(`/api/external-call-logs/${id}`)),
|
||||
};
|
||||
Reference in New Issue
Block a user