From b60b933a08ab34c3a52ee646371312583e7bcf64 Mon Sep 17 00:00:00 2001 From: jade Date: Wed, 12 Aug 2026 00:10:04 +0900 Subject: [PATCH] refactor: remove claim schema sample tool --- README.md | 6 +- .../mcc/biz/cmm/dto/ClaimSearchRequest.java | 58 ------------ .../mcc/biz/cmm/dto/ClaimSearchResponse.java | 87 ------------------ .../ClaimSearchSchemaSampleUseCase.java | 16 ---- .../ClaimSearchSchemaSampleUseCaseImpl.java | 36 -------- .../mcc/biz/oth/usecase/Onnba3011UseCase.java | 2 +- .../claim-search-resource-input-schema.json | 49 ---------- .../claim-search-resource-output-schema.json | 83 ----------------- .../claim-search-resource-input-schema.json | 37 -------- .../claim-search-resource-output-schema.json | 81 ---------------- .../cmm/dto/ClaimSearchRequestSchemaTest.java | 92 ------------------- 11 files changed, 4 insertions(+), 543 deletions(-) delete mode 100644 dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequest.java delete mode 100644 dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchResponse.java delete mode 100644 dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/ClaimSearchSchemaSampleUseCase.java delete mode 100644 dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/impl/ClaimSearchSchemaSampleUseCaseImpl.java delete mode 100644 dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-input-schema.json delete mode 100644 dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-output-schema.json delete mode 100644 dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-input-schema.json delete mode 100644 dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-output-schema.json delete mode 100644 dap-was-oth/src/test/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequestSchemaTest.java diff --git a/README.md b/README.md index bfb0acd7..f8da4873 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ UI에서 사용하는 Tailwind CSS와 Chart.js는 `dap-gateway/src/main/resource "jsonrpc": "2.0", "method": "tools/call", "params": { - "name": "cmm_claim_schema_search", + "name": "cmm_claim_search", "arguments": { "claimNo": "CLM2026070100120" } @@ -171,7 +171,7 @@ Tool 함수명은 아래 4단계 규칙을 사용합니다. ```text pod_domain_service_action -예: cmm_claim_schema_search +예: cmm_claim_search ``` - `pod`: Tool Pod 식별자 (`oth`, `sms` 등) @@ -268,4 +268,4 @@ Tool 관련 공통 기능은 `dap-was-*` 모듈명만 기준으로 동작합니 - `validateMcpToolNames`는 `dap-was-*` Tool Pod를 탐색하여 이름 규칙과 전역 중복을 검사합니다. - Tool Scaffold는 Pod 이름을 Tool 함수명에 포함하지 않습니다. 함수명은 `도메인_비즈니스_행위` 형식입니다. 예: `cmm_notification_send` - Pod Scaffold와 Gateway Scaffold 화면/API의 모듈 목록도 `dap-was-*` 명칭으로 통일되어 있습니다. -- Tool Source Update 기능은 `dap-was-*` 아래의 `*UseCase.java`를 검색합니다. \ No newline at end of file +- Tool Source Update 기능은 `dap-was-*` 아래의 `*UseCase.java`를 검색합니다. diff --git a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequest.java b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequest.java deleted file mode 100644 index 6dd3d75d..00000000 --- a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequest.java +++ /dev/null @@ -1,58 +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.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -/** - * 보험금 청구 조회 Tool의 입력 DTO 샘플이다. - * 청구번호 또는 계약번호 중 하나를 반드시 입력받는다. - */ -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ClaimSearchRequest { - - @McpToolParam(description = "청구번호. CLM 다음 숫자 13자리 형식이다.") - @Schema(pattern = "^CLM[0-9]{13}$", example = "CLM2026070100123") - private String claimNo; - - @McpToolParam(description = "계약번호. 숫자 11자리 형식이다.") - @Schema(pattern = "^[0-9]{11}$", example = "10023456789") - private String contractNo; - - @McpToolParam(description = "청구 상태 필터") - @Schema(example = "RECEIVED", allowableValues = { - "RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", - "APPROVED", "PAID", "REJECTED", "WITHDRAWN" - }) - private String status; - - @McpToolParam(description = "청구 유형 필터") - @Schema(example = "MEDICAL", allowableValues = { - "MEDICAL", "SURGERY", "HOSPITALIZATION", - "DIAGNOSIS", "DEATH", "DISABILITY" - }) - private String claimType; - - @McpToolParam(description = "접수일 조회 시작일(YYYY-MM-DD)") - @Schema(format = "date", example = "2026-01-01") - private String fromDate; - - @McpToolParam(description = "접수일 조회 종료일(YYYY-MM-DD)") - @Schema(format = "date", example = "2026-07-31") - private String toDate; - - @McpToolParam(description = "반환할 최대 건수 (기본값: 20, 최대: 50)") - @Schema(pattern = "^[1-9][0-9]?$|^50$", defaultValue = "20", example = "20") - private String size; -} \ No newline at end of file diff --git a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchResponse.java b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchResponse.java deleted file mode 100644 index 9560f6e9..00000000 --- a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchResponse.java +++ /dev/null @@ -1,87 +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 java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -/** - * Claim search response sample. - * Complex response rules are defined by outputSchemaResource; annotations document - * the same simple field constraints for automatic schema generation examples. - */ -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ClaimSearchResponse { - - @McpToolParam(description = "Execution result code.") - @Schema(required = true, allowableValues = {"SUCCESS", "FAILURE"}) - private String resultCode; - - @McpToolParam(description = "User-readable label for resultCode.") - @Schema(required = true, maxLength = 100) - private String resultLabel; - - @McpToolParam(description = "Current claim processing status code.") - @Schema(required = true, allowableValues = { - "RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", - "APPROVED", "PAID", "REJECTED", "WITHDRAWN" - }) - private String status; - - @McpToolParam(description = "User-readable label for status.") - @Schema(required = true, maxLength = 100) - private String statusLabel; - - @McpToolParam(description = "Approved amount. Null before review; do not interpret null as zero.") - @Schema(minimum = "0", nullable = true) - private Long approvedAmount; - - @McpToolParam(description = "Present only when status is REJECTED; otherwise null.") - @Schema(maxLength = 200, nullable = true) - private String rejectionReason; - - @McpToolParam(description = "Claim summaries, ordered by received date descending.") - @Schema(required = true) - private List items; - - @McpToolParam(description = "True when additional results exist beyond this response.") - @Schema(required = true) - private Boolean hasMore; - - @McpToolParam(description = "Total number of matched claims.") - @Schema(required = true, nullable = true) - private Integer totalCount; - - @Getter - @Setter - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class ClaimSummary { - - @McpToolParam(description = "Claim processing status code.") - private String status; - - @McpToolParam(description = "User-readable label for status.") - private String statusLabel; - - @McpToolParam(description = "Received date in YYYY-MM-DD format.") - @Schema(required = true, format = "date") - private String receivedDate; - - @McpToolParam(description = "Approved amount. Null before review; do not interpret null as zero.") - @Schema(nullable = true) - private Long approvedAmount; - } -} \ No newline at end of file diff --git a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/ClaimSearchSchemaSampleUseCase.java b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/ClaimSearchSchemaSampleUseCase.java deleted file mode 100644 index 765ae5ed..00000000 --- a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/ClaimSearchSchemaSampleUseCase.java +++ /dev/null @@ -1,16 +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.ClaimSearchRequest; -import io.shinhanlife.dap.mcc.biz.cmm.dto.ClaimSearchResponse; - -public interface ClaimSearchSchemaSampleUseCase { - - @McpTool(name = "cmm_claim_schema_search", title = "청구 조회 스키마 샘플", description = "Claim search Tool sample using input and output JSON Schema resources.", annotations = @McpTool.McpAnnotations(readOnlyHint = true, idempotentHint = true)) - @ToolHint(register = false, categoryKey = "cmm", - inputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-input-schema.json", - outputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-output-schema.json") - ClaimSearchResponse search(ClaimSearchRequest request); -} diff --git a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/impl/ClaimSearchSchemaSampleUseCaseImpl.java b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/impl/ClaimSearchSchemaSampleUseCaseImpl.java deleted file mode 100644 index 1a817f59..00000000 --- a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/impl/ClaimSearchSchemaSampleUseCaseImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.shinhanlife.dap.mcc.biz.cmm.usecase.impl; - -import io.shinhanlife.dap.mcc.biz.cmm.dto.ClaimSearchRequest; -import io.shinhanlife.dap.mcc.biz.cmm.dto.ClaimSearchResponse; -import io.shinhanlife.dap.mcc.biz.cmm.usecase.ClaimSearchSchemaSampleUseCase; -import java.util.List; -import org.springframework.stereotype.Service; - -/** - * Non-exposed sample Tool. It does not call MCI or EIMS. - */ -@Service -public class ClaimSearchSchemaSampleUseCaseImpl implements ClaimSearchSchemaSampleUseCase { - - @Override - public ClaimSearchResponse search(ClaimSearchRequest request) { - ClaimSearchResponse.ClaimSummary item = ClaimSearchResponse.ClaimSummary.builder() - .status("REVIEWING") - .statusLabel("Under review") - .receivedDate("2026-08-04") - .approvedAmount(null) - .build(); - - return ClaimSearchResponse.builder() - .resultCode("SUCCESS") - .resultLabel("Success") - .status("REVIEWING") - .statusLabel("Under review") - .approvedAmount(null) - .rejectionReason(null) - .items(List.of(item)) - .hasMore(false) - .totalCount(1) - .build(); - } -} \ No newline at end of file diff --git a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/oth/usecase/Onnba3011UseCase.java b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/oth/usecase/Onnba3011UseCase.java index 60a48c85..1e88db13 100644 --- a/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/oth/usecase/Onnba3011UseCase.java +++ b/dap-was-oth/src/main/java/io/shinhanlife/dap/mcc/biz/oth/usecase/Onnba3011UseCase.java @@ -5,7 +5,7 @@ import io.shinhanlife.dap.lib.annotation.ToolHint; import io.shinhanlife.dap.mcc.biz.oth.dto.*; public interface Onnba3011UseCase { - @McpTool(name = "onnba3011_call", description = "Onnba3011 호출 툴") + @McpTool(name = "oth_onnba3011_call", description = "Onnba3011 호출 툴") @ToolHint(categoryKey = "oth", register = false) Object execute(Onnba3011Request req); } diff --git a/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-input-schema.json b/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-input-schema.json deleted file mode 100644 index 56994fb2..00000000 --- a/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-input-schema.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "object", - "additionalProperties": false, - "properties": { - "claimNo": { - "type": "string", - "description": "청구번호. CLM 이후 숫자 13자리 형식입니다.", - "pattern": "^CLM[0-9]{13}$", - "example": "CLM2026070100123" - }, - "contractNo": { - "type": "string", - "description": "계약번호. 숫자 11자리 형식입니다.", - "pattern": "^[0-9]{11}$", - "example": "10023456789" - }, - "status": { - "type": "string", - "description": "청구 상태 필터", - "enum": ["RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", "APPROVED", "PAID", "REJECTED", "WITHDRAWN"], - "example": "RECEIVED" - }, - "claimType": { - "type": "string", - "description": "청구 유형 필터", - "enum": ["MEDICAL", "SURGERY", "HOSPITALIZATION", "DIAGNOSIS", "DEATH", "DISABILITY"], - "example": "MEDICAL" - }, - "fromDate": { - "type": "string", - "description": "접수일 조회 시작일 (YYYY-MM-DD)", - "format": "date", - "example": "2026-01-01" - }, - "toDate": { - "type": "string", - "description": "접수일 조회 종료일 (YYYY-MM-DD)", - "format": "date", - "example": "2026-07-31" - }, - "size": { - "type": "string", - "description": "반환할 최대 건수 (기본값: 20, 최대: 50)", - "pattern": "^[1-9][0-9]?$|^50$", - "default": "20", - "example": "20" - } - } -} diff --git a/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-output-schema.json b/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-output-schema.json deleted file mode 100644 index b7844be3..00000000 --- a/dap-was-oth/src/main/resources/mcp/schema/claim-search-resource-output-schema.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "type": "object", - "additionalProperties": false, - "properties": { - "resultCode": { - "type": "string", - "description": "실행 결과 코드", - "enum": ["SUCCESS", "FAILURE"] - }, - "resultLabel": { - "type": "string", - "description": "resultCode의 사용자 표시 라벨", - "maxLength": 100 - }, - "status": { - "type": "string", - "description": "현재 청구 처리 상태 코드", - "enum": ["RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", "APPROVED", "PAID", "REJECTED", "WITHDRAWN"] - }, - "statusLabel": { - "type": "string", - "description": "status의 사용자 표시 라벨", - "maxLength": 100 - }, - "approvedAmount": { - "anyOf": [ - {"type": "integer", "minimum": 0}, - {"type": "null"} - ], - "description": "승인 금액. 심사 전에는 null이며 0으로 해석하지 않습니다." - }, - "rejectionReason": { - "anyOf": [ - {"type": "string", "maxLength": 200}, - {"type": "null"} - ], - "description": "status가 REJECTED일 때만 존재하며, 그 외에는 null입니다." - }, - "items": { - "type": "array", - "description": "수령일 내림차순으로 정렬된 청구 요약 목록", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "status": { - "type": "string", - "description": "청구 처리 상태 코드" - }, - "statusLabel": { - "type": "string", - "description": "status의 사용자 표시 라벨" - }, - "receivedDate": { - "type": "string", - "description": "접수일 (YYYY-MM-DD 형식)", - "format": "date" - }, - "approvedAmount": { - "anyOf": [ - {"type": "integer", "minimum": 0}, - {"type": "null"} - ], - "description": "승인 금액. 심사 전에는 null" - } - }, - "required": ["receivedDate"] - } - }, - "hasMore": { - "type": "boolean", - "description": "이 응답 이후 추가 결과가 있는지 여부" - }, - "totalCount": { - "anyOf": [ - {"type": "integer", "minimum": 0}, - {"type": "null"} - ], - "description": "매칭된 청구 건수 합계" - } - }, - "required": ["resultCode", "resultLabel", "status", "statusLabel", "items", "hasMore"] -} diff --git a/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-input-schema.json b/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-input-schema.json deleted file mode 100644 index f2c2f633..00000000 --- a/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-input-schema.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "claimNo": { - "type": "string", - "description": "청구번호. CLM 다음 숫자 13자리 형식이다.", - "pattern": "^CLM[0-9]{13}$", - "examples": ["CLM2026070100123"] - }, - "contractNo": { - "type": "string", - "description": "계약번호. 숫자 11자리 형식이다.", - "pattern": "^[0-9]{11}$", - "examples": ["10023456789"] - }, - "status": { - "type": "string", - "enum": [ - "RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", - "APPROVED", "PAID", "REJECTED", "WITHDRAWN" - ] - }, - "size": { - "type": "integer", - "minimum": 1, - "maximum": 50, - "default": 20 - } - }, - "required": [], - "additionalProperties": false, - "anyOf": [ - { "required": ["claimNo"] }, - { "required": ["contractNo"] } - ] -} diff --git a/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-output-schema.json b/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-output-schema.json deleted file mode 100644 index f94c6613..00000000 --- a/dap-was-oth/src/main/resources/tool-schemas/cmm/claim-search-resource-output-schema.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "description": "Claim search response. This schema intentionally excludes employee identifiers, customer names, contact details, account information, and other PII.", - "properties": { - "resultCode": { - "type": "string", - "enum": ["SUCCESS", "FAILURE"], - "description": "Machine-readable execution result code." - }, - "resultLabel": { - "type": "string", - "description": "User-readable label for resultCode." - }, - "status": { - "type": "string", - "enum": ["RECEIVED", "REVIEWING", "ADDITIONAL_DOC_REQUIRED", "APPROVED", "PAID", "REJECTED", "WITHDRAWN"], - "description": "Current claim processing status code." - }, - "statusLabel": { - "type": "string", - "description": "User-readable label for status." - }, - "approvedAmount": { - "anyOf": [ - { "type": "number", "minimum": 0 }, - { "type": "null" } - ], - "description": "Approved amount. It is null before review and must not be interpreted as zero." - }, - "rejectionReason": { - "type": ["string", "null"], - "maxLength": 200, - "description": "Has a value only when status is REJECTED. It is null for every other status." - }, - "items": { - "type": "array", - "description": "Claim summaries ordered by receivedDate descending. No personally identifiable information is included.", - "items": { - "type": "object", - "properties": { - "status": { "type": "string", "description": "Claim status code." }, - "statusLabel": { "type": "string", "description": "User-readable label for status." }, - "receivedDate": { "type": "string", "format": "date", "description": "Claim received date." }, - "approvedAmount": { - "anyOf": [ - { "type": "number", "minimum": 0 }, - { "type": "null" } - ], - "description": "Null before review; do not interpret as zero." - } - }, - "required": ["status", "statusLabel", "receivedDate"], - "additionalProperties": false - } - }, - "hasMore": { - "type": "boolean", - "description": "True when additional results exist beyond this response." - }, - "totalCount": { - "type": "integer", - "minimum": 0, - "description": "Total number of matched claims." - } - }, - "required": ["resultCode", "resultLabel", "status", "statusLabel", "items", "hasMore", "totalCount"], - "allOf": [ - { - "if": { - "properties": { "status": { "const": "REJECTED" } }, - "required": ["status"] - }, - "then": { - "properties": { "rejectionReason": { "type": "string", "minLength": 1 } }, - "required": ["rejectionReason"] - } - } - ], - "additionalProperties": false -} \ No newline at end of file diff --git a/dap-was-oth/src/test/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequestSchemaTest.java b/dap-was-oth/src/test/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequestSchemaTest.java deleted file mode 100644 index 574310c8..00000000 --- a/dap-was-oth/src/test/java/io/shinhanlife/dap/mcc/biz/cmm/dto/ClaimSearchRequestSchemaTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package io.shinhanlife.dap.mcc.biz.cmm.dto; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.ObjectMapper; -import io.shinhanlife.dap.lib.util.JsonSchemaGenerator; -import io.shinhanlife.dap.lib.util.ToolSchemaResolver; -import io.shinhanlife.dap.lib.annotation.ToolHint; -import io.shinhanlife.dap.mcc.biz.cmm.usecase.impl.ClaimSearchSchemaSampleUseCaseImpl; -import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;import io.shinhanlife.dap.mcc.biz.cmm.usecase.ClaimSearchSchemaSampleUseCase; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.springaicommunity.mcp.annotation.McpTool; - -class ClaimSearchRequestSchemaTest { - - @Test - void generatesClaimOrContractSearchSchema() { - Map schema = JsonSchemaGenerator.generateSchema(ClaimSearchRequest.class); - Map> properties = properties(schema); - - assertEquals(false, schema.get("additionalProperties")); - assertEquals("^CLM[0-9]{13}$", properties.get("claimNo").get("pattern")); - assertEquals("^[1-9][0-9]?$|^50$", properties.get("size").get("pattern")); - assertEquals("20", properties.get("size").get("default")); - assertFalse(schema.containsKey("anyOf")); - } - - @Test - void resolvesSchemaFromToolModuleResource() throws Exception { - Method method = ClaimSearchSchemaSampleUseCase.class - .getDeclaredMethod("search", ClaimSearchRequest.class); - McpTool function = method.getAnnotation(McpTool.class); - ToolHint hint = method.getAnnotation(ToolHint.class); - - Map schema = new ToolSchemaResolver(new ObjectMapper()) - .resolve(function, hint, ClaimSearchRequest.class); - - assertEquals("https://json-schema.org/draft/2020-12/schema", schema.get("$schema")); - assertTrue(schema.containsKey("anyOf")); - assertEquals(50, property(schema, "size").get("maximum")); - } - - @Test - void resolvesOutputSchemaFromToolModuleResource() throws Exception { - Method method = ClaimSearchSchemaSampleUseCase.class - .getDeclaredMethod("search", ClaimSearchRequest.class); - McpTool function = method.getAnnotation(McpTool.class); - ToolHint hint = method.getAnnotation(ToolHint.class); - Map schema = new ToolSchemaResolver(new ObjectMapper()) - .resolveOutput(function, ClaimSearchResponse.class, hint); - assertEquals("https://json-schema.org/draft/2020-12/schema", schema.get("$schema")); - assertTrue(properties(schema).containsKey("resultCode")); - assertTrue(properties(schema).containsKey("statusLabel")); - assertTrue(properties(schema).containsKey("hasMore")); - assertTrue(schema.containsKey("allOf")); - } - - @Test - void sampleResponseConformsToOutputSchema() throws Exception { - Method method = ClaimSearchSchemaSampleUseCase.class - .getDeclaredMethod("search", ClaimSearchRequest.class); - Map schema = new ToolSchemaResolver(new ObjectMapper()) - .resolveOutput(method.getAnnotation(McpTool.class), ClaimSearchResponse.class, - method.getAnnotation(ToolHint.class)); - - ClaimSearchResponse response = new ClaimSearchSchemaSampleUseCaseImpl().search(new ClaimSearchRequest()); - ToolArgumentSchemaValidator validator = new ToolArgumentSchemaValidator(new ObjectMapper()); - - assertTrue(validator.validateValue(schema, response).isEmpty()); - } - @Test - void sampleResponseConformsToAutomaticallyGeneratedOutputSchema() throws Exception { - Map schema = JsonSchemaGenerator.generateSchema(ClaimSearchResponse.class); - ClaimSearchResponse response = new ClaimSearchSchemaSampleUseCaseImpl().search(new ClaimSearchRequest()); - ToolArgumentSchemaValidator validator = new ToolArgumentSchemaValidator(new ObjectMapper()); - - assertTrue(validator.validateValue(schema, response).isEmpty()); - } - @SuppressWarnings("unchecked") - private Map> properties(Map schema) { - return (Map>) schema.get("properties"); - } - - private Map property(Map schema, String name) { - return properties(schema).get(name); - } -}