forked from kimhyungsik/ax_hub_mcp_tool
feat: update MCP contracts and integrations
All checks were successful
Deploy Tools / deploy (push) Successful in 1m34s
All checks were successful
Deploy Tools / deploy (push) Successful in 1m34s
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.converter;
|
||||
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryRequest;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryResponse;
|
||||
import io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io. DATNCSO00001_I;
|
||||
import io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io. DATNCSO00001_O;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface PersonalCustomerDetailInquiryConverter {
|
||||
// Field names differ? Add mappings like this before the method.
|
||||
@Mapping(source = "customerId", target = "customerId")
|
||||
DATNCSO00001_I toLegacyRequest(PersonalCustomerDetailInquiryRequest request);
|
||||
|
||||
|
||||
PersonalCustomerDetailInquiryResponse toResponse( DATNCSO00001_O mciRes);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
|
||||
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class PersonalCustomerDetailInquiryRequest {
|
||||
@Schema(description = "조회할 고객의 고유 ID (형식: ^[A-Za-z0-9-]{1,20}$) (예시: 12345, CUST-00123)", example = "12345", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Pattern(regexp = "^[A-Za-z0-9-]{1,20}$")
|
||||
private String customerId;
|
||||
|
||||
@Schema(description = "고객 이름 (선택적 확인용) (형식: ^[가-힣a-zA-Z\s]{2,20}$) (예시: 김철수, Lee Chul-soo)", example = "김철수")
|
||||
@Pattern(regexp = "^[가-힣a-zA-Z\s]{2,20}$")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "고객 전화번호 (선택적 확인용) (형식: $) (예시: 010-1234-5678, +821012345678)", example = "010-1234-5678")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "고객 이메일 주소 (선택적 확인용) (형식: $) (예시: customer@example.com, user@test.co.kr)", example = "customer@example.com")
|
||||
private String email;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class PersonalCustomerDetailInquiryResponse {
|
||||
private String resultCode;
|
||||
|
||||
private String resultMessage;
|
||||
@Schema(description = "조회된 고객의 고유 ID (예시: 12345, CUST-00123)", example = "12345", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String customerId;
|
||||
|
||||
@Schema(description = "고객의 전체 이름 (예시: 김철수, Lee Chul-soo)", example = "김철수", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "고객의 전화번호 (예시: 010-1234-5678)", example = "010-1234-5678", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "고객의 이메일 주소 (예시: customer@example.com)", example = "customer@example.com", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String email;
|
||||
|
||||
@Schema(description = "고객의 주소 정보 (예시: 서울시 강남구 테헤란로 123)", example = "서울시 강남구 테헤란로 123")
|
||||
private String address;
|
||||
|
||||
@Schema(description = "고객의 생년월일 (예시: 1990-01-15)", example = "1990-01-15")
|
||||
private String birthDate;
|
||||
|
||||
@Schema(description = "고객의 멤버십 등급 (예시: GOLD, SILVER, BRONZE)", example = "GOLD")
|
||||
private String membershipLevel;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.usecase;
|
||||
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import io.shinhanlife.dat.lib.annotation.GrowToolHint;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryRequest;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryResponse;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dat.mcc.biz.pro.usecase
|
||||
* @className PersonalCustomerDetailInquiryUseCase
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author jade
|
||||
* @create 2026.08.25
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.08.25 jade 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public interface PersonalCustomerDetailInquiryUseCase {
|
||||
|
||||
@McpTool(name = "pro_personal_inquiry", title = "개인고객 상세 정보 조회", description = "개인고객의 상세 정보를 조회하는 도구로, 고객 ID 또는 기본 정보를 통해 이름, 연락처, 주소, 생년월일, 멤버십 등급 등 개인 고객 정보를 안전하게 조회할 수 있습니다.")
|
||||
@GrowToolHint(
|
||||
requiresApproval = false,
|
||||
categoryKey = "pro",
|
||||
mappingId = " DATNCSO00001",
|
||||
functionDescription = "고객 ID 또는 기본 정보를 기반으로 개인 고객의 상세 정보를 조회하고 반환하는 핵심 비즈니스 함수입니다.",
|
||||
whenToUse = "개인 고객의 상세 정보가 필요한 경우, 예를 들어 고객 ID, 이름, 전화번호, 이메일 등을 입력하여 고객 정보를 조회하고자 할 때 이 도구를 선택해야 합니다.",
|
||||
whenNotToUse = "개인 고객이 아닌 법인 고객 정보 조회, 익명 또는 비개인 정보 요청, 또는 개인 정보 보호 정책상 정보 조회가 제한된 경우 이 도구를 선택하지 않아야 합니다.",
|
||||
ioLimits = "입력 필드는 고객 ID(필수) 및 선택적 이름, 전화번호, 이메일을 허용하며, 최대 10개의 필드를 포함할 수 있습니다. 출력 필드는 결과 코드, 고객 ID, 이름, 전화번호, 이메일, 주소, 생년월일, 멤버십 등급 등을 포함하며, 최대 10개의 필드를 반환할 수 있습니다.",
|
||||
displayDescription = "개인 고객의 상세 정보를 조회하는 포털용 간략한 설명으로, 이름, 연락처, 주소, 생년월일, 멤버십 등급 등을 확인할 수 있습니다.",
|
||||
exampleQueries = {"고객 ID 12345로 개인 고객 정보를 조회해줘", "김철수 고객의 상세 정보를 알려줘", "010-1234-5678로 등록된 개인 고객 정보를 조회해줘", "lee@example.com 이메일로 가입된 개인 고객 정보를 조회해줘"},
|
||||
destructive = false,
|
||||
idempotent = true,
|
||||
tags = {"고객관리", "조회"},
|
||||
ownerOrg = "MCP_TOOL"
|
||||
)
|
||||
PersonalCustomerDetailInquiryResponse execute(PersonalCustomerDetailInquiryRequest req);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryRequest;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryResponse;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.usecase.PersonalCustomerDetailInquiryUseCase;
|
||||
import io.shinhanlife.dat.lib.integration.mci.component.AxhubMciComponent;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
import org.springframework.stereotype.Service;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.converter.PersonalCustomerDetailInquiryConverter;
|
||||
import io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io. DATNCSO00001_I;
|
||||
import io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io. DATNCSO00001_O;
|
||||
import io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.MciNcscClient;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dat.mcc.biz.pro.usecase.impl
|
||||
* @className PersonalCustomerDetailInquiryUseCaseImpl
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author jade
|
||||
* @create 2026.08.25
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.08.25 jade 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PersonalCustomerDetailInquiryUseCaseImpl implements PersonalCustomerDetailInquiryUseCase {
|
||||
|
||||
private final MciNcscClient mci;
|
||||
private final PersonalCustomerDetailInquiryConverter converter;
|
||||
|
||||
@Override
|
||||
public PersonalCustomerDetailInquiryResponse execute(PersonalCustomerDetailInquiryRequest req) {
|
||||
log.info("[MCI Tool] {} 요청 수신.", "pro_personal_inquiry");
|
||||
try {
|
||||
// MapStruct를 이용한 자동 매핑 (AI DTO -> MCI DTO)
|
||||
DATNCSO00001_I mciReq = converter.toLegacyRequest(req);
|
||||
|
||||
Transfer< DATNCSO00001_O> resTransfer = mci.callTo(
|
||||
" DATNCSO00001",
|
||||
null,
|
||||
mciReq,
|
||||
DATNCSO00001_O.class
|
||||
);
|
||||
PersonalCustomerDetailInquiryResponse response = new PersonalCustomerDetailInquiryResponse();
|
||||
if (resTransfer.getBody() != null) {
|
||||
response = converter.toResponse(resTransfer.getBody());
|
||||
}
|
||||
response.setResultCode("SUCCESS");
|
||||
response.setResultMessage(resTransfer.getBody() != null
|
||||
? "MCI call completed."
|
||||
: "MCI call completed without a response body.");
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("[MCI Tool] 연동 중 오류 발생: {}", e.getMessage(), e);
|
||||
PersonalCustomerDetailInquiryResponse response = new PersonalCustomerDetailInquiryResponse();
|
||||
response.setResultCode("ERROR");
|
||||
response.setResultMessage(e.getMessage() != null ? e.getMessage() : "Unknown error");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import io.shinhanlife.dat.lib.integration.mci.component.AxhubMciComponent;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c
|
||||
* @className MciNcscClient
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author jade
|
||||
* @create 2026.08.25
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.08.25 jade 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MciNcscClient {
|
||||
private final AxhubMciComponent mci;
|
||||
|
||||
public <O> Transfer<O> callTo(String interfaceId, String dummy, Object mciReq, Class<O> resType) throws Exception {
|
||||
return mci.callTo(interfaceId, dummy, mciReq, resType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
|
||||
|
||||
@Data
|
||||
public class DATNCSO00001_I {
|
||||
@Schema(description = "조회할 고객의 고유 ID (형식: ^[A-Za-z0-9-]{1,20}$) (예시: 12345, CUST-00123)", example = "12345", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Pattern(regexp = "^[A-Za-z0-9-]{1,20}$")
|
||||
private String customerId;
|
||||
|
||||
@Schema(description = "고객 이름 (선택적 확인용) (형식: ^[가-힣a-zA-Z\s]{2,20}$) (예시: 김철수, Lee Chul-soo)", example = "김철수")
|
||||
@Pattern(regexp = "^[가-힣a-zA-Z\s]{2,20}$")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "고객 전화번호 (선택적 확인용) (형식: {4}$) (예시: 010-1234-5678, +821012345678)", example = "010-1234-5678")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "고객 이메일 주소 (선택적 확인용) (형식: $) (예시: customer@example.com, user@test.co.kr)", example = "customer@example.com")
|
||||
private String email;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.shinhanlife.dat.mcc.infra.itrf.mci.ncs.c.io;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class DATNCSO00001_O {
|
||||
@Schema(description = "조회 결과 상태 코드 (예시: SUCCESS, ERROR_001)", example = "SUCCESS", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String resultCode;
|
||||
|
||||
@Schema(description = "조회된 고객의 고유 ID (예시: 12345, CUST-00123)", example = "12345", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String customerId;
|
||||
|
||||
@Schema(description = "고객의 전체 이름 (예시: 김철수, Lee Chul-soo)", example = "김철수", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String name;
|
||||
|
||||
@Schema(description = "고객의 전화번호 (예시: 010-1234-5678)", example = "010-1234-5678", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "고객의 이메일 주소 (예시: customer@example.com)", example = "customer@example.com", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String email;
|
||||
|
||||
@Schema(description = "고객의 주소 정보 (예시: 서울시 강남구 테헤란로 123)", example = "서울시 강남구 테헤란로 123")
|
||||
private String address;
|
||||
|
||||
@Schema(description = "고객의 생년월일 (예시: 1990-01-15)", example = "1990-01-15")
|
||||
private String birthDate;
|
||||
|
||||
@Schema(description = "고객의 멤버십 등급 (예시: GOLD, SILVER, BRONZE)", example = "GOLD")
|
||||
private String membershipLevel;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"resultCode" : "SUCCESS",
|
||||
"customerId" : "12345",
|
||||
"name" : "김철수",
|
||||
"phoneNumber" : "010-1234-5678",
|
||||
"email" : "customer@example.com",
|
||||
"address" : "서울시 강남구 테헤란로 123",
|
||||
"birthDate" : "1990-01-15",
|
||||
"membershipLevel" : "GOLD"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.shinhanlife.dat.mcc.biz.pro.usecase;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryRequest;
|
||||
import io.shinhanlife.dat.mcc.biz.pro.dto.PersonalCustomerDetailInquiryResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class PersonalCustomerDetailInquiryUseCaseTest {
|
||||
|
||||
@Test
|
||||
void createsToolRequestAndResponseDtos() {
|
||||
assertNotNull(new PersonalCustomerDetailInquiryRequest());
|
||||
assertNotNull(new PersonalCustomerDetailInquiryResponse());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user