refactor: remove legacy eims tool path
Some checks failed
Deploy to OCIWP / deploy (push) Has been cancelled
Some checks failed
Deploy to OCIWP / deploy (push) Has been cancelled
This commit is contained in:
@@ -1,151 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.connector;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.lib.adapter.sender.EimsSender;
|
||||
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
|
||||
import io.github.resilience4j.ratelimiter.RequestNotPermitted;
|
||||
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import io.shinhanlife.dap.lib.adapter.util.LegacyDataTransformer;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.connector
|
||||
* @className LegacyEimsConnector
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LegacyEimsConnector {
|
||||
|
||||
// 4가지 방식의 Sender를 모두 주입받습니다. (변수명이 아주 중요합니다!)
|
||||
private final EimsSender httpEimsSender; // 1~20 (EIMS API)
|
||||
private final EimsSender tcpEimsSender; // 21~30 (EIMS Socket)
|
||||
private final EimsSender jspFormEimsSender; // 31~40 (JSP Form)
|
||||
private final EimsSender jspJsonEimsSender; // 41~50 (JSP JSON)
|
||||
|
||||
private final EimsSender mciEimsSender; // 실시간 연계 (기존 HTTP/TCP 대체, 동기식 API)
|
||||
private final EimsSender mciStringEimsSender; // 실시간 연계 (String 전문 버전)
|
||||
private final EimsSender eaiEimsSender; // 비동기/대용량 연계 (배치 통신 등)
|
||||
|
||||
private final ObjectMapper jsonMapper;
|
||||
|
||||
|
||||
// 방어막 적용: 예외가 발생하거나 차단기가 열리면 fallbackMethod를 즉시 실행합니다!
|
||||
// 서킷 브레이커와 Rate Limiter를 동시에 적용 (둘 중 하나라도 걸리면 fallbackForEims 실행)
|
||||
@RateLimiter(name = "eims", fallbackMethod = "fallbackForEims")
|
||||
@CircuitBreaker(name = "eims", fallbackMethod = "fallbackForEims")
|
||||
// 2번 업그레이드 적용: 파라미터 기반의 스마트 캐싱 (고객의 요청 데이터가 다르면 캐시도 다르게 적용)
|
||||
@Cacheable(value = "eimsData", key = "#routingType + '-' + #interfaceId + '-' + (#data != null ? #data.hashCode() : 0)")
|
||||
public String executeByTool(String routingType, String interfaceId, Map<String, Object> data, List<Map<String, Object>> spec) throws Exception {
|
||||
|
||||
// 1. 데이터 조립 (방어 로직 포함)
|
||||
String payload = buildPayload(data, spec);
|
||||
|
||||
log.info("\n [Adapter -> Legacy] EIMS 통신 요청 - RoutingType: {}, Interface: {}, Payload: {}", routingType, interfaceId, payload);
|
||||
|
||||
// 2. 4단계 라우팅 분기 처리 (Switch Expression 활용)
|
||||
String upperRoutingType = routingType != null ? routingType.toUpperCase() : "";
|
||||
|
||||
String legacyResponse = switch (upperRoutingType) {
|
||||
case "HTTP" -> {
|
||||
log.info("[라우팅] EIMS API (HTTP) 통신으로 전달");
|
||||
yield httpEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
case "TCP" -> {
|
||||
log.info("[라우팅] EIMS 소켓 (TCP) 통신으로 전달");
|
||||
yield tcpEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
case "JSP_FORM" -> {
|
||||
log.info("[라우팅] JSP Form 통신으로 전달");
|
||||
yield jspFormEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
case "JSP_JSON" -> {
|
||||
log.info("[라우팅] JSP JSON 통신으로 전달");
|
||||
yield jspJsonEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
|
||||
case "MCI" -> {
|
||||
if (isStringMci(spec)) {
|
||||
log.info("[라우팅] 스펙 자동 판별 (String 포맷 감지) -> MCI 연계 어댑터(String)를 통해 EIMS 전달");
|
||||
yield mciStringEimsSender.send(interfaceId, payload);
|
||||
} else {
|
||||
log.info("[라우팅] 실시간 AI 요청 -> MCI 연계 어댑터를 통해 EIMS 전달");
|
||||
yield mciEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
}
|
||||
case "EAI" -> {
|
||||
log.info("[라우팅] 비동기/대용량 요청 -> EAI 연계 어댑터를 통해 EIMS 전달");
|
||||
yield eaiEimsSender.send(interfaceId, payload);
|
||||
}
|
||||
default -> {
|
||||
log.error("[라우팅] 알 수 없는 라우팅 타입: {}", routingType);
|
||||
throw new IllegalArgumentException("지원하지 않는 라우팅 타입입니다: " + routingType);
|
||||
}
|
||||
};
|
||||
|
||||
log.info("\n [Legacy -> Adapter] EIMS 통신 응답 수신: {}", legacyResponse);
|
||||
return legacyResponse;
|
||||
}
|
||||
|
||||
|
||||
// 비상용 응답 메서드 (차단기가 열려있거나, 타임아웃/에러가 났을 때 실행됨)
|
||||
// 주의: 파라미터는 원본 메서드와 100% 똑같이 맞추고, 마지막에 Throwable을 받아야 합니다.
|
||||
public String fallbackForEims(String routingType, String interfaceId, Map<String, Object> data, List<Map<String, Object>> spec, Throwable t) {
|
||||
|
||||
// 1. Rate Limiter에 의해 차단된 경우 (트래픽 폭주)
|
||||
if (t instanceof RequestNotPermitted) {
|
||||
log.warn(" [Rate Limiter 발동] 트래픽 폭주로 요청 차단! interfaceId: {}", interfaceId);
|
||||
return String.format(
|
||||
"{\"status\":\"TOO_MANY_REQUESTS\", \"message\":\"순간적인 요청 폭주로 인해 일시적으로 제한되었습니다. 잠시 후 시도해 주세요.\", \"interfaceId\":\"%s\"}",
|
||||
interfaceId
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Circuit Breaker에 의해 차단된 경우 (레거시 시스템 장애/지연)
|
||||
log.error(" [서킷 브레이커 발동] 레거시 통신 차단! 원인: {}", t.getMessage());
|
||||
return String.format(
|
||||
"{\"status\":\"CIRCUIT_OPEN\", \"message\":\"신한라이프 내부 시스템 장애로 인해 일시적으로 차단되었습니다. 복구 후 재시도 부탁드립니다.\", \"interfaceId\":\"%s\"}",
|
||||
interfaceId
|
||||
);
|
||||
}
|
||||
|
||||
private String buildPayload(Map<String, Object> data, List<Map<String, Object>> spec) {
|
||||
// 3번 항목 적용: 원본 데이터를 스펙에 맞게 엄격히 정제(변환, 형변환, 잘라내기, 기본값 등)
|
||||
Map<String, Object> transformedData = LegacyDataTransformer.transform(data, spec);
|
||||
|
||||
if (transformedData == null || transformedData.isEmpty()) return "{}";
|
||||
|
||||
try {
|
||||
return jsonMapper.writeValueAsString(transformedData);
|
||||
} catch (Exception e) {
|
||||
log.error(" JSON 변환 에러: {}", e.getMessage());
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isStringMci(List<Map<String, Object>> spec) {
|
||||
if (spec == null || spec.isEmpty()) return false;
|
||||
// 스펙 내에 maxLength 등 고정길이 전문 관련 속성이 하나라도 존재하거나 명시적으로 STRING 힌트가 있으면 String 전문으로 간주
|
||||
return spec.stream().anyMatch(field ->
|
||||
field.containsKey("maxLength") ||
|
||||
field.containsKey("byteSize") ||
|
||||
"STRING".equalsIgnoreCase(String.valueOf(field.get("mciFormat")))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.support;
|
||||
|
||||
import io.shinhanlife.dap.lib.adapter.connector.LegacyEimsConnector;
|
||||
import io.shinhanlife.dap.lib.adapter.dto.ErrorDetail;
|
||||
import io.shinhanlife.dap.lib.adapter.dto.JsonRpcRequest;
|
||||
import io.shinhanlife.dap.lib.adapter.dto.JsonRpcResponse;
|
||||
import io.shinhanlife.dap.lib.adapter.dto.Params;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.support
|
||||
* @className ToolExecutionService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ToolExecutionService {
|
||||
|
||||
// 방어막(서킷/캐시)이 적용된 커넥터 주입
|
||||
private final LegacyEimsConnector legacyEimsConnector;
|
||||
|
||||
/**
|
||||
* AI Agent가 호출한 툴을 실제 레거시 커넥터로 전달합니다.
|
||||
*/
|
||||
public JsonRpcResponse executeTool(JsonRpcRequest request) {
|
||||
Params params = request.getParams();
|
||||
|
||||
// 1. 필수 파라미터 검증
|
||||
if (params == null || params.getName() == null) {
|
||||
return createErrorResponse(request.getId(), -32602, "Invalid params: 'name' is required");
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. Connector의 executeByTool 메서드 호출
|
||||
// [참고] connector에 선언된 파라미터 구조에 맞게 매핑합니다.
|
||||
String result = legacyEimsConnector.executeByTool(
|
||||
params.getRoutingType(),
|
||||
params.getInterfaceId(),
|
||||
params.getData(),
|
||||
params.getSpec()
|
||||
);
|
||||
|
||||
// 3. 성공 응답 생성 (result가 JSON 문자열일 경우, 실제 DTO로 변환하여 반환하면 더 좋습니다)
|
||||
return createSuccessResponse(request.getId(), result);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(" [ToolExecution] 커넥터 호출 실패: RoutingType={}, Error={}", params.getRoutingType(), e.getMessage());
|
||||
return createErrorResponse(request.getId(), -32000, "Connector error: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AI Agent를 위한 툴 목록 스키마 반환
|
||||
*/
|
||||
public JsonRpcResponse getToolList(String requestId) {
|
||||
// 기존에 정의한 Tool 스키마 리스트 반환 로직...
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
// ... (Tool 명세 내용)
|
||||
return createSuccessResponse(requestId, result);
|
||||
}
|
||||
|
||||
private JsonRpcResponse createSuccessResponse(String id, Object result) {
|
||||
JsonRpcResponse response = new JsonRpcResponse();
|
||||
response.setId(id);
|
||||
response.setResult(result);
|
||||
return response;
|
||||
}
|
||||
|
||||
private JsonRpcResponse createErrorResponse(String id, int code, String message) {
|
||||
JsonRpcResponse response = new JsonRpcResponse();
|
||||
response.setId(id);
|
||||
response.setError(new ErrorDetail(code, message));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -150,6 +150,9 @@ public class ToolScaffolder {
|
||||
String bizPackage = BASE_PACKAGE + ".biz." + group.toLowerCase();
|
||||
boolean isMci = "MCI".equalsIgnoreCase(routingType);
|
||||
boolean isHttp = "HTTP".equalsIgnoreCase(routingType);
|
||||
if (!isMci && !isHttp) {
|
||||
throw new IllegalArgumentException("Unsupported routing type: " + routingType + ". Only MCI and HTTP are supported.");
|
||||
}
|
||||
String mciGroupPath = "infra/itrf/mci/" + group.toLowerCase();
|
||||
String clientPrefixCap = "";
|
||||
Path mciClientDir = null;
|
||||
@@ -425,7 +428,6 @@ public class ToolScaffolder {
|
||||
import %s.dto.%sRequest;
|
||||
import %s.dto.%sResponse;
|
||||
import %s.usecase.%sUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import %s.converter.%sConverter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -448,14 +450,14 @@ public class ToolScaffolder {
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class %sUseCaseImpl extends AbstractMcpToolUseCase implements %sUseCase {
|
||||
public class %sUseCaseImpl implements %sUseCase {
|
||||
|
||||
private final %sConverter converter;
|
||||
|
||||
@Override
|
||||
public %sResponse execute(%sRequest req) {
|
||||
// %sLegacyRequest legacyRequest = converter.toLegacyRequest(req);
|
||||
Object legacyResponse = executeLegacy("%s", "%s", req); // Or pass legacyRequest
|
||||
Object legacyResponse = null;
|
||||
if (legacyResponse instanceof %sResponse response) {
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.usecase;
|
||||
|
||||
import io.shinhanlife.dap.lib.adapter.connector.LegacyEimsConnector;
|
||||
import io.shinhanlife.dap.lib.adapter.util.PiiMaskingUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className AbstractMcpToolUseCase
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractMcpToolUseCase {
|
||||
|
||||
@Autowired
|
||||
protected LegacyEimsConnector legacyEimsConnector;
|
||||
|
||||
@Autowired
|
||||
protected ObjectMapper objectMapper;
|
||||
|
||||
protected Map<String, Object> executeLegacy(String routingType, String interfaceId, Object inputData) {
|
||||
return executeLegacy(routingType, interfaceId, inputData, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 레거시 시스템을 호출하고 공통 처리(PII 마스킹 등)를 수행합니다. (스펙 지정 가능)
|
||||
*/
|
||||
protected Map<String, Object> executeLegacy(String routingType, String interfaceId, Object inputData, List<Map<String, Object>> spec) {
|
||||
Map<String, Object> inputMap;
|
||||
if (inputData == null) {
|
||||
inputMap = new HashMap<>();
|
||||
} else if (inputData instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) inputData;
|
||||
inputMap = map;
|
||||
} else {
|
||||
inputMap = objectMapper.convertValue(inputData, new TypeReference<Map<String, Object>>() {});
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("\n=======================================================");
|
||||
log.info(" [Tool -> Legacy] 레거시 시스템 통신 시작");
|
||||
log.info(" - Routing Type: {}", routingType);
|
||||
log.info(" - Interface ID: {}", interfaceId);
|
||||
log.info(" - 호출 파라미터 (Request): \n{}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(inputMap));
|
||||
log.info("=======================================================\n");
|
||||
|
||||
// 1. Adapter 공통 모듈 직접 호출
|
||||
String executionResult = legacyEimsConnector.executeByTool(routingType, interfaceId, inputMap, spec);
|
||||
|
||||
log.info("\n=======================================================");
|
||||
log.info(" [Legacy -> Tool] 레거시 시스템 통신 완료");
|
||||
log.info(" - 응답 파라미터 (Response, 마스킹 전): \n{}", executionResult);
|
||||
log.info("=======================================================\n");
|
||||
|
||||
// 2. PII 마스킹 처리
|
||||
String maskedResult = PiiMaskingUtils.mask(executionResult);
|
||||
|
||||
if (executionResult != null && (executionResult.contains("\"status\":\"CIRCUIT_OPEN\"") || executionResult.contains("\"status\":\"TOO_MANY_REQUESTS\""))) {
|
||||
try {
|
||||
return objectMapper.readValue(executionResult, new TypeReference<Map<String, Object>>() {});
|
||||
} catch (Exception e) {
|
||||
log.error("Fallback JSON 파싱 에러: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("status", "SUCCESS");
|
||||
result.put("legacy_response", maskedResult);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
Map<String, Object> error = new HashMap<>();
|
||||
error.put("status", "ERROR");
|
||||
error.put("message", e.getMessage());
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,24 +84,6 @@ class McpToolNameValidatorTest {
|
||||
assertDoesNotThrow(() -> McpToolNameValidator.assertUnique(findProjectRoot()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void usesDomainSpecificNamesForCustomerBillingAndBondTools() throws IOException {
|
||||
Path root = findProjectRoot();
|
||||
|
||||
assertToolName(root, "dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/CustomerInfoUseCase.java",
|
||||
"cmm_customer_detail", "detail");
|
||||
assertToolName(root, "dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/BillingProcessUseCase.java",
|
||||
"cmm_billing_process", "process");
|
||||
assertToolName(root, "dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/BondIssueUseCase.java",
|
||||
"cmm_bond_issue", "issue");
|
||||
}
|
||||
|
||||
private void assertToolName(Path root, String relativePath, String expectedName, String legacyName) throws IOException {
|
||||
String source = Files.readString(root.resolve(relativePath));
|
||||
assertTrue(source.contains("name = \"" + expectedName + "\""));
|
||||
assertFalse(source.contains("name = \"" + legacyName + "\""));
|
||||
}
|
||||
|
||||
private void writeToolSource(String moduleName, String fileName, String className, String toolName) throws IOException {
|
||||
Path source = temporaryRoot.resolve(moduleName).resolve("src/main/java/example").resolve(fileName);
|
||||
Files.createDirectories(source.getParent());
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BalanceRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class BalanceRequest {
|
||||
@McpToolParam(description = "고객의 계좌번호 (- 제외) ", required = true)
|
||||
@Schema(pattern = "\\S", example = "1234567890")
|
||||
private String accountNumber;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BalanceResponse
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class BalanceResponse {
|
||||
private String status;
|
||||
private String message;
|
||||
private String accountNumber;
|
||||
private long balance;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BillingProcessRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BillingProcessRequest {
|
||||
|
||||
@McpToolParam(description = "처리할 청구 접수 번호", required = true)
|
||||
@Schema(pattern = "\\S", example = "BILL20260805")
|
||||
private String billingId;
|
||||
|
||||
|
||||
@McpToolParam(description = "승인 처리 구분 (예: APPROVE, REJECT)")
|
||||
@Schema(required = true, allowableValues = {"APPROVE", "REJECT"}, example = "APPROVE")
|
||||
private String approvalStatus;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BillingStatusRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BillingStatusRequest {
|
||||
|
||||
@McpToolParam(description = "조회할 청구 접수 번호", required = true)
|
||||
@Schema(example = "BILL20260805")
|
||||
private String billingId;
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BondCheckRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BondCheckRequest {
|
||||
|
||||
@McpToolParam(description = "확인하고자 하는 디지털 증권 발행 금액", required = true)
|
||||
@Schema(pattern = "^[0-9]+$", example = "1000000")
|
||||
private String amount;
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className BondIssueRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BondIssueRequest {
|
||||
|
||||
@McpToolParam(description = "발행할 증권 금액 (숫자 문자열)", required = true)
|
||||
@Schema(pattern = "^[0-9]+$", example = "1000000")
|
||||
private String amount;
|
||||
|
||||
|
||||
@McpToolParam(description = "발행 대상 계좌 번호", required = true)
|
||||
@Schema(pattern = "\\S", example = "1234567890")
|
||||
private String targetAccount;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className ContractDetailRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ContractDetailRequest {
|
||||
|
||||
@McpToolParam(description = "고객명", required = true)
|
||||
@Schema(example = "홍길동")
|
||||
private String customerName;
|
||||
|
||||
|
||||
@McpToolParam(description = "조회할 계약 번호", required = true)
|
||||
@Schema(example = "1234567890")
|
||||
private String contractId;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className ContractStatusRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ContractStatusRequest {
|
||||
|
||||
@McpToolParam(description = "고객명", required = true)
|
||||
@Schema(example = "홍길동")
|
||||
private String customerName;
|
||||
|
||||
|
||||
@McpToolParam(description = "조회할 계약 번호")
|
||||
private String contractId;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className CustomerDetailRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CustomerDetailRequest {
|
||||
|
||||
@McpToolParam(description = "고객명", required = true)
|
||||
@Schema(example = "홍길동")
|
||||
private String customerName;
|
||||
|
||||
|
||||
@McpToolParam(description = "고객 식별 번호 (CID)")
|
||||
private String customerId;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className CustomerGradeRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CustomerGradeRequest {
|
||||
|
||||
@McpToolParam(description = "고객 이름 (예: 김신한)", required = true)
|
||||
@Schema(example = "홍길동")
|
||||
private String customerName;
|
||||
|
||||
|
||||
@McpToolParam(description = "고객 식별 번호 (CID)")
|
||||
private String customerId;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className LeaveCountRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LeaveCountRequest {
|
||||
|
||||
@McpToolParam(description = "연차 내역을 조회할 사원 번호", required = true)
|
||||
@Schema(example = "EMP12345")
|
||||
private String employeeId;
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className VacationRegisterRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class VacationRegisterRequest {
|
||||
|
||||
@McpToolParam(description = "연차를 등록할 사원 번호", required = true)
|
||||
@Schema(pattern = "\\S", example = "EMP12345")
|
||||
private String employeeId;
|
||||
|
||||
|
||||
@McpToolParam(description = "휴가 일자 (YYYY-MM-DD 형식)", required = true)
|
||||
@Schema(pattern = "^\\d{4}-\\d{2}-\\d{2}$", example = "2026-08-05")
|
||||
private String date;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface BalanceUseCase {
|
||||
@McpTool(name = "cmm_balance_inquiry", title = "잔고 조회 툴", description = "고객의 계좌 잔액을 조회합니다.")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "ACC_001")
|
||||
Object execute(BalanceRequest req);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface BillingProcessUseCase {
|
||||
Object getStatus(BillingStatusRequest req);
|
||||
|
||||
@McpTool(name = "cmm_billing_process", title = "청구 프로세스 툴", description = "청구 처리")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "BILL_002")
|
||||
Object processBilling(BillingProcessRequest data);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface BondIssueUseCase {
|
||||
Object check(BondCheckRequest req);
|
||||
|
||||
@McpTool(name = "cmm_bond_issue", title = "채권 발행 툴", description = "증권 발행 테스트1")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "BOND_002")
|
||||
Object issue(BondIssueRequest data);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface CommonUtilityUseCase {
|
||||
Object registerVacation(VacationRegisterRequest req);
|
||||
|
||||
@McpTool(name = "cmm_leave_count", title = "공통 유틸리티 툴", description = "연차 갯수 조회")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "HR_VAC_02")
|
||||
Object getLeaveCount(LeaveCountRequest data);
|
||||
|
||||
@McpTool(name = "cmm_secret_execute", title = "공통 유틸리티 툴", description = "비공개 툴 테스트")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "SECRET_001")
|
||||
Object secretTool(LeaveCountRequest data);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface ContractInquiryUseCase {
|
||||
Object getStatus(ContractStatusRequest req);
|
||||
|
||||
@McpTool(name = "cmm_contract_detail", title = "계약 상세조회 툴", description = "계약상세 조회")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "CNTR_002")
|
||||
Object getDetail(ContractDetailRequest data);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase;
|
||||
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
public interface CustomerInfoUseCase {
|
||||
Object getGrade(CustomerGradeRequest req);
|
||||
|
||||
@McpTool(name = "cmm_customer_detail", title = "고객 상세조회 툴", description = "고객상세 정보 조회")
|
||||
@ToolHint(register = false, categoryKey = "cmm", mappingId = "CRM_002")
|
||||
Object getDetail(CustomerDetailRequest data);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className BalanceService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BalanceUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BalanceRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BalanceUseCaseImpl extends AbstractMcpToolUseCase implements BalanceUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object execute(BalanceRequest req) {
|
||||
log.info("[Balance] 계좌 잔액 조회 요청 수신. 계좌번호: {}", req.getAccountNumber());
|
||||
|
||||
// 레거시 연동
|
||||
Map<String, Object> result = executeLegacy("MCI", "ACC_001", req);
|
||||
|
||||
// 가짜 데이터 응답 매핑 (AI 에이전트가 그럴듯하게 보여주기 위함)
|
||||
if ("SUCCESS".equals(result.get("status"))) {
|
||||
result.put("accountNumber", req.getAccountNumber());
|
||||
result.put("balance", 1520300); // 1,520,300원 (가상의 잔액)
|
||||
result.put("currency", "KRW");
|
||||
result.put("message", "잔액 조회가 완료되었습니다.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BillingProcessUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingProcessRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BillingStatusRequest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className BillingProcessService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@lombok.extern.slf4j.Slf4j
|
||||
@Service
|
||||
public class BillingProcessUseCaseImpl extends AbstractMcpToolUseCase implements BillingProcessUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object getStatus(BillingStatusRequest data) {
|
||||
return executeBillingLogic("BILL_001", data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object processBilling(BillingProcessRequest data) {
|
||||
return executeBillingLogic("BILL_002", data);
|
||||
}
|
||||
|
||||
private Object executeBillingLogic(String mappingId, Object data) {
|
||||
log.info(" [Billing] 청구 처리 전용 커스텀 전/후처리 로직 수행 시작");
|
||||
|
||||
Map<String, Object> payload;
|
||||
if (data == null) {
|
||||
payload = new HashMap<>();
|
||||
} else {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
payload = mapper.convertValue(data, new TypeReference<Map<String, Object>>() {});
|
||||
}
|
||||
|
||||
// 커스텀 전처리
|
||||
payload.put("custom_injected_data", "Billing System Check OK");
|
||||
log.info(" [Billing] 커스텀 파라미터 주입 완료");
|
||||
|
||||
// 부모 클래스의 레거시 공통 연동 메서드 호출 (PII 마스킹 포함)
|
||||
Map<String, Object> result = executeLegacy("MCI", mappingId, payload);
|
||||
|
||||
// 커스텀 후처리
|
||||
if ("SUCCESS".equals(result.get("status"))) {
|
||||
result.put("billing_custom_insight", "청구 특화 후처리 로직이 적용되었습니다.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.BondIssueUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondCheckRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.BondIssueRequest;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className BondIssueService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Service
|
||||
public class BondIssueUseCaseImpl extends AbstractMcpToolUseCase implements BondIssueUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object check(BondCheckRequest data) {
|
||||
return executeLegacy("EAI", "BOND_001", data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object issue(BondIssueRequest data) {
|
||||
return executeLegacy("EAI", "BOND_002", data);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CommonUtilityUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.LeaveCountRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.VacationRegisterRequest;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className CommonUtilityService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Service
|
||||
public class CommonUtilityUseCaseImpl extends AbstractMcpToolUseCase implements CommonUtilityUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object registerVacation(VacationRegisterRequest data) {
|
||||
return executeLegacy("HTTP", "HR_VAC_01", data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getLeaveCount(LeaveCountRequest data) {
|
||||
return executeLegacy("HTTP", "HR_VAC_02", data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object secretTool(LeaveCountRequest data) {
|
||||
return executeLegacy("HTTP", "SECRET_001", data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.ContractInquiryUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractDetailRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.ContractStatusRequest;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className ContractInquiryService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Service
|
||||
public class ContractInquiryUseCaseImpl extends AbstractMcpToolUseCase implements ContractInquiryUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object getStatus(ContractStatusRequest data) {
|
||||
return executeLegacy("HTTP", "CNTR_001", data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDetail(ContractDetailRequest data) {
|
||||
return executeLegacy("HTTP", "CNTR_002", data);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.CustomerInfoUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerDetailRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.CustomerGradeRequest;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.service
|
||||
* @className CustomerInfoService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Service
|
||||
public class CustomerInfoUseCaseImpl extends AbstractMcpToolUseCase implements CustomerInfoUseCase {
|
||||
|
||||
|
||||
@Override
|
||||
public Object getGrade(CustomerGradeRequest req) {
|
||||
return executeLegacy("TCP", "CRM_001", req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDetail(CustomerDetailRequest data) {
|
||||
return executeLegacy("TCP", "CRM_002", data);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.usecase.TemplateUtilityUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.biz.cmm.dto.TemplateDownloadRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -27,7 +26,7 @@ import java.util.Map;
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class TemplateUtilityUseCaseImpl extends AbstractMcpToolUseCase implements TemplateUtilityUseCase {
|
||||
public class TemplateUtilityUseCaseImpl implements TemplateUtilityUseCase {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getTemplateFileUrl(TemplateDownloadRequest data) {
|
||||
@@ -55,4 +54,4 @@ public class TemplateUtilityUseCaseImpl extends AbstractMcpToolUseCase implement
|
||||
throw new RuntimeException("템플릿 URL 생성 실패", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.DailyQuoteToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -26,7 +25,7 @@ import java.util.Random;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DailyQuoteToolUseCaseImpl extends AbstractMcpToolUseCase implements DailyQuoteToolUseCase {
|
||||
public class DailyQuoteToolUseCaseImpl implements DailyQuoteToolUseCase {
|
||||
|
||||
private final List<DailyQuoteResponse> quotes = List.of(
|
||||
new DailyQuoteResponse("성공은 매일 반복한 작은 노력들의 합이다.", "로버트 콜리어"),
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.ExchangeRateToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClient;
|
||||
@@ -24,7 +23,7 @@ import org.springframework.web.client.RestClient;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ExchangeRateToolUseCaseImpl extends AbstractMcpToolUseCase implements ExchangeRateToolUseCase {
|
||||
public class ExchangeRateToolUseCaseImpl implements ExchangeRateToolUseCase {
|
||||
|
||||
private final RestClient restClient;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.TeamMemberUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -25,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TeamMemberUseCaseImpl extends AbstractMcpToolUseCase implements TeamMemberUseCase {
|
||||
public class TeamMemberUseCaseImpl implements TeamMemberUseCase {
|
||||
|
||||
@Override
|
||||
public Object execute(TeamMemberRequest req) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.shinhanlife.dap.mcc.biz.smp.usecase.impl;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.WeatherToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.WeatherResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -29,7 +28,7 @@ import java.time.format.DateTimeFormatter;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class WeatherToolUseCaseImpl extends AbstractMcpToolUseCase implements WeatherToolUseCase {
|
||||
public class WeatherToolUseCaseImpl implements WeatherToolUseCase {
|
||||
|
||||
private final RestClient restClient;
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.sms.converter;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.sms.converter
|
||||
* @className SmsLegacyConverter
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import io.shinhanlife.dap.mcc.biz.sms.dto.SmsSendRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.sms.legacy.SmsLegacyRequest;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface SmsLegacyConverter {
|
||||
|
||||
@Mapping(source = "phoneNumber", target = "phone")
|
||||
@Mapping(source = "message", target = "content")
|
||||
SmsLegacyRequest toLegacyRequest(SmsSendRequest req);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.sms.dto;
|
||||
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.dto
|
||||
* @className SmsSendRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SmsSendRequest {
|
||||
|
||||
@McpToolParam(description = "수신자 전화번호", required = true)
|
||||
@Schema(pattern = "^01[0-9]-?\\d{3,4}-?\\d{4}$", example = "01012345678")
|
||||
private String phoneNumber;
|
||||
|
||||
|
||||
@McpToolParam(description = "전송할 메시지 내용", required = true)
|
||||
@Schema(pattern = "\\S", example = "테스트 메시지입니다.")
|
||||
private String message;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.sms.legacy;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.sms.dto
|
||||
* @className SmsLegacyRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class SmsLegacyRequest {
|
||||
/**
|
||||
* EAI 시스템이 요구하는 수신자 번호 파라미터명
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* EAI 시스템이 요구하는 메시지 내용 파라미터명
|
||||
*/
|
||||
private String content;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.sms.usecase;
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dap.lib.annotation.ToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.sms.dto.*;
|
||||
|
||||
public interface SmsToolUseCase {
|
||||
@McpTool(name = "sms_msg_send", title = "SMS 발송 툴", description = "SMS 발송 기능을 제공합니다.")
|
||||
@ToolHint(register = false, categoryKey = "sms", mappingId = "SMS_SEND")
|
||||
Object sendSms(SmsSendRequest req);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.sms.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.sms.usecase.SmsToolUseCase;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.springframework.stereotype.Service;
|
||||
import io.shinhanlife.dap.mcc.biz.sms.converter.SmsLegacyConverter;
|
||||
import io.shinhanlife.dap.mcc.biz.sms.dto.SmsSendRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.sms.legacy.SmsLegacyRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.sms
|
||||
* @className SmsToolService
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class SmsToolUseCaseImpl extends AbstractMcpToolUseCase implements SmsToolUseCase {
|
||||
|
||||
private final SmsLegacyConverter converter;
|
||||
|
||||
|
||||
@Override
|
||||
public Object sendSms(SmsSendRequest req) {
|
||||
log.info("[SMS] SMS 발송 요청 수신. 수신자: {}", req.getPhoneNumber());
|
||||
|
||||
// MapStruct를 이용한 자동 매핑 (AI DTO -> MCI DTO)
|
||||
SmsLegacyRequest legacyRequest = converter.toLegacyRequest(req);
|
||||
|
||||
// 레거시 시스템 연동 (EAI) - DTO 객체를 그대로 넘김
|
||||
Map<String, Object> result = executeLegacy("EAI", "SMS_SEND_001", legacyRequest);
|
||||
|
||||
// 결과 가공
|
||||
if ("SUCCESS".equals(result.get("status"))) {
|
||||
result.put("message", "SMS가 성공적으로 발송되었습니다.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.shinhanlife.dap.mcc.biz.smp.usecase;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@@ -9,7 +8,6 @@ import io.shinhanlife.dap.mcc.infra.itrf.http.sample.SampleClient;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.EmployeeSearchRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.dto.EmployeeSearchResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.smp.usecase.impl.EmployeeSearchUseCaseImpl;
|
||||
import io.shinhanlife.dap.mcc.usecase.AbstractMcpToolUseCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class EmployeeSearchUseCaseTest {
|
||||
@@ -20,15 +18,10 @@ class EmployeeSearchUseCaseTest {
|
||||
assertNotNull(new EmployeeSearchResponse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotDependOnAbstractMcpToolUseCase() {
|
||||
assertFalse(AbstractMcpToolUseCase.class.isAssignableFrom(EmployeeSearchUseCaseImpl.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void delegatesHttpCallThroughApiSpecificClient() {
|
||||
assertNotNull(EmployeeSearchUseCaseImpl.class.getDeclaredFields());
|
||||
assertTrue(java.util.Arrays.stream(EmployeeSearchUseCaseImpl.class.getDeclaredFields())
|
||||
.anyMatch(field -> field.getType().equals(SampleClient.class)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user