diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/converter/SolReqDetailConverter.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/converter/SolReqDetailConverter.java new file mode 100644 index 00000000..6b3a7019 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/converter/SolReqDetailConverter.java @@ -0,0 +1,31 @@ +package io.shinhanlife.dap.mcc.biz.sol.converter; + +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailRequest; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailResponse; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io.SOLG00000002_I; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io.SOLG00000002_O; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.converter + * @className SolReqDetailConverter + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Mapper(componentModel = "spring") +public interface SolReqDetailConverter { + + @Mapping(source = "srId", target = "srId") + SOLG00000002_I toLegacyRequest(SolReqDetailRequest req); + + SolReqDetailResponse toResponse(SOLG00000002_O mciRes); +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailRequest.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailRequest.java new file mode 100644 index 00000000..13045419 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailRequest.java @@ -0,0 +1,27 @@ +package io.shinhanlife.dap.mcc.biz.sol.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.shinhanlife.dap.lib.annotation.McpParameter; +import lombok.Data; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.dto + * @className SolReqDetailRequest + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SolReqDetailRequest { + + @McpParameter(description = "상세 조회할 SOL 의뢰서 ID", required = true) + private String srId; +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailResponse.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailResponse.java new file mode 100644 index 00000000..b1c1c230 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/dto/SolReqDetailResponse.java @@ -0,0 +1,33 @@ +package io.shinhanlife.dap.mcc.biz.sol.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.dto + * @className SolReqDetailResponse + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SolReqDetailResponse { + + private String srId; + private String srName; + private String process; + private String devStage; + private String appName; + private String requester; + private String requestDate; + private String dueDate; + private String description; +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/SolReqDetailUseCase.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/SolReqDetailUseCase.java new file mode 100644 index 00000000..043bb0a2 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/SolReqDetailUseCase.java @@ -0,0 +1,39 @@ +package io.shinhanlife.dap.mcc.biz.sol.usecase; + +import io.shinhanlife.dap.lib.annotation.McpFunction; +import io.shinhanlife.dap.lib.annotation.McpTool; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailRequest; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.usecase + * @className SolReqDetailUseCase + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@McpTool( + routingType = "MCI", + categoryKey = "sol" +) +public interface SolReqDetailUseCase { + + @McpFunction( + displayName = "SolReqDetail 툴", + name = "solReqDetail", + description = "SOL 의뢰서 상세 조회", + prompt = "SOL 의뢰서 상세 조회해줘", + mappingId = "SOLG00000002", + register = false, + requiresApproval = false, + readOnlyHint = true, + openWorldHint = true + ) + Object execute(SolReqDetailRequest req); +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImpl.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImpl.java new file mode 100644 index 00000000..be197500 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImpl.java @@ -0,0 +1,101 @@ +package io.shinhanlife.dap.mcc.biz.sol.usecase.impl; + +import io.shinhanlife.dap.mcc.biz.sol.converter.SolReqDetailConverter; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailRequest; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailResponse; +import io.shinhanlife.dap.mcc.biz.sol.usecase.SolReqDetailUseCase; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.MciNclgClient; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io.SOLG00000002_I; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io.SOLG00000002_O; +import io.shinhanlife.glow.communication.dto.Transfer; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.usecase.impl + * @className SolReqDetailUseCaseImpl + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SolReqDetailUseCaseImpl implements SolReqDetailUseCase { + + private final MciNclgClient mci; + private final SolReqDetailConverter converter; + + @Value("${sol.req-detail.mock-enabled:false}") + private boolean mockEnabled; + + @Override + public Object execute(SolReqDetailRequest req) { + log.info("[MCI Tool] {} 요청 수신. 파라미터: {}", "solReqDetail", req); + if (req == null || req.getSrId() == null || req.getSrId().isBlank()) { + return Map.of("status", "ERROR", "message", "srId는 필수입니다."); + } + + if (mockEnabled) { + return createLocalSampleResponse(req.getSrId()); + } + + try { + SOLG00000002_I mciRequest = converter.toLegacyRequest(req); + Transfer mciResponse = mci.callTo( + "SOLG00000002", "SOLG00000002", mciRequest, SOLG00000002_O.class); + + if (mciResponse == null || mciResponse.getBody() == null) { + return Map.of("status", "NOT_FOUND", "message", "의뢰서 상세 정보를 찾을 수 없습니다."); + } + return converter.toResponse(mciResponse.getBody()); + } catch (Exception e) { + log.error("[MCI Tool] 연동 중 오류 발생: {}", e.getMessage(), e); + return Map.of( + "status", "ERROR", + "message", e.getMessage() != null ? e.getMessage() : "Unknown error"); + } + } + + private Object createLocalSampleResponse(String srId) { + SolReqDetailResponse response = new SolReqDetailResponse(); + if ("SR-2026-001".equalsIgnoreCase(srId)) { + response.setSrId("SR-2026-001"); + response.setSrName("AX HUB 메인 화면 UI 개편"); + response.setProcess("진행중"); + response.setDevStage("개발(단위테스트)"); + response.setAppName("AX HUB"); + response.setRequester("신한준"); + response.setRequestDate("2026-07-01"); + response.setDueDate("2026-08-31"); + response.setDescription("AX HUB 메인 화면의 사용성과 접근성을 개선하는 UI 개편 의뢰입니다."); + return response; + } + if ("SR-2026-002".equalsIgnoreCase(srId)) { + response.setSrId("SR-2026-002"); + response.setSrName("SOL 연동 모듈 추가 개발"); + response.setProcess("진행중"); + response.setDevStage("분석/설계"); + response.setAppName("MCP Gateway"); + response.setRequester("고석민"); + response.setRequestDate("2026-07-15"); + response.setDueDate("2026-09-30"); + response.setDescription("SOL 의뢰서 조회 기능을 MCP 도구로 제공하기 위한 연동 모듈 개발 의뢰입니다."); + return response; + } + return Map.of( + "status", "NOT_FOUND", + "message", "의뢰서를 찾을 수 없습니다.", + "srId", srId); + } +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_I.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_I.java new file mode 100644 index 00000000..3b8b2cb1 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_I.java @@ -0,0 +1,23 @@ +package io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io; + +import lombok.Data; + +/** + * @package io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io + * @className SOLG00000002_I + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Data +public class SOLG00000002_I { + + private String srId; +} diff --git a/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_O.java b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_O.java new file mode 100644 index 00000000..1aa61472 --- /dev/null +++ b/dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/infra/itrf/mci/ncl/g/io/SOLG00000002_O.java @@ -0,0 +1,31 @@ +package io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io; + +import lombok.Data; + +/** + * @package io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.io + * @className SOLG00000002_O + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +@Data +public class SOLG00000002_O { + + private String srId; + private String srName; + private String process; + private String devStage; + private String appName; + private String requester; + private String requestDate; + private String dueDate; + private String description; +} diff --git a/dap-tool-oth/src/main/resources/application-local.yml b/dap-tool-oth/src/main/resources/application-local.yml index 13593bf4..a4e5f24c 100644 --- a/dap-tool-oth/src/main/resources/application-local.yml +++ b/dap-tool-oth/src/main/resources/application-local.yml @@ -36,4 +36,8 @@ axhub: gateway: url: http://localhost:8081 tool: - url: ${AXHUB_TOOL_URL:http://localhost:${server.port}} \ No newline at end of file + url: ${AXHUB_TOOL_URL:http://localhost:${server.port}} + +sol: + req-detail: + mock-enabled: true diff --git a/dap-tool-oth/src/test/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImplTest.java b/dap-tool-oth/src/test/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImplTest.java new file mode 100644 index 00000000..e2b245f0 --- /dev/null +++ b/dap-tool-oth/src/test/java/io/shinhanlife/dap/mcc/biz/sol/usecase/impl/SolReqDetailUseCaseImplTest.java @@ -0,0 +1,45 @@ +package io.shinhanlife.dap.mcc.biz.sol.usecase.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.shinhanlife.dap.mcc.biz.sol.converter.SolReqDetailConverter; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailRequest; +import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqDetailResponse; +import io.shinhanlife.dap.mcc.infra.itrf.mci.ncl.g.MciNclgClient; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.test.util.ReflectionTestUtils; + +/** + * @package io.shinhanlife.dap.mcc.biz.sol.usecase.impl + * @className SolReqDetailUseCaseImplTest + * @description AX HUB 시스템 처리 클래스 + * @author 0986406 + * @create 2026.09.01 + *
+ * ---------- 개정이력 ----------
+ * 수정일      수정자    수정내용
+ * ---------- -------- ---------------------------
+ * 2026.09.01  0986406    최초생성
+ *
+ * 
+ */ +class SolReqDetailUseCaseImplTest { + + @Test + void returnsLocalSampleDetailBySrId() { + MciNclgClient mci = Mockito.mock(MciNclgClient.class); + SolReqDetailConverter converter = Mockito.mock(SolReqDetailConverter.class); + SolReqDetailUseCaseImpl useCase = new SolReqDetailUseCaseImpl(mci, converter); + ReflectionTestUtils.setField(useCase, "mockEnabled", true); + + SolReqDetailRequest request = new SolReqDetailRequest(); + request.setSrId("SR-2026-001"); + + SolReqDetailResponse response = (SolReqDetailResponse) useCase.execute(request); + + assertThat(response.getSrId()).isEqualTo("SR-2026-001"); + assertThat(response.getSrName()).isEqualTo("AX HUB 메인 화면 UI 개편"); + Mockito.verifyNoInteractions(mci); + } +}