forked from kimhyungsik/ax_hub_mcp_tool
Compare commits
64 Commits
762681f1ce
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b187d6fd1 | ||
|
|
5955c2168e | ||
|
|
244bfade74 | ||
|
|
a8555f05af | ||
|
|
5f58c22efe | ||
|
|
ae8ab85016 | ||
|
|
d2a82db6a4 | ||
|
|
f3099b76ea | ||
|
|
82551d87bb | ||
|
|
f80461a071 | ||
|
|
bb6cbab912 | ||
|
|
93111b430a | ||
|
|
38462b8ad7 | ||
|
|
b6603d7449 | ||
|
|
10aa14ccf4 | ||
|
|
d0471dfc6a | ||
|
|
62a05bf18a | ||
|
|
a5ac2f99eb | ||
|
|
96c0b779e6 | ||
|
|
032b639291 | ||
|
|
42a04c03fd | ||
|
|
cd991bd623 | ||
|
|
740ef1c757 | ||
|
|
8b9bd4de16 | ||
|
|
6a6592f2d5 | ||
|
|
0fcbef043b | ||
|
|
0921e6d85d | ||
|
|
3498dbb388 | ||
|
|
f7ffc00b36 | ||
|
|
bd8db994ce | ||
|
|
6479b56c8e | ||
|
|
eff142b956 | ||
|
|
935702a569 | ||
|
|
87249a621c | ||
|
|
d3cc1f7f33 | ||
|
|
53bc1487c8 | ||
|
|
5080887f8b | ||
|
|
ba2f43cd60 | ||
|
|
b617eaabe4 | ||
|
|
540faff2d8 | ||
|
|
311462d613 | ||
|
|
11738a9e89 | ||
|
|
b71c585cd7 | ||
|
|
ded9fac9ef | ||
|
|
c9a04d031a | ||
|
|
fdf9e91b0a | ||
|
|
7389c6380c | ||
|
|
7f84dd848b | ||
|
|
2db5be1f67 | ||
|
|
318a6ba8d9 | ||
|
|
6416e0e499 | ||
|
|
a7450cb1db | ||
|
|
fe1ed9ea65 | ||
|
|
2e9a0d6005 | ||
|
|
a8363fae1e | ||
|
|
9dcf06ae95 | ||
|
|
317f9865b8 | ||
|
|
6646741665 | ||
|
|
a50c425dba | ||
|
|
96369f8fb5 | ||
|
|
1560589dd5 | ||
|
|
90cf757b5e | ||
|
|
784d00d61c | ||
|
|
e200dbd5b8 |
458
README.md
458
README.md
@@ -1,400 +1,72 @@
|
||||
# DAP WAS MCP Tool Pods
|
||||
# 신한라이프 시스템 도메인 Tool Pod (dat-was-datsy)
|
||||
|
||||
신한라이프 업무 기능을 MCP(Model Context Protocol) Tool로 제공하는 Java 멀티 모듈 프로젝트입니다. 각 업무 모듈은 독립 실행 가능한 Spring Boot 애플리케이션이며, MCP Streamable HTTP와 REST 실행 API를 함께 제공합니다.
|
||||
신한라이프 DX그룹 PJT **MCP & TOOL 파트**에서 개발 및 운영하는 시스템(SYS) 도메인 전용 DATMT Tool Service Pod(`dat-was-sys`)입니다.
|
||||
IAM(계정·인증·인가 및 담당자 조회)과 PCT(점검 일정, 릴리즈 이력, 시스템 공지사항 등) 영역에서 AI Agent가 시스템 운영 현황을 파악하고 질의응답을 지원할 수 있는 MCP 도구를 제공합니다.
|
||||
|
||||
이 저장소에는 DAPMS(Gateway) 애플리케이션이 포함되어 있지 않습니다. DAPMT는 Gateway로 Tool을 push 등록하지 않으며, 각 Pod가 `GET /tool-manifest`를 제공하면 DAPMS가 이 Manifest를 pull하여 Tool 목록을 구성합니다. Tool 조회와 직접 실행은 각 Pod에서도 자체적으로 처리합니다.
|
||||
---
|
||||
|
||||
## 기술 기준
|
||||
## 1. 서비스 사양 요약
|
||||
|
||||
- Java 21
|
||||
- Gradle Wrapper 8.14.3
|
||||
- Spring Boot 3.5.11
|
||||
- MCP Java SDK 2.0.0
|
||||
- Spring AI Community MCP Annotations 0.9.0
|
||||
- Jackson 2.20.1
|
||||
- MapStruct, MyBatis, Redis, Kafka, Resilience4j
|
||||
- JUnit 5
|
||||
|
||||
## 모듈 구성
|
||||
|
||||
| 모듈 | 역할 | 기본 포트 | Tool 수 |
|
||||
|---|---|---:|---:|
|
||||
| `dap-was-lib` | MCP 서버, Tool 스캔·실행, Schema, Manifest, 보안, MCI/EAI/HTTP 연동 공통 기능 | - | - |
|
||||
| `dap-was-cus` | 고객·CRM·VOC·웹 콘텐츠 관리 Tool | 8084 | 51 |
|
||||
| `dap-was-sal` | 영업·청구·인수·동의·현장지원 Tool | 8082 | 52 |
|
||||
| `dap-was-pro` | 상품·계약·고객·GA 설계사 Tool | 8085 | 50 |
|
||||
| `dap-was-sys` | IAM·시스템 상태·공지·점검·배포 Tool | 8086 | 50 |
|
||||
|
||||
총 203개의 `@McpTool` 선언과 203개의 V17 Tool YAML 정의가 있습니다.
|
||||
|
||||
현재 업무 구현은 개발·연동 검증 단계입니다. `dap-was-sal`의 `cmm_claim_search`와 `cmm_memo_retriever`는 각각 MCI와 HTTP Client 흐름을 사용하며, 나머지 Tool은 외부 시스템을 변경하지 않는 모의 응답을 중심으로 구현되어 있습니다.
|
||||
|
||||
## 처리 구조
|
||||
|
||||
```text
|
||||
MCP Client 또는 REST Client
|
||||
├─ MCP Streamable HTTP: /mcp
|
||||
└─ REST: POST /mcp/{toolName}
|
||||
│
|
||||
▼
|
||||
Tool Pod
|
||||
├─ McpToolMethodRegistry
|
||||
│ └─ Spring Bean의 @McpTool 메서드 탐색 및 실행 메서드 캐시
|
||||
├─ ToolRegistryHeartbeatSender
|
||||
│ ├─ Tool 메타데이터 생성
|
||||
│ └─ tool-definitions YAML 병합
|
||||
├─ ToolManifestService
|
||||
│ └─ DAPMS가 pull할 bundle 단위 Manifest 생성
|
||||
├─ McpToolExecutionService
|
||||
│ ├─ 입력 Schema 검증
|
||||
│ ├─ 요청 DTO 변환 및 Tool 호출
|
||||
│ └─ 출력 Schema 검증
|
||||
└─ UseCase → Converter → MCI/EAI/HTTP Client 또는 Mock 응답
|
||||
```
|
||||
|
||||
애플리케이션 시작 시 다음 순서로 Tool이 준비됩니다.
|
||||
|
||||
1. `ToolDefinitionRepository`가 `classpath*:tool-definitions/**/*.yml`을 읽고 V17 필수 항목을 검증합니다.
|
||||
2. `ToolRegistryHeartbeatSender`가 `@McpTool` 메서드를 스캔하고 YAML 정의를 병합해 `ToolMetadata`를 생성합니다.
|
||||
3. `McpToolMethodRegistry`가 실제 호출 가능한 Bean과 메서드를 Tool 이름으로 캐시합니다.
|
||||
4. `ToolPodMcpToolSynchronizer`가 Tool을 MCP SDK 서버에 등록합니다.
|
||||
5. REST와 MCP 요청은 공통 `McpToolExecutionService`를 통해 실행됩니다.
|
||||
|
||||
DAPMT 내부에는 `/registry/register`, `/registry/deregister` 호출이나 주기적인 Gateway heartbeat 전송이 없습니다. `ToolRegistryHeartbeatSender`라는 클래스명은 호환성을 위해 남아 있지만 현재 역할은 로컬 Tool 스캔과 메타데이터 생성뿐입니다.
|
||||
|
||||
### DAPMS 연동 방식
|
||||
|
||||
```text
|
||||
DAPMS
|
||||
└─ GET {DAPMT Pod URL}/tool-manifest
|
||||
└─ bundleId + revision + tools[]
|
||||
└─ 각 Tool endpoint: {Pod URL}/mcp/{toolName}
|
||||
```
|
||||
|
||||
- `mcp.manifest.bundle-id`는 Manifest를 제공하는 Pod의 고유 식별자이며 필수입니다.
|
||||
- 현재 값은 `was-sal`, `was-cus`, `was-pro`, `was-sys`입니다.
|
||||
- DAPMS에 설정한 bundle ID와 DAPMT가 반환하는 `bundleId`가 일치해야 같은 Tool bundle로 관리됩니다.
|
||||
- `mcp.manifest.name-prefix`가 비어 있지 않으면 모든 Tool 이름이 해당 prefix로 시작해야 합니다.
|
||||
- Manifest 내용이 바뀌면 `revision`이 증가하며, `If-None-Match`가 일치하면 `304 Not Modified`를 반환합니다.
|
||||
|
||||
## 제공 API
|
||||
|
||||
각 업무 Pod가 동일한 API 구조를 제공합니다.
|
||||
|
||||
| 목적 | 메서드 | 경로 |
|
||||
|---|---|---|
|
||||
| MCP Streamable HTTP | MCP 프로토콜 | `/mcp` |
|
||||
| MCP 메시지 전송 | MCP 프로토콜 | `/mcp/message` |
|
||||
| 로컬 Tool 메타데이터 조회 | `GET` | `/mcp/api/v1/tools/local` |
|
||||
| Tool 직접 실행 | `POST` | `/mcp/{toolName}` |
|
||||
| Tool Manifest 조회 | `GET` | `/tool-manifest` |
|
||||
|
||||
`GET /tool-manifest`는 `If-None-Match` 요청 헤더를 지원합니다. Manifest가 변경되지 않았으면 `304 Not Modified`를 반환합니다.
|
||||
|
||||
### REST 실행 예시
|
||||
|
||||
다음은 SYS Pod의 시스템 상태 Tool 호출 예시입니다.
|
||||
|
||||
```powershell
|
||||
$headers = @{
|
||||
'X-Tool-Server-API-Key' = $env:TOOL_SERVER_API_KEY
|
||||
'guid' = 'guid-local-001'
|
||||
'x-request-id' = 'request-local-001'
|
||||
'employee-no' = '100001'
|
||||
'virtual-employee-no' = 'V100001'
|
||||
'mcp-session-id' = 'session-local-001'
|
||||
}
|
||||
|
||||
Invoke-RestMethod `
|
||||
-Method Post `
|
||||
-Uri 'http://localhost:8086/mcp/iam_system_status' `
|
||||
-Headers $headers `
|
||||
-ContentType 'application/json' `
|
||||
-Body '{"environment":"개발"}'
|
||||
```
|
||||
|
||||
### 요청 헤더 계약
|
||||
|
||||
DAPMS가 DAPMT Tool Service를 호출할 때 사용하는 헤더는 다음과 같습니다. HTTP 헤더 이름은 대소문자를 구분하지 않지만, 문서와 구현에서는 아래 표기를 기준으로 사용합니다.
|
||||
|
||||
| 헤더 | 필수 여부 | 용도 | 전달 동작 |
|
||||
|---|---|---|---|
|
||||
| `X-Tool-Server-API-Key` | 인증 설정 시 필수 | DAPMS와 DAPMT 사이의 Tool Server 인증 | `mcp.security.api-key` 또는 `api-keys`와 비교 |
|
||||
| `guid` | 선택 | 업무 호출 상관관계 식별자 | 실행 로그, 성공 응답, 하위 HTTP 호출로 전달 |
|
||||
| `x-request-id` | 선택 | 요청 추적 식별자 | 실행 로그, 성공 응답, 하위 HTTP 호출로 전달 |
|
||||
| `employee-no` | 선택 | 실제 사용자 사번 | 하위 HTTP 호출로 전달 |
|
||||
| `virtual-employee-no` | 선택 | 가상 사용자 사번 | 하위 HTTP 호출로 전달 |
|
||||
| `mcp-session-id` | 선택 | MCP 세션 식별자 | 성공 응답과 하위 HTTP 호출로 전달 |
|
||||
|
||||
REST 경로 `/mcp/{toolName}`은 Controller가 위 헤더를 직접 읽습니다. MCP Streamable HTTP 경로 `/mcp`는 `McpRequestHeaderFilter`가 동일한 헤더를 `McpRequestHeaderContext`에 저장한 뒤 Tool 실행과 하위 HTTP 호출에 전달합니다. 헤더가 없는 하위 HTTP 호출에는 `X-ANONYMOUS-REQ: AXHUB-TOOL`이 설정됩니다.
|
||||
|
||||
주요 실행 응답은 다음과 같습니다.
|
||||
|
||||
| HTTP 상태 | 코드 | 의미 |
|
||||
|---:|---|---|
|
||||
| 200 | - | Tool 실행 성공 |
|
||||
| 404 | `TOOL_NOT_FOUND` | 요청한 Tool 이름이 없음 |
|
||||
| 422 | `INVALID_PARAM` | 요청이 입력 Schema와 일치하지 않음 |
|
||||
| 500 | `INVALID_TOOL_RESPONSE` | 결과가 출력 Schema와 일치하지 않음 |
|
||||
| 502 | `TOOL_ERROR` | Tool 실행 중 예외 발생 |
|
||||
|
||||
## Tool 구현 방식
|
||||
|
||||
호출 가능한 메서드는 Spring AI Community의 `@McpTool`로 선언합니다. 프로젝트 고유 실행·표시 정보는 `@GrowToolHint`로 보완합니다.
|
||||
|
||||
```java
|
||||
@McpTool(
|
||||
name = "iam_system_status",
|
||||
title = "시스템 상태 조회",
|
||||
description = "모의 시스템 상태 정보를 조회합니다.",
|
||||
annotations = @McpTool.McpAnnotations(openWorldHint = false)
|
||||
)
|
||||
@GrowToolHint(
|
||||
categoryKey = "iam",
|
||||
mappingId = "DIRECT_IAM_STATUS",
|
||||
requiresApproval = false
|
||||
)
|
||||
SystemStatusResponse getSystemStatus(SystemStatusRequest request);
|
||||
```
|
||||
|
||||
`@McpTool.name`은 다음 형식을 사용합니다.
|
||||
|
||||
```text
|
||||
^[a-z][a-z0-9_]{2,63}$
|
||||
```
|
||||
|
||||
예: `cmm_claim_search`, `crm_customer_detail`, `iam_system_status`
|
||||
|
||||
이름 중복과 형식은 `validateMcpToolNames`, V17 정의는 `validateToolSchemaV17` Gradle 작업으로 검사합니다. 모든 `bootJar` 작업은 두 검증 작업에 의존합니다.
|
||||
|
||||
## Tool YAML 정의
|
||||
|
||||
각 Tool은 업무 모듈의 다음 경로에 YAML 정의를 가집니다.
|
||||
|
||||
```text
|
||||
dap-was-*/src/main/resources/tool-definitions/{category}/{tool-name}.yml
|
||||
```
|
||||
|
||||
V17 정의의 주요 필수 항목은 다음과 같습니다.
|
||||
|
||||
- `name`, `display_name`, `version`, `category_key`
|
||||
- `description.function`, `when_to_use`, `when_not_to_use`, `io_limits`
|
||||
- 3~10개의 `example_queries`
|
||||
- `read_only`, `destructive`, `idempotent`
|
||||
- `parameters_schema.type: object`
|
||||
- `parameters_schema.additionalProperties: false`
|
||||
- 각 입력 property의 `description`
|
||||
|
||||
입력·출력 Schema는 `ToolSchemaResolver`가 어노테이션의 Schema 리소스와 인라인 Schema, DTO에서 생성한 Schema를 해석합니다. `ToolRegistryHeartbeatSender`는 여기에 YAML의 `parameters_schema`와 `output_schema`를 병합하여 최종 메타데이터를 만듭니다.
|
||||
|
||||
실행 시 Schema 검증은 MCP Java SDK의 `DefaultJsonSchemaValidator`를 사용하며 JSON Schema 2020-12 기준으로 처리합니다. 입력 불일치는 `422 INVALID_PARAM`, 출력 불일치는 `500 INVALID_TOOL_RESPONSE`로 반환됩니다. 단, Schema 해석 또는 검증기 자체에서 예외가 발생하면 현재 구현은 오류를 로그에 기록하고 해당 검증을 건너뜁니다.
|
||||
|
||||
## 로컬 실행
|
||||
|
||||
### 사전 조건
|
||||
|
||||
- JDK 21
|
||||
- 프로젝트에 포함된 Gradle Wrapper
|
||||
- Redis 또는 외부 연동이 필요한 경우 Docker
|
||||
|
||||
기본 활성 프로필은 `local`입니다. 로컬 프로필은 H2 메모리 DB와 P6Spy를 사용합니다.
|
||||
|
||||
```powershell
|
||||
$env:SPRING_PROFILES_ACTIVE = 'local'
|
||||
$env:TOOL_SERVER_API_KEY = 'tool-server-key'
|
||||
```
|
||||
|
||||
`TOOL_SERVER_API_KEY`를 지정하지 않으면 현재 개발 기본값인 `tool-server-key`가 사용됩니다. 운영 환경에서는 기본값을 사용하지 말고 DAPMS의 Tool Server API Key와 동일한 별도 Secret을 주입해야 합니다.
|
||||
|
||||
각 Pod는 별도 터미널에서 실행합니다.
|
||||
|
||||
```powershell
|
||||
# 영업 Tool Pod
|
||||
$env:AXHUB_TOOL_URL = 'http://localhost:8082'
|
||||
.\gradlew.bat :dap-was-sal:bootRun
|
||||
|
||||
# 고객 Tool Pod
|
||||
$env:AXHUB_TOOL_URL = 'http://localhost:8084'
|
||||
.\gradlew.bat :dap-was-cus:bootRun
|
||||
|
||||
# 상품 Tool Pod
|
||||
$env:AXHUB_TOOL_URL = 'http://localhost:8085'
|
||||
.\gradlew.bat :dap-was-pro:bootRun
|
||||
|
||||
# 시스템 Tool Pod
|
||||
$env:AXHUB_TOOL_URL = 'http://localhost:8086'
|
||||
.\gradlew.bat :dap-was-sys:bootRun
|
||||
```
|
||||
|
||||
실행 후 SYS Pod 기준 확인 URL은 다음과 같습니다.
|
||||
|
||||
```text
|
||||
http://localhost:8086/mcp/api/v1/tools/local
|
||||
http://localhost:8086/tool-manifest
|
||||
http://localhost:8086/swagger-ui/index.html
|
||||
```
|
||||
|
||||
### 주요 환경 변수
|
||||
|
||||
| 환경 변수 | 설명 | 기본값 |
|
||||
|---|---|---|
|
||||
| `SPRING_PROFILES_ACTIVE` | Spring 활성 프로필 | `local` |
|
||||
| `PORT` | Pod 수신 포트 | 모듈별 기본 포트 |
|
||||
| `TOOL_SERVER_API_KEY` | DAPMS가 `X-Tool-Server-API-Key`로 전달할 공통 인증 Key | `tool-server-key` |
|
||||
| `AXHUB_TOOL_URL` | Manifest의 Tool endpoint 생성에 사용할 Pod 외부 URL | `http://localhost:${server.port}` |
|
||||
| `AXHUB_GATEWAY_URL` | 프로필 및 Compose 호환용 Gateway URL. 현재 DAPMT의 push 등록에는 사용하지 않음 | `http://localhost:8081` |
|
||||
| `SPRING_DATA_REDIS_HOST` | Redis 호스트 | `localhost` |
|
||||
| `SPRING_DATA_REDIS_PORT` | Redis 포트 | `6379` |
|
||||
| `GLOW_COMMUNICATION_MCI_HOST` | MCI 대상 호스트 | 프로필별 설정 |
|
||||
| `GLOW_COMMUNICATION_MCI_PORT` | MCI 대상 포트 | 프로필별 설정 |
|
||||
|
||||
`mcp.security.api-key`는 단일 DAPMS 공통 Key를, `mcp.security.api-keys`는 `API Key → tenant ID` 형태의 다중 Key를 지원합니다. 둘 중 하나라도 설정되어 있으면 올바른 `X-Tool-Server-API-Key`가 없는 `/rpc/**`, `/mcp/**` 요청은 `401 Unauthorized`가 됩니다. 두 설정이 모두 비어 있을 때만 익명 요청을 허용합니다. 현재 네 업무 Pod의 기본 `application.yml`은 단일 Key를 설정하므로 API Key 없이 Tool을 호출할 수 없습니다.
|
||||
|
||||
## Scaffold
|
||||
|
||||
공통 라이브러리는 새 Tool과 새 Tool Pod를 만드는 두 개의 Java CLI를 제공합니다. 두 클래스의 `main` 메서드를 IDE에서 실행하거나 필요한 인자를 전달해 실행할 수 있습니다.
|
||||
|
||||
| Scaffolder | 역할 | 주요 생성·수정 대상 |
|
||||
|---|---|---|
|
||||
| `ToolScaffolder` | 기존 Pod에 Tool 구현 추가 | UseCase, DTO, Converter, Mock 응답, V17 Tool YAML, 연동 설정 |
|
||||
| `PodScaffolder` | 새 실행 Pod 모듈 추가 | 모듈 디렉터리, `build.gradle`, Dockerfile, Application 클래스, 프로필 설정, `settings.gradle`, `docker-compose.yml` |
|
||||
|
||||
`PodScaffolder`의 인자 순서는 다음과 같습니다.
|
||||
|
||||
```text
|
||||
PodScaffolder <module-name> <port> [author] [yyyy.MM.dd]
|
||||
```
|
||||
|
||||
예를 들어 `payment 8099`를 입력하면 `dap-was-payment` 모듈을 생성합니다. 생성되는 `application.yml`에는 다음 계약이 포함됩니다.
|
||||
|
||||
```yaml
|
||||
mcp:
|
||||
manifest:
|
||||
bundle-id: dap-was-payment
|
||||
name-prefix: ""
|
||||
security:
|
||||
api-key: ${TOOL_SERVER_API_KEY:tool-server-key}
|
||||
```
|
||||
|
||||
생성되는 Compose 서비스에도 `TOOL_SERVER_API_KEY=${TOOL_SERVER_API_KEY:-tool-server-key}`가 추가됩니다. 생성 후에는 다음 항목을 반드시 확인해야 합니다.
|
||||
|
||||
1. `bundle-id`를 DAPMS에 등록할 bundle ID와 일치시킵니다.
|
||||
2. 운영 환경의 `TOOL_SERVER_API_KEY`를 DAPMS가 전달하는 Key와 동일한 Secret으로 설정합니다.
|
||||
3. 실제 배포 주소에 맞게 `AXHUB_TOOL_URL`을 설정합니다.
|
||||
4. MCI·EAI·HTTP 연동 대상과 timeout을 환경별 설정으로 교체합니다.
|
||||
5. `validateMcpToolNames`, `validateToolSchemaV17`, 전체 테스트를 실행합니다.
|
||||
|
||||
## 테스트와 검증
|
||||
|
||||
```powershell
|
||||
# 운영 소스 전체 컴파일
|
||||
.\gradlew.bat classes
|
||||
|
||||
# 전체 테스트
|
||||
.\gradlew.bat test
|
||||
|
||||
# 모듈별 테스트
|
||||
.\gradlew.bat :dap-was-lib:test
|
||||
.\gradlew.bat :dap-was-cus:test
|
||||
.\gradlew.bat :dap-was-sal:test
|
||||
.\gradlew.bat :dap-was-pro:test
|
||||
.\gradlew.bat :dap-was-sys:test
|
||||
|
||||
# Tool 이름·중복 검사
|
||||
.\gradlew.bat validateMcpToolNames
|
||||
|
||||
# 203개 Tool V17 정의 검사
|
||||
.\gradlew.bat validateToolSchemaV17
|
||||
|
||||
# 검증, 테스트, 패키징
|
||||
.\gradlew.bat clean build
|
||||
```
|
||||
|
||||
### 현재 검증 상태
|
||||
|
||||
2026-08-18 기준 확인 결과입니다.
|
||||
|
||||
- 전체 `test`: 성공
|
||||
- 총 94개 테스트 성공, 실패·오류·건너뜀 0개
|
||||
- `validateMcpToolNames`: 성공
|
||||
- `validateToolSchemaV17`: 203개 Tool 성공
|
||||
- 실행 명령: `.\gradlew.bat test validateMcpToolNames validateToolSchemaV17`
|
||||
|
||||
## Docker Compose
|
||||
|
||||
`docker-compose.yml`은 DAPMT의 네 업무 Pod만 정의합니다.
|
||||
|
||||
| 서비스 | 컨테이너 포트 | 호스트 포트 |
|
||||
|---|---:|---:|
|
||||
| `was-sal` | 8082 | 8282 |
|
||||
| `was-cus` | 8084 | 8284 |
|
||||
| `was-pro` | 8085 | 8285 |
|
||||
| `was-sys` | 8086 | 8286 |
|
||||
|
||||
모듈 Dockerfile은 사전에 생성된 Boot JAR를 이미지에 복사합니다. 먼저 JAR를 빌드한 뒤 Compose를 실행합니다.
|
||||
|
||||
```powershell
|
||||
.\gradlew.bat :dap-was-sal:bootJar :dap-was-cus:bootJar :dap-was-pro:bootJar :dap-was-sys:bootJar
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Compose 파일의 용도와 현재 주의점은 다음과 같습니다.
|
||||
|
||||
| 파일 | 용도 | 현재 소스 기준 주의점 |
|
||||
|---|---|---|
|
||||
| `docker-compose.yml` | DAPMT 네 Pod 단독 실행 | `gateway` 서비스가 없지만 push 등록이 제거되어 DAPMT 시작에는 필요하지 않음 |
|
||||
| `docker-compose.local.yml` | DAPMS와 DAPMT의 로컬 통합 구성 | 두 저장소가 같은 상위 디렉터리에 있는 구조를 가정 |
|
||||
| `docker-compose.prod.yml` | DAPMS와 DAPMT의 개발 프로필 기반 OCI 구성 | 저장소의 runner 등록 토큰을 운영 Secret으로 분리해야 함 |
|
||||
|
||||
`docker-compose.local.yml`과 `docker-compose.prod.yml`의 build context는 각각 `./dap-was-dapms`, `./dap-was-dapmt`입니다. 현재 파일 위치에서 사용할 때는 context 기준을 두 저장소의 상위 디렉터리로 맞춰야 합니다.
|
||||
|
||||
```powershell
|
||||
# DAPMT 저장소 디렉터리에서 실행
|
||||
docker compose --project-directory .. -f docker-compose.local.yml up --build
|
||||
```
|
||||
|
||||
현재 기존 네 Pod의 Compose 정의에는 `TOOL_SERVER_API_KEY` 환경 변수 전달이 없습니다. 따라서 컨테이너는 애플리케이션 기본값 `tool-server-key`를 사용합니다. 운영 배포 전 각 서비스에 Secret 기반 `TOOL_SERVER_API_KEY` 전달 설정을 추가하고 DAPMS의 Key와 일치시켜야 합니다. DAPMS는 각 Pod의 `AXHUB_TOOL_URL` 또는 배포 URL에 접근해 `/tool-manifest`를 pull할 수 있어야 합니다.
|
||||
|
||||
## 보안 및 운영 주의사항
|
||||
|
||||
현재 구현을 운영 환경에 노출하기 전에 아래 항목을 반드시 점검해야 합니다.
|
||||
|
||||
- API Key 인터셉터는 `/rpc/**`, `/mcp/**`에 적용됩니다. 따라서 `/mcp`, `/mcp/{toolName}`, `/mcp/api/v1/tools/local`은 인증 대상입니다.
|
||||
- `/tool-manifest`는 위 인터셉터 경로 밖에 있어 현재 API Key 인증 대상이 아닙니다. 내부망·Ingress 정책 또는 별도 인증이 필요한지 운영 기준을 확인해야 합니다.
|
||||
- 네 업무 Pod의 기본 Key는 모두 `tool-server-key`입니다. 운영에서는 반드시 별도 Secret으로 교체하고 DAPMS의 `X-Tool-Server-API-Key` 값과 일치시켜야 합니다.
|
||||
- 설정된 단일 Key와 다중 Key가 모두 없을 때만 익명 요청이 허용됩니다.
|
||||
- `mcp.security.tenant-domains`는 설정 객체에 바인딩되지만 Tool별 인가에 사용되지 않습니다.
|
||||
- `requiresApproval`은 메타데이터에만 기록되며 실행 차단이나 승인 확인 로직은 없습니다.
|
||||
- 입력·출력 Schema 처리 자체에서 예외가 발생하면 현재 실행 서비스는 로그를 남기고 검증을 건너뜁니다.
|
||||
- CORS는 모든 Origin을 허용하면서 credential도 허용하도록 설정되어 있습니다. 운영 Origin을 명시적으로 제한해야 합니다.
|
||||
- `docker-compose.prod.yml`에 runner 등록 토큰이 평문으로 포함되어 있습니다. 사용 중인 토큰은 폐기·재발급하고 배포 Secret으로 이전해야 합니다.
|
||||
- Tool 요청과 연동 오류 로그에 개인정보나 인증정보가 포함되지 않도록 DTO와 로그 마스킹 정책을 검토해야 합니다.
|
||||
|
||||
## 주요 소스 위치
|
||||
|
||||
| 주제 | 위치 |
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 공통 빌드 및 검증 작업 | `build.gradle` |
|
||||
| REST Tool 실행 API | `dap-was-lib/src/main/java/io/shinhanlife/dap/mcc/presentation/BusinessToolController.java` |
|
||||
| 요청 헤더 캡처·전달 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpRequestHeaderFilter.java`, `McpRequestHeaderContext.java` |
|
||||
| Tool 실행 서비스 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpToolExecutionService.java` |
|
||||
| JSON Schema 2020-12 검증 설정 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/config/ToolSchemaConfiguration.java` |
|
||||
| 실행 메서드 Registry | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/McpToolMethodRegistry.java` |
|
||||
| MCP SDK 서버 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolMcpServerConfiguration.java` |
|
||||
| MCP Tool 동기화 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolPodMcpToolSynchronizer.java` |
|
||||
| Tool 스캔 및 메타데이터 생성 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/ToolRegistryHeartbeatSender.java` |
|
||||
| YAML Tool 정의 로딩 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/metadata/ToolDefinitionRepository.java` |
|
||||
| V17 정의 검증 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/metadata/ToolDefinitionValidator.java` |
|
||||
| Manifest 생성 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/manifest/ToolManifestService.java` |
|
||||
| API Key 인터셉터 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/mcp/security/ApiKeyInterceptor.java` |
|
||||
| Tool·Pod 스캐폴딩 | `dap-was-lib/src/main/java/io/shinhanlife/dap/lib/util/ToolScaffolder.java`, `PodScaffolder.java` |
|
||||
| **서비스명 (모듈)** | `dat-was-sys` (`dat-was-datsy`) |
|
||||
| **서버 포트** | **8086** (기본) |
|
||||
| **MCP 엔드포인트** | `http://localhost:8086/mcp`, `http://localhost:8086/mcp/message` |
|
||||
| **Swagger UI** | `http://localhost:8086/swagger-ui.html` |
|
||||
| **Bundle ID** | `was-sys` |
|
||||
| **기반 기술** | Java 21, Spring Boot 3.5.11, MCP Java SDK 2.0.0 |
|
||||
| **공통 의존성** | `io.shinhanlife:dat-lib-datmt:0.0.1-SNAPSHOT` (`dat-was-lib`) |
|
||||
|
||||
## 개발 시 권장 확인 순서
|
||||
---
|
||||
|
||||
## 2. 제공 MCP 도구 (Tools) 목록
|
||||
|
||||
### ① IAM (Identity & Access Management / 조직)
|
||||
- **`AccountInquiryUseCase`**: 사번 또는 계정 ID를 통한 사용자/임직원 기본 정보 조회
|
||||
- **`AuthenticationInquiryUseCase`**: 계정의 2차 인증 상태, 계정 잠김 여부 등 인증 상태 확인
|
||||
- **`AuthorizationInquiryUseCase`**: 사용자가 보유한 시스템 권한 그룹 및 리소스 접근 인가 현황 조회
|
||||
- **`SystemStatusUseCase`**: 신한라이프 주요 IT 서비스 및 연계 채널의 실시간 가동 상태 점검
|
||||
- **`TeamContactUseCase`**: 특정 업무/시스템별 담당 부서, 담당자 및 비상 연락처 조회
|
||||
|
||||
### ② PCT (Process & Change Management / 운영)
|
||||
- **`MaintenanceInquiryUseCase`**: 예정된 시스템 정기 점검, 서버 패치 및 서비스 중단 일정 조회
|
||||
- **`ReleaseInquiryUseCase`**: 최근 배포된 시스템 기능 개선 및 릴리즈 이력 정보 조회
|
||||
- **`SystemNoticeUseCase`**: 전사 시스템 공지사항 및 긴급 장애 공지 내역 조회
|
||||
|
||||
---
|
||||
|
||||
## 3. 공통 라이브러리 연동 (Composite Build)
|
||||
|
||||
본 저장소는 상위 워크스페이스의 `../dat-lib-datmt` 공통 라이브러리를 로컬 복합 빌드(Composite Build)로 직접 참조합니다.
|
||||
|
||||
```text
|
||||
workspace/
|
||||
├── dat-lib-datmt/ # 공통 라이브러리 (:dat-was-lib)
|
||||
└── dat-was-datsy/ # [현재 저장소] 시스템 도메인 Tool Pod (:dat-was-sys)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 빌드 및 실행 가이드
|
||||
|
||||
### 컴파일 및 빌드
|
||||
```powershell
|
||||
.\gradlew.bat compileJava
|
||||
```
|
||||
|
||||
### 단위 테스트 실행
|
||||
```powershell
|
||||
.\gradlew.bat test
|
||||
```
|
||||
|
||||
### 로컬 애플리케이션 실행
|
||||
```powershell
|
||||
.\gradlew.bat :dat-was-sys:bootRun
|
||||
```
|
||||
*기본 활성화 프로파일: `local` (`application-local.yml` 참조)*
|
||||
|
||||
### 도커 컨테이너 빌드 및 로컬 구동
|
||||
```powershell
|
||||
docker compose -f docker-compose.local.yml up -d --build
|
||||
```
|
||||
|
||||
1. Tool 메서드와 요청·응답 DTO를 구현합니다.
|
||||
2. 동일 이름의 V17 YAML 정의를 `tool-definitions` 아래에 추가합니다.
|
||||
3. `validateMcpToolNames`와 `validateToolSchemaV17`을 실행합니다.
|
||||
4. 모듈 테스트와 전체 테스트를 실행합니다.
|
||||
5. 로컬 Pod에서 `/mcp/api/v1/tools/local`과 `/tool-manifest`를 확인합니다.
|
||||
6. DAPMS의 bundle ID, Pod Manifest URL, Tool Server API Key가 DAPMT 설정과 일치하는지 확인합니다.
|
||||
7. REST와 MCP 양쪽에서 동일한 Tool 결과·요청 헤더 전달·오류 계약을 확인합니다.
|
||||
|
||||
227
build.gradle
227
build.gradle
@@ -1,113 +1,178 @@
|
||||
// 루트 Gradle 설정: 모든 Gateway/Tool Pod 모듈이 공유하는 빌드 기준을 정의합니다.
|
||||
plugins {
|
||||
// Java 컴파일, 테스트, JAR 생성 기능을 제공합니다.
|
||||
id 'java'
|
||||
|
||||
// 하위 실행 모듈에서 bootRun/bootJar를 사용하기 위한 Spring Boot 플러그인입니다.
|
||||
// 루트 프로젝트에는 적용하지 않으므로 apply false를 사용합니다.
|
||||
id 'org.springframework.boot' version '3.5.11' apply false
|
||||
|
||||
// Spring Boot / Spring AI BOM에 정의된 라이브러리 버전을 일관되게 적용합니다.
|
||||
id 'io.spring.dependency-management' version '1.1.6' apply false
|
||||
id 'org.springframework.boot' version '3.5.11'
|
||||
id 'io.spring.dependency-management' version '1.1.7'
|
||||
}
|
||||
|
||||
// 모든 모듈이 공유하는 Maven 식별자입니다.
|
||||
|
||||
// ============================================================================
|
||||
// 전체 프로젝트 공통 Maven 좌표
|
||||
// ============================================================================
|
||||
|
||||
allprojects {
|
||||
// 모든 모듈이 공유하는 Maven Group ID입니다.
|
||||
group = 'io.shinhanlife'
|
||||
// 모든 모듈이 공유하는 프로젝트 버전입니다.
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
// dap-gateway, dap-was-lib, dap-was-oth, dap-was-sms에 공통 적용합니다.
|
||||
|
||||
subprojects {
|
||||
// 모든 하위 모듈에서 Java Plugin을 사용합니다.
|
||||
apply plugin: 'java'
|
||||
// Spring Boot BOM 기반 의존성 버전 관리를 위해 적용합니다.
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
|
||||
java {
|
||||
// 프로젝트 표준 Java 버전입니다.
|
||||
sourceCompatibility = '21'
|
||||
}
|
||||
|
||||
repositories {
|
||||
// 현재 공개 정식 라이브러리 저장소입니다.
|
||||
// 폐쇄망 적용 시 사내 Nexus Proxy URL로 교체합니다.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
// Spring Boot 3.5.11과 호환되는 Spring/Jackson/Tomcat 등의 버전을 관리합니다.
|
||||
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
|
||||
|
||||
// Boot 3.5.11과 호환되는 Spring AI 계층은 1.1.8로 유지합니다.
|
||||
mavenBom 'org.springframework.ai:spring-ai-bom:1.1.8'
|
||||
|
||||
// MCP Java SDK만 2.0.0으로 올립니다. Spring AI 2.x 전체 BOM은 Boot 4 기반이므로 사용하지 않습니다.
|
||||
mavenBom 'io.modelcontextprotocol.sdk:mcp-bom:2.0.0'
|
||||
|
||||
// MCP SDK 2.0의 Jackson 2 전송 모듈이 요구하는 호환 버전입니다.
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.20.1'
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
// [로컬 개발 순서]
|
||||
// 1. ../dat-lib-datmt에서 .\gradlew.bat :dat-was-lib:publishToMavenLocal 실행
|
||||
// 2. 위 명령이 ~/.m2/repository/io/shinhanlife/dat-lib-datmt에 JAR/POM을 등록
|
||||
// 3. 아래 mavenLocal()이 등록된 JAR을 찾아 implementation 의존성을 해석
|
||||
//
|
||||
// [신한라이프 이관]
|
||||
// mavenLocal() 대신 사내 Nexus Maven repository를 추가합니다.
|
||||
// implementation 좌표는 그대로 유지합니다.
|
||||
mavenLocal()
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// 외부 개발 환경
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// 현재 인터넷이 가능한 환경에서는 Maven Central을 사용합니다.
|
||||
//
|
||||
// 신한라이프 폐쇄망 반입 시 아래 mavenCentral()은 제거하고
|
||||
// 사내 Nexus Repository URL로 교체해야 합니다.
|
||||
//
|
||||
// 예:
|
||||
//
|
||||
// maven {
|
||||
// url = uri('https://내부-Nexus/repository/maven-public/')
|
||||
// }
|
||||
//
|
||||
// Nexus 인증이 필요한 경우에는 credentials 설정도 추가해야 합니다.
|
||||
//
|
||||
// credentials {
|
||||
// username = findProperty('nexusUsername') ?: System.getenv('NEXUS_USERNAME')
|
||||
// password = findProperty('nexusPassword') ?: System.getenv('NEXUS_PASSWORD')
|
||||
// }
|
||||
//
|
||||
// 계정/비밀번호를 build.gradle에 직접 작성하면 안 됩니다.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Dependency Version Management
|
||||
// ========================================================================
|
||||
|
||||
dependencyManagement {
|
||||
|
||||
imports {
|
||||
// Spring Boot 3.5.11이 검증한
|
||||
// Spring Framework / Jackson / Tomcat / Logback /
|
||||
// JUnit 등 주요 라이브러리 버전을 공통 관리합니다.
|
||||
// 하위 모듈에서는 Spring Boot가 관리하는 라이브러리라면
|
||||
// 가급적 개별 버전을 직접 지정하지 않고 사용합니다.
|
||||
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
|
||||
|
||||
// MCP SDK 버전 관리
|
||||
mavenBom 'io.modelcontextprotocol.sdk:mcp-bom:2.0.0'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Common Dependencies
|
||||
// ========================================================================
|
||||
|
||||
dependencies {
|
||||
// Lombok은 컴파일 시 getter/builder 등 반복 코드를 생성하며 실행 JAR에는 포함하지 않습니다.
|
||||
compileOnly 'org.projectlombok:lombok:1.18.32'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
||||
testCompileOnly 'org.projectlombok:lombok:1.18.32'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'
|
||||
|
||||
// Tool DTO와 MCI 요청/응답 객체 간 Converter 구현체를 컴파일 시 자동 생성합니다.
|
||||
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
|
||||
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
|
||||
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
|
||||
// ====================================================================
|
||||
// Lombok
|
||||
// ====================================================================
|
||||
|
||||
// 모든 모듈의 JUnit 5 기반 테스트 공통 의존성입니다.
|
||||
// Lombok은 컴파일 시 Getter / Setter / Builder 등의
|
||||
// 반복 코드를 생성합니다.
|
||||
//
|
||||
// compileOnly이므로 Runtime JAR에는 포함되지 않습니다.
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
|
||||
// Lombok Annotation Processor입니다.
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
// 테스트 코드에서도 Lombok Annotation을 사용할 수 있도록 합니다.
|
||||
testCompileOnly 'org.projectlombok:lombok'
|
||||
|
||||
// 테스트 코드용 Lombok Annotation Processor입니다.
|
||||
testAnnotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
|
||||
// ====================================================================
|
||||
// MapStruct
|
||||
// ====================================================================
|
||||
|
||||
// Tool DTO와
|
||||
// MCI 요청/응답 DTO 사이의 Converter 구현체를
|
||||
// 컴파일 시 자동 생성하기 위해 사용합니다.
|
||||
implementation 'org.mapstruct:mapstruct:1.6.3'
|
||||
|
||||
// MapStruct Converter 구현 클래스를 생성하는
|
||||
// Annotation Processor입니다.
|
||||
annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3'
|
||||
|
||||
|
||||
// ====================================================================
|
||||
// Test
|
||||
// ====================================================================
|
||||
|
||||
// Spring Boot Test / JUnit 5 / Mockito / AssertJ 등
|
||||
// 공통 테스트 환경을 제공합니다.
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
|
||||
// Gradle / IDE 환경에서 JUnit Platform 기반 테스트 실행을 지원합니다.
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
// 리플렉션/MCP Schema 생성 시 메서드 파라미터명을 사용할 수 있도록 보존합니다.
|
||||
|
||||
// ========================================================================
|
||||
// Java Compile Options
|
||||
// ========================================================================
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
|
||||
// Reflection 및 MCP Schema 생성 시
|
||||
// Java 메서드의 실제 파라미터명을 사용할 수 있도록
|
||||
// 컴파일 결과에 파라미터 이름을 보존합니다.
|
||||
options.compilerArgs << '-parameters'
|
||||
|
||||
// MapStruct 구현체를 Spring Bean으로 생성해 생성자 주입으로 사용할 수 있게 합니다.
|
||||
// MapStruct가 생성하는 Converter 구현 클래스를
|
||||
// Spring Bean(@Component)으로 생성합니다.
|
||||
//
|
||||
// 이를 통해 생성자 주입 등의 방식으로 사용할 수 있습니다.
|
||||
options.compilerArgs << '-Amapstruct.defaultComponentModel=spring'
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
// JUnit 5 테스트 플랫폼을 사용합니다.
|
||||
|
||||
// ========================================================================
|
||||
// Test Configuration
|
||||
// ========================================================================
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
|
||||
// 모든 하위 모듈에서 JUnit 5 Platform을 사용합니다.
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
// Tool 이름 중복 검사 프로그램이 포함된 공통 라이브러리 모듈입니다.
|
||||
def toolCoreProject = project(':dap-was-lib')
|
||||
|
||||
// 전체 Tool Pod의 @McpTool(name) 중복을 배포 산출물 생성 전에 차단합니다.
|
||||
tasks.register('validateMcpToolNames', JavaExec) {
|
||||
group = 'verification'
|
||||
description = 'Checks duplicate @McpTool names across all Tool modules before packaging.'
|
||||
|
||||
// 검사 Runner를 실행하기 전에 dap-was-lib 클래스를 먼저 컴파일합니다.
|
||||
dependsOn toolCoreProject.tasks.named('classes')
|
||||
classpath = toolCoreProject.sourceSets.main.runtimeClasspath
|
||||
mainClass.set('io.shinhanlife.dap.lib.validation.McpToolNameValidationRunner')
|
||||
args rootProject.projectDir.absolutePath
|
||||
}
|
||||
|
||||
tasks.register('validateToolSchemaV17', JavaExec) {
|
||||
group = 'verification'
|
||||
description = 'Validates BC-DAB-STD-003 V17 definitions for every @McpTool.'
|
||||
dependsOn toolCoreProject.tasks.named('classes')
|
||||
classpath = toolCoreProject.sourceSets.main.runtimeClasspath
|
||||
mainClass.set('io.shinhanlife.dap.lib.validation.ToolSchemaV17ValidationRunner')
|
||||
args rootProject.projectDir.absolutePath
|
||||
}
|
||||
|
||||
subprojects {
|
||||
// 배포용 Spring Boot JAR 생성 전에 Tool 이름 중복 검증을 강제합니다.
|
||||
tasks.matching { it.name == 'bootJar' }.configureEach {
|
||||
dependsOn rootProject.tasks.named('validateMcpToolNames')
|
||||
dependsOn rootProject.tasks.named('validateToolSchemaV17')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
FROM eclipse-temurin:21-jre-alpine
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache tzdata
|
||||
ENV TZ=Asia/Seoul
|
||||
COPY dap-was-cus/build/libs/*-SNAPSHOT.jar app.jar
|
||||
EXPOSE 8084
|
||||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
plugins {
|
||||
// OTH Tool Pod를 독립 실행 가능한 Spring Boot JAR로 생성합니다.
|
||||
id 'org.springframework.boot'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// MCP Server, Tool 공통 처리, MCI/EAI 연동 기반은 dap-was-lib에서 상속합니다.
|
||||
implementation project(':dap-was-lib')
|
||||
implementation 'org.apache.poi:poi-ooxml:5.3.0'
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.crm.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
|
||||
@Data
|
||||
public class CrmToolRequest {
|
||||
@McpToolParam(description = "업무 대상 식별자", required = false)
|
||||
private String subjectId;
|
||||
|
||||
@McpToolParam(description = "고객 식별자", required = false)
|
||||
private String customerId;
|
||||
|
||||
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
|
||||
private String content;
|
||||
|
||||
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
|
||||
private String value;
|
||||
|
||||
@McpToolParam(description = "담당자 식별자", required = false)
|
||||
private String assigneeId;
|
||||
|
||||
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
|
||||
private String startDate;
|
||||
|
||||
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
|
||||
private String endDate;
|
||||
|
||||
@McpToolParam(description = "페이지 번호", required = false)
|
||||
private Integer page;
|
||||
|
||||
@McpToolParam(description = "페이지 크기", required = false)
|
||||
private Integer size;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.crm.dto;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CrmToolResponse {
|
||||
private String toolName;
|
||||
private String category;
|
||||
private String referenceId;
|
||||
private String status;
|
||||
private String summary;
|
||||
private String processedAt;
|
||||
private List<String> details;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.crm.usecase;
|
||||
|
||||
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolResponse;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
|
||||
public interface CrmToolUseCase {
|
||||
@McpTool(name = "crm_customer_search", title = "고객 통합 조회", description = "고객 통합 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_SEARCH")
|
||||
CrmToolResponse searchCustomers(CrmToolRequest request);
|
||||
@McpTool(name = "crm_customer_detail", title = "고객 상세 정보 조회", description = "고객 상세 정보 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_DETAIL")
|
||||
CrmToolResponse getCustomerDetail(CrmToolRequest request);
|
||||
@McpTool(name = "crm_customer_create", title = "고객 정보 등록", description = "고객 정보 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_CREATE")
|
||||
CrmToolResponse createCustomer(CrmToolRequest request);
|
||||
@McpTool(name = "crm_customer_update", title = "고객 정보 수정", description = "고객 정보 수정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_UPDATE")
|
||||
CrmToolResponse updateCustomer(CrmToolRequest request);
|
||||
@McpTool(name = "crm_customer_duplicate_check", title = "고객 중복 여부 확인", description = "고객 중복 여부 확인 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CUSTOMER_DUPLICATE_CHECK")
|
||||
CrmToolResponse checkDuplicateCustomer(CrmToolRequest request);
|
||||
@McpTool(name = "crm_consultation_history", title = "고객 상담 이력 조회", description = "고객 상담 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSULTATION_HISTORY")
|
||||
CrmToolResponse getConsultationHistory(CrmToolRequest request);
|
||||
@McpTool(name = "crm_consultation_register", title = "고객 상담 이력 등록", description = "고객 상담 이력 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSULTATION_REGISTER")
|
||||
CrmToolResponse registerConsultation(CrmToolRequest request);
|
||||
@McpTool(name = "crm_contact_history", title = "고객 접촉 이력 조회", description = "고객 접촉 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONTACT_HISTORY")
|
||||
CrmToolResponse getContactHistory(CrmToolRequest request);
|
||||
@McpTool(name = "crm_contact_register", title = "고객 접촉 이력 등록", description = "고객 접촉 이력 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONTACT_REGISTER")
|
||||
CrmToolResponse registerContact(CrmToolRequest request);
|
||||
@McpTool(name = "crm_grade_detail", title = "고객 등급 조회", description = "고객 등급 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_GRADE_DETAIL")
|
||||
CrmToolResponse getCustomerGrade(CrmToolRequest request);
|
||||
@McpTool(name = "crm_grade_change", title = "고객 등급 변경", description = "고객 등급 변경 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_GRADE_CHANGE")
|
||||
CrmToolResponse changeCustomerGrade(CrmToolRequest request);
|
||||
@McpTool(name = "crm_segment_detail", title = "고객 세그먼트 조회", description = "고객 세그먼트 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_SEGMENT_DETAIL")
|
||||
CrmToolResponse getCustomerSegment(CrmToolRequest request);
|
||||
@McpTool(name = "crm_tag_manage", title = "고객 태그 관리", description = "고객 태그 관리 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_TAG_MANAGE")
|
||||
CrmToolResponse manageCustomerTags(CrmToolRequest request);
|
||||
@McpTool(name = "crm_consent_detail", title = "고객 동의 정보 조회", description = "고객 동의 정보 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSENT_DETAIL")
|
||||
CrmToolResponse getCustomerConsent(CrmToolRequest request);
|
||||
@McpTool(name = "crm_consent_change", title = "고객 동의 정보 변경", description = "고객 동의 정보 변경 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_CONSENT_CHANGE")
|
||||
CrmToolResponse changeCustomerConsent(CrmToolRequest request);
|
||||
@McpTool(name = "crm_owner_assign", title = "고객 담당자 배정", description = "고객 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "crm", mappingId = "DIRECT_CRM_OWNER_ASSIGN")
|
||||
CrmToolResponse assignCustomerOwner(CrmToolRequest request);
|
||||
@McpTool(name = "crm_activity_status", title = "고객 활동 현황 조회", description = "고객 활동 현황 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "crm", mappingId = "DIRECT_CRM_ACTIVITY_STATUS")
|
||||
CrmToolResponse getCustomerActivityStatus(CrmToolRequest request);
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.crm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.crm.dto.CrmToolResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.crm.usecase.CrmToolUseCase;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CrmToolUseCaseImpl implements CrmToolUseCase {
|
||||
@Override
|
||||
public CrmToolResponse searchCustomers(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_customer_search", "고객 통합 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getCustomerDetail(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_customer_detail", "고객 상세 정보 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse createCustomer(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_customer_create", "고객 정보 등록");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse updateCustomer(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_customer_update", "고객 정보 수정");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse checkDuplicateCustomer(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_customer_duplicate_check", "고객 중복 여부 확인");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getConsultationHistory(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_consultation_history", "고객 상담 이력 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse registerConsultation(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_consultation_register", "고객 상담 이력 등록");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getContactHistory(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_contact_history", "고객 접촉 이력 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse registerContact(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_contact_register", "고객 접촉 이력 등록");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getCustomerGrade(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_grade_detail", "고객 등급 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse changeCustomerGrade(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_grade_change", "고객 등급 변경");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getCustomerSegment(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_segment_detail", "고객 세그먼트 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse manageCustomerTags(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_tag_manage", "고객 태그 관리");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getCustomerConsent(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_consent_detail", "고객 동의 정보 조회");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse changeCustomerConsent(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_consent_change", "고객 동의 정보 변경");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse assignCustomerOwner(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_owner_assign", "고객 담당자 배정");
|
||||
}
|
||||
@Override
|
||||
public CrmToolResponse getCustomerActivityStatus(CrmToolRequest request) {
|
||||
return mockResponse(request, "crm_activity_status", "고객 활동 현황 조회");
|
||||
}
|
||||
private CrmToolResponse mockResponse(CrmToolRequest request, String toolName, String title) {
|
||||
CrmToolResponse response = new CrmToolResponse();
|
||||
response.setToolName(toolName);
|
||||
response.setCategory("CRM");
|
||||
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "CRM-000001");
|
||||
response.setStatus("정상");
|
||||
response.setSummary(title + " 처리 결과");
|
||||
response.setProcessedAt(LocalDateTime.now().toString());
|
||||
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
|
||||
return response;
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.isBlank();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.voc.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
|
||||
@Data
|
||||
public class VocToolRequest {
|
||||
@McpToolParam(description = "업무 대상 식별자", required = false)
|
||||
private String subjectId;
|
||||
|
||||
@McpToolParam(description = "고객 식별자", required = false)
|
||||
private String customerId;
|
||||
|
||||
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
|
||||
private String content;
|
||||
|
||||
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
|
||||
private String value;
|
||||
|
||||
@McpToolParam(description = "담당자 식별자", required = false)
|
||||
private String assigneeId;
|
||||
|
||||
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
|
||||
private String startDate;
|
||||
|
||||
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
|
||||
private String endDate;
|
||||
|
||||
@McpToolParam(description = "페이지 번호", required = false)
|
||||
private Integer page;
|
||||
|
||||
@McpToolParam(description = "페이지 크기", required = false)
|
||||
private Integer size;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.voc.dto;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VocToolResponse {
|
||||
private String toolName;
|
||||
private String category;
|
||||
private String referenceId;
|
||||
private String status;
|
||||
private String summary;
|
||||
private String processedAt;
|
||||
private List<String> details;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.voc.usecase;
|
||||
|
||||
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolResponse;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
|
||||
public interface VocToolUseCase {
|
||||
@McpTool(name = "voc_register", title = "VOC 접수 등록", description = "VOC 접수 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_REGISTER")
|
||||
VocToolResponse registerVoc(VocToolRequest request);
|
||||
@McpTool(name = "voc_detail", title = "VOC 상세 조회", description = "VOC 상세 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_DETAIL")
|
||||
VocToolResponse getVocDetail(VocToolRequest request);
|
||||
@McpTool(name = "voc_search", title = "VOC 목록 검색", description = "VOC 목록 검색 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_SEARCH")
|
||||
VocToolResponse searchVocs(VocToolRequest request);
|
||||
@McpTool(name = "voc_update", title = "VOC 내용 수정", description = "VOC 내용 수정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_UPDATE")
|
||||
VocToolResponse updateVoc(VocToolRequest request);
|
||||
@McpTool(name = "voc_assign", title = "VOC 담당자 배정", description = "VOC 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_ASSIGN")
|
||||
VocToolResponse assignVocOwner(VocToolRequest request);
|
||||
@McpTool(name = "voc_change_status", title = "VOC 처리 상태 변경", description = "VOC 처리 상태 변경 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_CHANGE_STATUS")
|
||||
VocToolResponse changeVocStatus(VocToolRequest request);
|
||||
@McpTool(name = "voc_register_result", title = "VOC 처리 결과 등록", description = "VOC 처리 결과 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_REGISTER_RESULT")
|
||||
VocToolResponse registerVocResult(VocToolRequest request);
|
||||
@McpTool(name = "voc_send_reply", title = "VOC 답변 발송", description = "VOC 답변 발송 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_SEND_REPLY")
|
||||
VocToolResponse sendVocReply(VocToolRequest request);
|
||||
@McpTool(name = "voc_transfer", title = "VOC 이관 처리", description = "VOC 이관 처리 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_TRANSFER")
|
||||
VocToolResponse transferVoc(VocToolRequest request);
|
||||
@McpTool(name = "voc_set_priority", title = "VOC 우선순위 설정", description = "VOC 우선순위 설정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_SET_PRIORITY")
|
||||
VocToolResponse setVocPriority(VocToolRequest request);
|
||||
@McpTool(name = "voc_classify_type", title = "VOC 유형 분류", description = "VOC 유형 분류 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_CLASSIFY_TYPE")
|
||||
VocToolResponse classifyVocType(VocToolRequest request);
|
||||
@McpTool(name = "voc_attachments", title = "VOC 첨부파일 조회", description = "VOC 첨부파일 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_ATTACHMENTS")
|
||||
VocToolResponse getVocAttachments(VocToolRequest request);
|
||||
@McpTool(name = "voc_customer_history", title = "고객별 VOC 이력 조회", description = "고객별 VOC 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_CUSTOMER_HISTORY")
|
||||
VocToolResponse getCustomerVocHistory(VocToolRequest request);
|
||||
@McpTool(name = "voc_detect_duplicate", title = "중복 VOC 탐지", description = "중복 VOC 탐지 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_DETECT_DUPLICATE")
|
||||
VocToolResponse detectDuplicateVoc(VocToolRequest request);
|
||||
@McpTool(name = "voc_urgent_list", title = "긴급 VOC 목록 조회", description = "긴급 VOC 목록 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_URGENT_LIST")
|
||||
VocToolResponse getUrgentVocs(VocToolRequest request);
|
||||
@McpTool(name = "voc_extend_due_date", title = "VOC 처리 기한 연장", description = "VOC 처리 기한 연장 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "voc", mappingId = "DIRECT_VOC_EXTEND_DUE_DATE")
|
||||
VocToolResponse extendVocDueDate(VocToolRequest request);
|
||||
@McpTool(name = "voc_statistics", title = "VOC 통계 조회", description = "VOC 통계 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "voc", mappingId = "DIRECT_VOC_STATISTICS")
|
||||
VocToolResponse getVocStatistics(VocToolRequest request);
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.voc.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.voc.dto.VocToolResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.voc.usecase.VocToolUseCase;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class VocToolUseCaseImpl implements VocToolUseCase {
|
||||
@Override
|
||||
public VocToolResponse registerVoc(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_register", "VOC 접수 등록");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse getVocDetail(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_detail", "VOC 상세 조회");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse searchVocs(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_search", "VOC 목록 검색");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse updateVoc(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_update", "VOC 내용 수정");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse assignVocOwner(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_assign", "VOC 담당자 배정");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse changeVocStatus(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_change_status", "VOC 처리 상태 변경");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse registerVocResult(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_register_result", "VOC 처리 결과 등록");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse sendVocReply(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_send_reply", "VOC 답변 발송");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse transferVoc(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_transfer", "VOC 이관 처리");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse setVocPriority(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_set_priority", "VOC 우선순위 설정");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse classifyVocType(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_classify_type", "VOC 유형 분류");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse getVocAttachments(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_attachments", "VOC 첨부파일 조회");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse getCustomerVocHistory(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_customer_history", "고객별 VOC 이력 조회");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse detectDuplicateVoc(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_detect_duplicate", "중복 VOC 탐지");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse getUrgentVocs(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_urgent_list", "긴급 VOC 목록 조회");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse extendVocDueDate(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_extend_due_date", "VOC 처리 기한 연장");
|
||||
}
|
||||
@Override
|
||||
public VocToolResponse getVocStatistics(VocToolRequest request) {
|
||||
return mockResponse(request, "voc_statistics", "VOC 통계 조회");
|
||||
}
|
||||
private VocToolResponse mockResponse(VocToolRequest request, String toolName, String title) {
|
||||
VocToolResponse response = new VocToolResponse();
|
||||
response.setToolName(toolName);
|
||||
response.setCategory("VOC");
|
||||
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "VOC-000001");
|
||||
response.setStatus("정상");
|
||||
response.setSummary(title + " 처리 결과");
|
||||
response.setProcessedAt(LocalDateTime.now().toString());
|
||||
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
|
||||
return response;
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.isBlank();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.wcm.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springaicommunity.mcp.annotation.McpToolParam;
|
||||
|
||||
@Data
|
||||
public class WcmToolRequest {
|
||||
@McpToolParam(description = "업무 대상 식별자", required = false)
|
||||
private String subjectId;
|
||||
|
||||
@McpToolParam(description = "고객 식별자", required = false)
|
||||
private String customerId;
|
||||
|
||||
@McpToolParam(description = "검색어 또는 처리 내용", required = false)
|
||||
private String content;
|
||||
|
||||
@McpToolParam(description = "상태, 유형, 등급 또는 처리 값", required = false)
|
||||
private String value;
|
||||
|
||||
@McpToolParam(description = "담당자 식별자", required = false)
|
||||
private String assigneeId;
|
||||
|
||||
@McpToolParam(description = "조회 시작일(YYYY-MM-DD)", required = false)
|
||||
private String startDate;
|
||||
|
||||
@McpToolParam(description = "조회 종료일 또는 처리 예정일(YYYY-MM-DD)", required = false)
|
||||
private String endDate;
|
||||
|
||||
@McpToolParam(description = "페이지 번호", required = false)
|
||||
private Integer page;
|
||||
|
||||
@McpToolParam(description = "페이지 크기", required = false)
|
||||
private Integer size;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.wcm.dto;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WcmToolResponse {
|
||||
private String toolName;
|
||||
private String category;
|
||||
private String referenceId;
|
||||
private String status;
|
||||
private String summary;
|
||||
private String processedAt;
|
||||
private List<String> details;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.wcm.usecase;
|
||||
|
||||
import io.shinhanlife.dap.lib.annotation.GrowToolHint;
|
||||
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolResponse;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
|
||||
public interface WcmToolUseCase {
|
||||
@McpTool(name = "wcm_content_list", title = "웹 콘텐츠 목록 조회", description = "웹 콘텐츠 목록 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_LIST")
|
||||
WcmToolResponse getContentList(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_detail", title = "웹 콘텐츠 상세 조회", description = "웹 콘텐츠 상세 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_DETAIL")
|
||||
WcmToolResponse getContentDetail(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_create", title = "웹 콘텐츠 등록", description = "웹 콘텐츠 등록 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_CREATE")
|
||||
WcmToolResponse createContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_update", title = "웹 콘텐츠 수정", description = "웹 콘텐츠 수정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_UPDATE")
|
||||
WcmToolResponse updateContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_delete", title = "웹 콘텐츠 삭제", description = "웹 콘텐츠 삭제 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_DELETE")
|
||||
WcmToolResponse deleteContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_copy", title = "웹 콘텐츠 복사", description = "웹 콘텐츠 복사 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_COPY")
|
||||
WcmToolResponse copyContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_preview", title = "웹 콘텐츠 미리보기", description = "웹 콘텐츠 미리보기 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_PREVIEW")
|
||||
WcmToolResponse previewContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_publish", title = "웹 콘텐츠 게시", description = "웹 콘텐츠 게시 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_PUBLISH")
|
||||
WcmToolResponse publishContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_unpublish", title = "웹 콘텐츠 게시 중지", description = "웹 콘텐츠 게시 중지 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_UNPUBLISH")
|
||||
WcmToolResponse unpublishContent(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_schedule_publish", title = "웹 콘텐츠 예약 게시", description = "웹 콘텐츠 예약 게시 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_SCHEDULE_PUBLISH")
|
||||
WcmToolResponse scheduleContentPublish(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_request_approval", title = "웹 콘텐츠 승인 요청", description = "웹 콘텐츠 승인 요청 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_REQUEST_APPROVAL")
|
||||
WcmToolResponse requestContentApproval(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_review_approval", title = "웹 콘텐츠 승인·반려", description = "웹 콘텐츠 승인·반려 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_REVIEW_APPROVAL")
|
||||
WcmToolResponse reviewContentApproval(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_version_history", title = "웹 콘텐츠 버전 이력 조회", description = "웹 콘텐츠 버전 이력 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_VERSION_HISTORY")
|
||||
WcmToolResponse getContentVersionHistory(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_content_restore_version", title = "웹 콘텐츠 이전 버전 복원", description = "웹 콘텐츠 이전 버전 복원 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_CONTENT_RESTORE_VERSION")
|
||||
WcmToolResponse restoreContentVersion(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_metadata_detail", title = "콘텐츠 메타데이터 조회", description = "콘텐츠 메타데이터 조회 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = false, categoryKey = "wcm", mappingId = "DIRECT_WCM_METADATA_DETAIL")
|
||||
WcmToolResponse getContentMetadata(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_metadata_upsert", title = "콘텐츠 메타데이터 등록·수정", description = "콘텐츠 메타데이터 등록·수정 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_METADATA_UPSERT")
|
||||
WcmToolResponse upsertContentMetadata(WcmToolRequest request);
|
||||
@McpTool(name = "wcm_taxonomy_manage", title = "콘텐츠 카테고리·태그 관리", description = "콘텐츠 카테고리·태그 관리 기능을 안전한 모의 데이터로 제공합니다.")
|
||||
@GrowToolHint(requiresApproval = true, categoryKey = "wcm", mappingId = "DIRECT_WCM_TAXONOMY_MANAGE")
|
||||
WcmToolResponse manageContentTaxonomy(WcmToolRequest request);
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.biz.wcm.usecase.impl;
|
||||
|
||||
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolRequest;
|
||||
import io.shinhanlife.dap.mcc.biz.wcm.dto.WcmToolResponse;
|
||||
import io.shinhanlife.dap.mcc.biz.wcm.usecase.WcmToolUseCase;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class WcmToolUseCaseImpl implements WcmToolUseCase {
|
||||
@Override
|
||||
public WcmToolResponse getContentList(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_list", "웹 콘텐츠 목록 조회");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse getContentDetail(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_detail", "웹 콘텐츠 상세 조회");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse createContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_create", "웹 콘텐츠 등록");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse updateContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_update", "웹 콘텐츠 수정");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse deleteContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_delete", "웹 콘텐츠 삭제");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse copyContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_copy", "웹 콘텐츠 복사");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse previewContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_preview", "웹 콘텐츠 미리보기");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse publishContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_publish", "웹 콘텐츠 게시");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse unpublishContent(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_unpublish", "웹 콘텐츠 게시 중지");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse scheduleContentPublish(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_schedule_publish", "웹 콘텐츠 예약 게시");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse requestContentApproval(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_request_approval", "웹 콘텐츠 승인 요청");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse reviewContentApproval(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_review_approval", "웹 콘텐츠 승인·반려");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse getContentVersionHistory(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_version_history", "웹 콘텐츠 버전 이력 조회");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse restoreContentVersion(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_content_restore_version", "웹 콘텐츠 이전 버전 복원");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse getContentMetadata(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_metadata_detail", "콘텐츠 메타데이터 조회");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse upsertContentMetadata(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_metadata_upsert", "콘텐츠 메타데이터 등록·수정");
|
||||
}
|
||||
@Override
|
||||
public WcmToolResponse manageContentTaxonomy(WcmToolRequest request) {
|
||||
return mockResponse(request, "wcm_taxonomy_manage", "콘텐츠 카테고리·태그 관리");
|
||||
}
|
||||
private WcmToolResponse mockResponse(WcmToolRequest request, String toolName, String title) {
|
||||
WcmToolResponse response = new WcmToolResponse();
|
||||
response.setToolName(toolName);
|
||||
response.setCategory("WCMS");
|
||||
response.setReferenceId(request != null && hasText(request.getSubjectId()) ? request.getSubjectId() : "WCMS-000001");
|
||||
response.setStatus("정상");
|
||||
response.setSummary(title + " 처리 결과");
|
||||
response.setProcessedAt(LocalDateTime.now().toString());
|
||||
response.setDetails(List.of(title + " 모의 상세 정보", "외부 시스템을 변경하지 않는 샘플 응답"));
|
||||
return response;
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.isBlank();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.shinhanlife.dap.mcc.cus;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcc.cus
|
||||
* @className DapWasCusApplication
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import io.shinhanlife.dap.lib.mcp.ToolMcpServerConfiguration;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib"})
|
||||
@ConfigurationPropertiesScan(basePackages = {"io.shinhanlife.dap.mcc", "io.shinhanlife.dap.lib"})
|
||||
@EnableCaching
|
||||
@Import(ToolMcpServerConfiguration.class)
|
||||
public class DapWasCusApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DapWasCusApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# OCI 클라우드 개발 환경 전용 설정
|
||||
server:
|
||||
port: ${PORT:8084}
|
||||
|
||||
axhub:
|
||||
gateway:
|
||||
url: https://axhubmcp.devjun.net
|
||||
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: dev
|
||||
import:
|
||||
- classpath:glow/application-glow.yml
|
||||
- classpath:glow/application-glow-dev.yml
|
||||
@@ -1,32 +0,0 @@
|
||||
# Local 환경 전용 설정 (H2 메모리 DB 등)
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: local
|
||||
import:
|
||||
- classpath:glow/application-glow.yml
|
||||
- classpath:glow/application-glow-local.yml
|
||||
datasource:
|
||||
url: jdbc:p6spy:h2:mem:testdb;DB_CLOSE_DELAY=-1;
|
||||
driverClassName: com.p6spy.engine.spy.P6SpyDriver
|
||||
username: sa
|
||||
password: password
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
|
||||
mcp:
|
||||
security:
|
||||
tenant-domains:
|
||||
mcp-client-1: CUSTOMER,COMMON
|
||||
mcp-client-2: ALL
|
||||
|
||||
axhub:
|
||||
gateway:
|
||||
url: http://localhost:8081
|
||||
tool:
|
||||
url: ${AXHUB_TOOL_URL:http://localhost:${server.port}}
|
||||
|
||||
sol:
|
||||
req-detail:
|
||||
mock-enabled: true
|
||||
@@ -1,16 +0,0 @@
|
||||
server:
|
||||
port: ${PORT:8084}
|
||||
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: prod
|
||||
import:
|
||||
- classpath:glow/application-glow.yml
|
||||
- classpath:glow/application-glow-prod.yml
|
||||
|
||||
axhub:
|
||||
gateway:
|
||||
url: ${AXHUB_GATEWAY_URL}
|
||||
tool:
|
||||
url: ${AXHUB_TOOL_URL}
|
||||
@@ -1,16 +0,0 @@
|
||||
server:
|
||||
port: ${PORT:8084}
|
||||
|
||||
spring:
|
||||
config:
|
||||
activate:
|
||||
on-profile: test
|
||||
import:
|
||||
- classpath:glow/application-glow.yml
|
||||
- classpath:glow/application-glow-test.yml
|
||||
|
||||
axhub:
|
||||
gateway:
|
||||
url: ${AXHUB_GATEWAY_URL}
|
||||
tool:
|
||||
url: ${AXHUB_TOOL_URL}
|
||||
@@ -1,20 +0,0 @@
|
||||
server:
|
||||
port: 8084
|
||||
spring:
|
||||
application:
|
||||
name: dap-was-cus
|
||||
profiles:
|
||||
active: local
|
||||
logging:
|
||||
level:
|
||||
org.apache.kafka: ERROR
|
||||
mcp:
|
||||
namespace: ""
|
||||
manifest:
|
||||
bundle-id: was-cus
|
||||
# Set the AA-assigned prefix before MCP pull activation (for example: cus.).
|
||||
name-prefix: ""
|
||||
security:
|
||||
api-key: ${TOOL_SERVER_API_KEY:tool-server-key}
|
||||
tenant-domains:
|
||||
TESTER-DEV: ALL
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<!-- 1. 로그 패턴 설정 (MDC traceId 포함) -->
|
||||
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
|
||||
|
||||
<!-- 2. 콘솔(Console) 출력 설정 (로컬 개발용) -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 3. 파일(File) 출력 설정 (서버 운영용) -->
|
||||
<!-- Logback에서 시스템 Hostname을 가져오기 위한 설정 -->
|
||||
<property name="HOSTNAME" value="${HOSTNAME}" />
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>/swlog/dap-was-cus/A01/${HOSTNAME}_A01.log</file> <!-- 현재 로그가 쌓이는 파일 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- 매일 자정에 날짜를 붙여서 지난 로그를 분리 저장 -->
|
||||
<fileNamePattern>/swlog/dap-was-cus/A01/${HOSTNAME}_A01_%d{yyyyMMdd}.%i.log</fileNamePattern>
|
||||
<!-- 개별 로그 파일 크기를 100MB로 제한하고, 전체 보관 일수는 30일, 총 로그 누적 용량은 1GB로 제한 -->
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
<totalSizeCap>1GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 4. 기본 로깅 레벨 설정 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
<!-- 5. 우리 프로젝트 패키지는 디버그 레벨까지 상세히 보기 -->
|
||||
<logger name="io.shinhanlife" level="DEBUG" />
|
||||
</configuration>
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"resultCode" : "SUCCESS",
|
||||
"data" : "[{\"date\":\"2024-01-05\",\"message\":\"안내 내용\"}]"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"resultCode" : "SUCCESS",
|
||||
"claimId" : "CLM20230001"
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_activity_status
|
||||
display_name: 고객 활동 현황 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 활동 현황 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 활동 현황 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 활동 현황 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 활동 현황 조회 해줘", "고객 활동 현황 조회 결과를 알려줘", "고객 활동 현황 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_consent_change
|
||||
display_name: 고객 동의 정보 변경
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 동의 정보 변경 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 동의 정보 변경 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 동의 정보 변경 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 동의 정보 변경 해줘", "고객 동의 정보 변경 결과를 알려줘", "고객 동의 정보 변경 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_consent_detail
|
||||
display_name: 고객 동의 정보 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 동의 정보 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 동의 정보 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 동의 정보 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 동의 정보 조회 해줘", "고객 동의 정보 조회 결과를 알려줘", "고객 동의 정보 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_consultation_history
|
||||
display_name: 고객 상담 이력 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 상담 이력 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 상담 이력 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 상담 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 상담 이력 조회 해줘", "고객 상담 이력 조회 결과를 알려줘", "고객 상담 이력 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_consultation_register
|
||||
display_name: 고객 상담 이력 등록
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 상담 이력 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 상담 이력 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 상담 이력 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 상담 이력 등록 해줘", "고객 상담 이력 등록 결과를 알려줘", "고객 상담 이력 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_contact_history
|
||||
display_name: 고객 접촉 이력 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 접촉 이력 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 접촉 이력 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 접촉 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 접촉 이력 조회 해줘", "고객 접촉 이력 조회 결과를 알려줘", "고객 접촉 이력 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_contact_register
|
||||
display_name: 고객 접촉 이력 등록
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 접촉 이력 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 접촉 이력 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 접촉 이력 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 접촉 이력 등록 해줘", "고객 접촉 이력 등록 결과를 알려줘", "고객 접촉 이력 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_customer_create
|
||||
display_name: 고객 정보 등록
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 정보 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 정보 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 정보 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 정보 등록 해줘", "고객 정보 등록 결과를 알려줘", "고객 정보 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_customer_detail
|
||||
display_name: 고객 상세 정보 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 상세 정보 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 상세 정보 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 상세 정보 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 상세 정보 조회 해줘", "고객 상세 정보 조회 결과를 알려줘", "고객 상세 정보 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_customer_duplicate_check
|
||||
display_name: 고객 중복 여부 확인
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 중복 여부 확인 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 중복 여부 확인 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 중복 여부 확인 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 중복 여부 확인 해줘", "고객 중복 여부 확인 결과를 알려줘", "고객 중복 여부 확인 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_customer_search
|
||||
display_name: 고객 통합 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 통합 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 통합 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 통합 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 통합 조회 해줘", "고객 통합 조회 결과를 알려줘", "고객 통합 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_customer_update
|
||||
display_name: 고객 정보 수정
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 정보 수정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 정보 수정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 정보 수정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 정보 수정 해줘", "고객 정보 수정 결과를 알려줘", "고객 정보 수정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_grade_change
|
||||
display_name: 고객 등급 변경
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 등급 변경 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 등급 변경 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 등급 변경 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 등급 변경 해줘", "고객 등급 변경 결과를 알려줘", "고객 등급 변경 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_grade_detail
|
||||
display_name: 고객 등급 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 등급 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 등급 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 등급 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 등급 조회 해줘", "고객 등급 조회 결과를 알려줘", "고객 등급 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_owner_assign
|
||||
display_name: 고객 담당자 배정
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 담당자 배정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 담당자 배정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 담당자 배정 해줘", "고객 담당자 배정 결과를 알려줘", "고객 담당자 배정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_segment_detail
|
||||
display_name: 고객 세그먼트 조회
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 세그먼트 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 세그먼트 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 세그먼트 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 세그먼트 조회 해줘", "고객 세그먼트 조회 결과를 알려줘", "고객 세그먼트 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: crm_tag_manage
|
||||
display_name: 고객 태그 관리
|
||||
version: 1.0.0
|
||||
category_key: crm
|
||||
description:
|
||||
function: 고객 태그 관리 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객 태그 관리 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객 태그 관리 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객 태그 관리 해줘", "고객 태그 관리 결과를 알려줘", "고객 태그 관리 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [crm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_assign
|
||||
display_name: VOC 담당자 배정
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 담당자 배정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 담당자 배정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 담당자 배정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 담당자 배정 해줘", "VOC 담당자 배정 결과를 알려줘", "VOC 담당자 배정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_attachments
|
||||
display_name: VOC 첨부파일 조회
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 첨부파일 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 첨부파일 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 첨부파일 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 첨부파일 조회 해줘", "VOC 첨부파일 조회 결과를 알려줘", "VOC 첨부파일 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_change_status
|
||||
display_name: VOC 처리 상태 변경
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 처리 상태 변경 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 처리 상태 변경 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 처리 상태 변경 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 처리 상태 변경 해줘", "VOC 처리 상태 변경 결과를 알려줘", "VOC 처리 상태 변경 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_classify_type
|
||||
display_name: VOC 유형 분류
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 유형 분류 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 유형 분류 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 유형 분류 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 유형 분류 해줘", "VOC 유형 분류 결과를 알려줘", "VOC 유형 분류 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_customer_history
|
||||
display_name: 고객별 VOC 이력 조회
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: 고객별 VOC 이력 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 고객별 VOC 이력 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 고객별 VOC 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["고객별 VOC 이력 조회 해줘", "고객별 VOC 이력 조회 결과를 알려줘", "고객별 VOC 이력 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_detail
|
||||
display_name: VOC 상세 조회
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 상세 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 상세 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 상세 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 상세 조회 해줘", "VOC 상세 조회 결과를 알려줘", "VOC 상세 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_detect_duplicate
|
||||
display_name: 중복 VOC 탐지
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: 중복 VOC 탐지 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 중복 VOC 탐지 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 중복 VOC 탐지 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["중복 VOC 탐지 해줘", "중복 VOC 탐지 결과를 알려줘", "중복 VOC 탐지 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_extend_due_date
|
||||
display_name: VOC 처리 기한 연장
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 처리 기한 연장 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 처리 기한 연장 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 처리 기한 연장 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 처리 기한 연장 해줘", "VOC 처리 기한 연장 결과를 알려줘", "VOC 처리 기한 연장 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_register
|
||||
display_name: VOC 접수 등록
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 접수 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 접수 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 접수 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 접수 등록 해줘", "VOC 접수 등록 결과를 알려줘", "VOC 접수 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_register_result
|
||||
display_name: VOC 처리 결과 등록
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 처리 결과 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 처리 결과 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 처리 결과 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 처리 결과 등록 해줘", "VOC 처리 결과 등록 결과를 알려줘", "VOC 처리 결과 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_search
|
||||
display_name: VOC 목록 검색
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 목록 검색 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 목록 검색 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 목록 검색 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 목록 검색 해줘", "VOC 목록 검색 결과를 알려줘", "VOC 목록 검색 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_send_reply
|
||||
display_name: VOC 답변 발송
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 답변 발송 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 답변 발송 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 답변 발송 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 답변 발송 해줘", "VOC 답변 발송 결과를 알려줘", "VOC 답변 발송 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_set_priority
|
||||
display_name: VOC 우선순위 설정
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 우선순위 설정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 우선순위 설정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 우선순위 설정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 우선순위 설정 해줘", "VOC 우선순위 설정 결과를 알려줘", "VOC 우선순위 설정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_statistics
|
||||
display_name: VOC 통계 조회
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 통계 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 통계 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 통계 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 통계 조회 해줘", "VOC 통계 조회 결과를 알려줘", "VOC 통계 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_transfer
|
||||
display_name: VOC 이관 처리
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 이관 처리 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 이관 처리 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 이관 처리 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 이관 처리 해줘", "VOC 이관 처리 결과를 알려줘", "VOC 이관 처리 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_update
|
||||
display_name: VOC 내용 수정
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: VOC 내용 수정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 VOC 내용 수정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: VOC 내용 수정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["VOC 내용 수정 해줘", "VOC 내용 수정 결과를 알려줘", "VOC 내용 수정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: voc_urgent_list
|
||||
display_name: 긴급 VOC 목록 조회
|
||||
version: 1.0.0
|
||||
category_key: voc
|
||||
description:
|
||||
function: 긴급 VOC 목록 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 긴급 VOC 목록 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 긴급 VOC 목록 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["긴급 VOC 목록 조회 해줘", "긴급 VOC 목록 조회 결과를 알려줘", "긴급 VOC 목록 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [voc, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_copy
|
||||
display_name: 웹 콘텐츠 복사
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 복사 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 복사 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 복사 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 복사 해줘", "웹 콘텐츠 복사 결과를 알려줘", "웹 콘텐츠 복사 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_create
|
||||
display_name: 웹 콘텐츠 등록
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 등록 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 등록 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 등록 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 등록 해줘", "웹 콘텐츠 등록 결과를 알려줘", "웹 콘텐츠 등록 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: false
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_delete
|
||||
display_name: 웹 콘텐츠 삭제
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 삭제 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 삭제 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 삭제 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 삭제 해줘", "웹 콘텐츠 삭제 결과를 알려줘", "웹 콘텐츠 삭제 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: true
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_detail
|
||||
display_name: 웹 콘텐츠 상세 조회
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 상세 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 상세 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 상세 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 상세 조회 해줘", "웹 콘텐츠 상세 조회 결과를 알려줘", "웹 콘텐츠 상세 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_list
|
||||
display_name: 웹 콘텐츠 목록 조회
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 목록 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 목록 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 목록 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 목록 조회 해줘", "웹 콘텐츠 목록 조회 결과를 알려줘", "웹 콘텐츠 목록 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_preview
|
||||
display_name: 웹 콘텐츠 미리보기
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 미리보기 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 미리보기 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 미리보기 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 미리보기 해줘", "웹 콘텐츠 미리보기 결과를 알려줘", "웹 콘텐츠 미리보기 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_publish
|
||||
display_name: 웹 콘텐츠 게시
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 게시 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 게시 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 게시 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 게시 해줘", "웹 콘텐츠 게시 결과를 알려줘", "웹 콘텐츠 게시 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_request_approval
|
||||
display_name: 웹 콘텐츠 승인 요청
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 승인 요청 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 승인 요청 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 승인 요청 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 승인 요청 해줘", "웹 콘텐츠 승인 요청 결과를 알려줘", "웹 콘텐츠 승인 요청 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_restore_version
|
||||
display_name: 웹 콘텐츠 이전 버전 복원
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 이전 버전 복원 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 이전 버전 복원 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 이전 버전 복원 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 이전 버전 복원 해줘", "웹 콘텐츠 이전 버전 복원 결과를 알려줘", "웹 콘텐츠 이전 버전 복원 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_review_approval
|
||||
display_name: 웹 콘텐츠 승인·반려
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 승인·반려 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 승인·반려 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 승인·반려 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 승인·반려 해줘", "웹 콘텐츠 승인·반려 결과를 알려줘", "웹 콘텐츠 승인·반려 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_schedule_publish
|
||||
display_name: 웹 콘텐츠 예약 게시
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 예약 게시 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 예약 게시 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 예약 게시 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 예약 게시 해줘", "웹 콘텐츠 예약 게시 결과를 알려줘", "웹 콘텐츠 예약 게시 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_unpublish
|
||||
display_name: 웹 콘텐츠 게시 중지
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 게시 중지 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 게시 중지 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 게시 중지 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 게시 중지 해줘", "웹 콘텐츠 게시 중지 결과를 알려줘", "웹 콘텐츠 게시 중지 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_update
|
||||
display_name: 웹 콘텐츠 수정
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 수정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 수정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 수정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 수정 해줘", "웹 콘텐츠 수정 결과를 알려줘", "웹 콘텐츠 수정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_content_version_history
|
||||
display_name: 웹 콘텐츠 버전 이력 조회
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 웹 콘텐츠 버전 이력 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 웹 콘텐츠 버전 이력 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 웹 콘텐츠 버전 이력 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["웹 콘텐츠 버전 이력 조회 해줘", "웹 콘텐츠 버전 이력 조회 결과를 알려줘", "웹 콘텐츠 버전 이력 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_metadata_detail
|
||||
display_name: 콘텐츠 메타데이터 조회
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 콘텐츠 메타데이터 조회 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 콘텐츠 메타데이터 조회 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 정보 변경이나 승인 처리가 필요한 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 조회 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 콘텐츠 메타데이터 조회 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["콘텐츠 메타데이터 조회 해줘", "콘텐츠 메타데이터 조회 결과를 알려줘", "콘텐츠 메타데이터 조회 기능을 실행해줘"]
|
||||
read_only: true
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 조회, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_metadata_upsert
|
||||
display_name: 콘텐츠 메타데이터 등록·수정
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 콘텐츠 메타데이터 등록·수정 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 콘텐츠 메타데이터 등록·수정 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 콘텐츠 메타데이터 등록·수정 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["콘텐츠 메타데이터 등록·수정 해줘", "콘텐츠 메타데이터 등록·수정 결과를 알려줘", "콘텐츠 메타데이터 등록·수정 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,30 +0,0 @@
|
||||
name: wcm_taxonomy_manage
|
||||
display_name: 콘텐츠 카테고리·태그 관리
|
||||
version: 1.0.0
|
||||
category_key: wcm
|
||||
description:
|
||||
function: 콘텐츠 카테고리·태그 관리 기능을 수행합니다.
|
||||
when_to_use: 고객채널 업무에서 콘텐츠 카테고리·태그 관리 기능이 필요할 때 사용합니다.
|
||||
when_not_to_use: 필수 식별자와 변경 내용이 확인되지 않은 경우에는 사용하지 않습니다.
|
||||
io_limits: 입력 범위에 대한 모의 처리 결과만 반환하며 외부 시스템을 직접 변경하지 않습니다.
|
||||
display_description: 콘텐츠 카테고리·태그 관리 기능을 안전한 모의 데이터로 제공합니다.
|
||||
example_queries: ["콘텐츠 카테고리·태그 관리 해줘", "콘텐츠 카테고리·태그 관리 결과를 알려줘", "콘텐츠 카테고리·태그 관리 기능을 실행해줘"]
|
||||
read_only: false
|
||||
destructive: false
|
||||
idempotent: true
|
||||
parameters_schema:
|
||||
type: object
|
||||
properties:
|
||||
subjectId: {type: string, description: 업무 대상 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
customerId: {type: string, description: 고객 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
content: {type: string, description: 검색어 또는 처리 내용, maxLength: 2000}
|
||||
value: {type: string, description: 상태·유형·등급 또는 처리 값, maxLength: 100}
|
||||
assigneeId: {type: string, description: 담당자 식별자, pattern: "^[A-Za-z0-9_-]{3,40}$"}
|
||||
startDate: {type: string, description: 조회 시작일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
endDate: {type: string, description: 조회 종료일 또는 처리 예정일, pattern: "^\\d{4}-\\d{2}-\\d{2}$"}
|
||||
page: {type: integer, description: 페이지 번호, minimum: 0}
|
||||
size: {type: integer, description: 페이지 크기, minimum: 1, maximum: 100}
|
||||
additionalProperties: false
|
||||
tags: [wcm, 고객채널, 처리, mock]
|
||||
required_env_keys: []
|
||||
owner_org: MCP_TOOL
|
||||
@@ -1,60 +0,0 @@
|
||||
plugins {
|
||||
// Gateway와 모든 Tool Pod가 의존하는 공통 라이브러리 모듈입니다.
|
||||
id 'java-library'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// 공통 REST Controller, HTTP Client, 예외 처리 기반입니다.
|
||||
api 'org.springframework.boot:spring-boot-starter-web'
|
||||
|
||||
// Tool Request DTO의 Bean Validation을 지원합니다.
|
||||
api 'org.springframework.boot:spring-boot-starter-validation'
|
||||
|
||||
// Tool Manifest/Registry 캐시 및 Redis 기반 공통 기능을 제공합니다.
|
||||
api 'org.springframework.boot:spring-boot-starter-data-redis'
|
||||
|
||||
// Tool SLA, 로깅, 공통 Aspect를 적용합니다.
|
||||
api 'org.springframework.boot:spring-boot-starter-aop'
|
||||
|
||||
// MCI/DB 연동에 필요한 JDBC 공통 기능입니다.
|
||||
api 'org.springframework.boot:spring-boot-starter-jdbc'
|
||||
|
||||
// Tool 호출의 Circuit Breaker, Rate Limit, Retry 등 복원력 기능입니다.
|
||||
api 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
|
||||
api 'io.github.resilience4j:resilience4j-core:2.2.0'
|
||||
api 'io.github.resilience4j:resilience4j-circuitbreaker:2.2.0'
|
||||
api 'io.github.resilience4j:resilience4j-ratelimiter'
|
||||
api 'io.github.resilience4j:resilience4j-retry:2.2.0'
|
||||
|
||||
// MCI/업무 데이터 접근을 위한 MyBatis 지원입니다.
|
||||
api 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
|
||||
|
||||
// 현재 로컬 테스트 DB 및 SQL 로그 처리에 사용합니다.
|
||||
api 'com.h2database:h2'
|
||||
api 'p6spy:p6spy:3.9.1'
|
||||
|
||||
// Spring Data Redis가 사용하는 Redis Client를 공통 모듈에서 직접 참조합니다.
|
||||
api 'io.lettuce:lettuce-core:6.6.0.RELEASE'
|
||||
|
||||
// MCI XML 전문, JSON Tool Schema/Manifest 처리에 사용합니다.
|
||||
api 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml'
|
||||
api 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
|
||||
api 'com.fasterxml.jackson.core:jackson-databind'
|
||||
// MCP Java SDK 2.0.0의 mcp-json-jackson2가 호출하는 Schema API와 반드시 맞춘다.
|
||||
// 3.x는 Schema.validate(JsonNode) 반환 규격이 달라 런타임 NoSuchMethodError가 발생한다.
|
||||
api 'com.networknt:json-schema-validator:2.0.0'
|
||||
|
||||
// Boot 3.5.11 위에서 MCP Java SDK 2.0.0의 Server/Client와 Servlet 전송 계층을 사용합니다.
|
||||
// Jackson 2 공급자를 명시해 Boot 3의 Jackson 계열과 맞춥니다.
|
||||
api 'io.modelcontextprotocol.sdk:mcp-core'
|
||||
api 'io.modelcontextprotocol.sdk:mcp-json-jackson2'
|
||||
|
||||
// Boot 3.5 호환 Spring AI 어노테이션 API를 유지합니다.
|
||||
api 'org.springaicommunity:mcp-annotations:0.9.0'
|
||||
|
||||
// 이벤트 기반 확장이 필요한 Tool의 공통 Kafka 연동 기능입니다.
|
||||
api 'org.springframework.kafka:spring-kafka:3.2.0'
|
||||
|
||||
// Tool Pod REST API 문서 및 Swagger UI를 제공합니다.
|
||||
api 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.dto
|
||||
* @className ErrorDetail
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
public class ErrorDetail {
|
||||
private int code;
|
||||
private String message;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.dto
|
||||
* @className JsonRpcRequest
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class JsonRpcRequest {
|
||||
private String jsonrpc;
|
||||
private String method;
|
||||
private Params params;
|
||||
private String id;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
// 2. 응답 DTO
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.dto
|
||||
* @className JsonRpcResponse
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonPropertyOrder({"jsonrpc", "result", "error", "id"})
|
||||
public class JsonRpcResponse {
|
||||
public String jsonrpc = "2.0";
|
||||
public Object result;
|
||||
public Object error;
|
||||
public String id;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.dto
|
||||
* @className Params
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Params {
|
||||
private String routingType;
|
||||
private String name;
|
||||
private String interfaceId;
|
||||
private Map<String, Object> data;
|
||||
private List<Map<String, Object>> spec;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.test;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.Map;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Local HTTP mock server for scaffolded HTTP Tools.
|
||||
*
|
||||
* <p>Each Tool Pod returns the JSON generated under
|
||||
* {@code src/main/resources/mock-responses/{toolName}.json}. It is enabled only
|
||||
* when {@code axhub.mock.http.enabled=true}, which the HTTP Scaffold adds to local configuration.</p>
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "axhub.mock.http", name = "enabled", havingValue = "true")
|
||||
@RequestMapping("/api")
|
||||
public class MockEimsHttpServer {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@PostMapping("/mock/http/{toolName:[a-z0-9_-]+}")
|
||||
public ResponseEntity<JsonNode> mockToolHttpResponse(
|
||||
@PathVariable String toolName,
|
||||
@RequestBody(required = false) JsonNode request) {
|
||||
ClassPathResource resource = new ClassPathResource("mock-responses/" + toolName + ".json");
|
||||
if (!resource.exists()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
try {
|
||||
log.info("[MockEimsHttpServer] HTTP mock request. toolName={}, body={}", toolName, request);
|
||||
return ResponseEntity.ok(objectMapper.readTree(resource.getInputStream()));
|
||||
} catch (Exception e) {
|
||||
log.warn("[MockEimsHttpServer] Unable to read mock response. toolName={}", toolName, e);
|
||||
return ResponseEntity.internalServerError().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/gateway")
|
||||
public ResponseEntity<?> mockEimsReceiver(
|
||||
@RequestHeader(value = "X-Trace-Id", required = false) String traceId,
|
||||
@RequestBody Map<String, Object> request) {
|
||||
String interfaceId = String.valueOf(request.getOrDefault("interfaceId", ""));
|
||||
log.info("[MockEimsHttpServer] Legacy gateway mock request. traceId={}, interfaceId={}", traceId, interfaceId);
|
||||
return ResponseEntity.ok(Map.of(
|
||||
"status", "404",
|
||||
"message", "MOCK data is not defined for interfaceId: " + interfaceId));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.util;
|
||||
|
||||
import ch.qos.logback.classic.pattern.MessageConverter;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
|
||||
/**
|
||||
* Logback 커스텀 컨버터
|
||||
* 모든 로그 메시지(%msg)가 파일이나 콘솔에 찍히기 직전에 이 클래스를 거쳐가게 됩니다.
|
||||
* 여기서 PiiMaskingUtils.mask()를 호출하여 PII(주민번호, 계좌번호 등)를 안전하게 별표(*) 처리합니다.
|
||||
*/
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.util
|
||||
* @className PiiMaskingLogbackConverter
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class PiiMaskingLogbackConverter extends MessageConverter {
|
||||
|
||||
@Override
|
||||
public String convert(ILoggingEvent event) {
|
||||
// 원본 로그 메시지를 가져옵니다.
|
||||
String originalMessage = super.convert(event);
|
||||
|
||||
// 정규식을 이용하여 개인정보가 포함되어 있으면 마스킹 처리하여 반환합니다.
|
||||
return PiiMaskingUtils.mask(originalMessage);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.adapter.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.adapter.util
|
||||
* @className PiiMaskingUtils
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class PiiMaskingUtils {
|
||||
|
||||
// 1. 주민등록번호 패턴 (ex: 900101-1234567 또는 9001011234567)
|
||||
private static final Pattern RRN_PATTERN = Pattern.compile("(\\d{6})[-]?([1-4]\\d{6})");
|
||||
|
||||
// 2. 휴대전화번호 패턴 (ex: 010-1234-5678)
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile("(01[016789])[-]?(\\d{3,4})[-]?(\\d{4})");
|
||||
|
||||
// 3. 신한라이프 계좌/증권번호 패턴 (단순 예시용 계좌번호 11~14자리)
|
||||
private static final Pattern ACCOUNT_PATTERN = Pattern.compile("(\\d{3})-?(\\d{3})-?(\\d{5,8})");
|
||||
|
||||
public static String mask(String input) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return input;
|
||||
}
|
||||
|
||||
String masked = input;
|
||||
|
||||
// [1] 주민번호 뒷자리 마스킹 (첫자리 성별 식별자는 남기고 마스킹: 900101-1******)
|
||||
Matcher rrnMatcher = RRN_PATTERN.matcher(masked);
|
||||
StringBuffer rrnBuffer = new StringBuffer();
|
||||
while (rrnMatcher.find()) {
|
||||
String firstPart = rrnMatcher.group(1);
|
||||
String secondPart = rrnMatcher.group(2);
|
||||
rrnMatcher.appendReplacement(rrnBuffer, firstPart + "-" + secondPart.charAt(0) + "******");
|
||||
}
|
||||
rrnMatcher.appendTail(rrnBuffer);
|
||||
masked = rrnBuffer.toString();
|
||||
|
||||
// [2] 전화번호 중간자리 마스킹 (010-****-5678)
|
||||
Matcher phoneMatcher = PHONE_PATTERN.matcher(masked);
|
||||
StringBuffer phoneBuffer = new StringBuffer();
|
||||
while (phoneMatcher.find()) {
|
||||
String p1 = phoneMatcher.group(1);
|
||||
String p2 = phoneMatcher.group(2);
|
||||
String p3 = phoneMatcher.group(3);
|
||||
String maskedP2 = p2.replaceAll(".", "*");
|
||||
phoneMatcher.appendReplacement(phoneBuffer, p1 + "-" + maskedP2 + "-" + p3);
|
||||
}
|
||||
phoneMatcher.appendTail(phoneBuffer);
|
||||
masked = phoneBuffer.toString();
|
||||
|
||||
// [3] 계좌번호 뒷자리 마스킹 (110-123-********)
|
||||
Matcher accMatcher = ACCOUNT_PATTERN.matcher(masked);
|
||||
StringBuffer accBuffer = new StringBuffer();
|
||||
while (accMatcher.find()) {
|
||||
String a1 = accMatcher.group(1);
|
||||
String a2 = accMatcher.group(2);
|
||||
String a3 = accMatcher.group(3);
|
||||
String maskedA3 = a3.replaceAll(".", "*");
|
||||
accMatcher.appendReplacement(accBuffer, a1 + "-" + a2 + "-" + maskedA3);
|
||||
}
|
||||
accMatcher.appendTail(accBuffer);
|
||||
masked = accBuffer.toString();
|
||||
|
||||
return masked;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Spring AI @Tool 어노테이션을 보완하여 MCP 시스템 메타데이터를 추가 제공하는 힌트 어노테이션
|
||||
* @package io.shinhanlife.dap.lib.annotation
|
||||
* @className GrowToolHint
|
||||
* @description 비즈니스 로직(Tool)과 시스템 제어 메타데이터 분리
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GrowToolHint {
|
||||
boolean register() default true;
|
||||
boolean requiresApproval() default false;
|
||||
String categoryKey() default "com";
|
||||
String mappingId() default "";
|
||||
String inputSchemaResource() default "";
|
||||
String outputSchemaResource() default "";
|
||||
|
||||
// Meta 정보 추가 (보고용 샘플)
|
||||
String displayDescription() default "";
|
||||
String functionDescription() default "";
|
||||
String whenToUse() default "";
|
||||
String whenNotToUse() default "";
|
||||
String ioLimits() default "";
|
||||
String[] exampleQueries() default {};
|
||||
boolean destructive() default false;
|
||||
boolean idempotent() default false;
|
||||
String[] tags() default {};
|
||||
String[] requiredEnvKeys() default {};
|
||||
String ownerOrg() default "";
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a response DTO whose generated JSON Schema must be exposed and validated for a Tool response.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface McpOutputSchema {
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.aop;
|
||||
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.aop
|
||||
* @className ToolSlaMonitoringAspect
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import io.shinhanlife.dap.lib.config.McpProperties;
|
||||
import java.lang.reflect.Method;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springaicommunity.mcp.annotation.McpTool;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ToolSlaMonitoringAspect {
|
||||
|
||||
private final McpProperties mcpProperties;
|
||||
|
||||
// @McpTool 어노테이션이 붙은 모든 비즈니스 툴 메서드 실행을 가로챕니다.
|
||||
@Around("@annotation(org.springaicommunity.mcp.annotation.McpTool)")
|
||||
public Object monitorToolSla(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
McpTool functionAnnotation = method.getAnnotation(McpTool.class);
|
||||
|
||||
// 네임스페이스 자동 주입 로직을 반영하여 최종 툴 이름을 산출합니다.
|
||||
String baseName = functionAnnotation.name();
|
||||
String finalName = mcpProperties.getNamespace() != null && !mcpProperties.getNamespace().isEmpty()
|
||||
? mcpProperties.getNamespace() + "_" + baseName
|
||||
: baseName;
|
||||
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
|
||||
try {
|
||||
// 실제 비즈니스 로직(툴) 실행
|
||||
Object result = joinPoint.proceed();
|
||||
|
||||
stopWatch.stop();
|
||||
long timeMillis = stopWatch.getTotalTimeMillis();
|
||||
|
||||
// SLA 기준을 초과하면 (예: 2초 이상) 경고 로깅 처리 가능
|
||||
if (timeMillis > 2000) {
|
||||
log.warn(" [SLA 경고] Tool: {} | 소요시간: {}ms | 상태: SLOW_RESPONSE", finalName, timeMillis);
|
||||
} else {
|
||||
log.info(" [SLA 추적] Tool: {} | 소요시간: {}ms | 상태: SUCCESS", finalName, timeMillis);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} catch (Throwable e) {
|
||||
if (stopWatch.isRunning()) {
|
||||
stopWatch.stop();
|
||||
}
|
||||
long timeMillis = stopWatch.getTotalTimeMillis();
|
||||
|
||||
// 에러 발생 시 명확하게 실패 로그 기록
|
||||
log.error(" [SLA 장애] Tool: {} | 소요시간: {}ms | 상태: FAILED | 사유: {}", finalName, timeMillis, e.getMessage());
|
||||
|
||||
// 원래 흐름대로 예외를 던져서 게이트웨이나 상위 로직이 에러를 처리하게 함
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import io.shinhanlife.glow.communication.module.http.component.GlowHttpComponent;
|
||||
import java.net.http.HttpClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.JdkClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
/**
|
||||
* Registers the temporary Glow HTTP compatibility component from the DAP library scan scope.
|
||||
* The bean is only created when an official GlowHttpComponent has not already been supplied.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class AxhubHttpConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(GlowHttpComponent.class)
|
||||
public GlowHttpComponent glowHttpComponent(RestClient.Builder restClientBuilder) {
|
||||
// WireMock and legacy internal endpoints can only support HTTP/1.1.
|
||||
// Avoid JDK HTTP/2 negotiation that may cause RST_STREAM responses.
|
||||
HttpClient http11Client = HttpClient.newBuilder()
|
||||
.version(HttpClient.Version.HTTP_1_1)
|
||||
.build();
|
||||
JdkClientHttpRequestFactory requestFactory = new JdkClientHttpRequestFactory(http11Client);
|
||||
return new GlowHttpComponent(restClientBuilder.requestFactory(requestFactory));
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.config
|
||||
* @className CorsConfig
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Configuration
|
||||
public class CorsConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**") // 모든 엔드포인트에 대해 CORS 허용
|
||||
.allowedOriginPatterns("*") // 외부 Agent Builder 등 모든 오리진 허용
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH") // 허용할 HTTP 메서드
|
||||
.allowedHeaders("*") // 모든 헤더 허용
|
||||
.exposedHeaders("Mcp-Session-Id") // MCP-HTTP 세션 아이디 노출 허용
|
||||
.allowCredentials(true) // 쿠키/인증 정보 허용
|
||||
.maxAge(3600); // preflight 요청 캐시 시간 (초 단위)
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* [Glow Framework 통신 환경 설정 클래스]
|
||||
* application-glow-local.yml 의 'glow.communication' 하위 설정값들을
|
||||
* 자바 객체(Bean)로 매핑하여 제공합니다.
|
||||
*/
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.config
|
||||
* @className GlowCommunicationProperties
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Component
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(prefix = "glow.communication")
|
||||
public class GlowCommunicationProperties {
|
||||
|
||||
private Common common = new Common();
|
||||
private Http http = new Http();
|
||||
private Mci mci = new Mci();
|
||||
private ExtMci extmci = new ExtMci();
|
||||
private Eai eai = new Eai();
|
||||
private Websocket websocket = new Websocket();
|
||||
|
||||
@Getter @Setter
|
||||
public static class Common {
|
||||
private String envType; // 대내표준 헤더의 환경 타입정보 (D, T, P)
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
public static class Http {
|
||||
private int connectionTimeout; // 연결 타임아웃 시간 (초 단위)
|
||||
private int readTimeout; // 읽기 타임아웃 시간 (초 단위)
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
public static class Mci {
|
||||
private String host;
|
||||
private int port;
|
||||
private String uri;
|
||||
private String receiveUri;
|
||||
private int connectionTimeout;
|
||||
private int readTimeout;
|
||||
private String encoding;
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
public static class ExtMci {
|
||||
private String host;
|
||||
private int port;
|
||||
private String uri;
|
||||
private String jsonUri;
|
||||
private String receiveUri;
|
||||
private int connectionTimeout;
|
||||
private int readTimeout;
|
||||
private String encoding;
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
public static class Eai {
|
||||
private String host;
|
||||
private int port;
|
||||
}
|
||||
|
||||
@Getter @Setter
|
||||
public static class Websocket {
|
||||
private String endpoint;
|
||||
private String allowedOrigins;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.config
|
||||
* @className McpProperties
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "mcp")
|
||||
public class McpProperties {
|
||||
|
||||
private String namespace;
|
||||
private Manifest manifest = new Manifest();
|
||||
|
||||
@Data
|
||||
public static class Manifest {
|
||||
private String bundleId;
|
||||
private String namePrefix;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.config
|
||||
* @className MybatisConfig
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import io.shinhanlife.glow.GlowMybatisMapper;
|
||||
|
||||
@Configuration
|
||||
@MapperScan(basePackages = "io.shinhanlife.dap", annotationClass = GlowMybatisMapper.class)
|
||||
public class MybatisConfig {
|
||||
|
||||
@Bean
|
||||
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
|
||||
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
|
||||
sessionFactory.setDataSource(dataSource);
|
||||
return sessionFactory.getObject();
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import com.p6spy.engine.logging.Category;
|
||||
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.config
|
||||
* @className P6SpySqlFormatter
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class P6SpySqlFormatter implements MessageFormattingStrategy {
|
||||
|
||||
@Override
|
||||
public String formatMessage(int connectionId, String now, long elapsed,
|
||||
String category, String prepared, String sql, String url) {
|
||||
|
||||
if (sql == null || sql.isBlank()) return "";
|
||||
if (Category.STATEMENT.getName().equals(category)) {
|
||||
|
||||
String prettySQL = sql
|
||||
.replaceAll("(?i)\\bSELECT\\b", "\nSELECT")
|
||||
.replaceAll("(?i)\\bFROM\\b", "\n FROM")
|
||||
.replaceAll("(?i)\\bWHERE\\b", "\n WHERE")
|
||||
.replaceAll("(?i)\\bAND\\b", "\n AND")
|
||||
.replaceAll("(?i)\\bOR\\b", "\n OR")
|
||||
.replaceAll("(?i)\\bINNER JOIN\\b", "\n INNER JOIN")
|
||||
.replaceAll("(?i)\\bLEFT JOIN\\b", "\n LEFT JOIN")
|
||||
.replaceAll("(?i)\\bORDER BY\\b", "\n ORDER BY")
|
||||
.replaceAll("(?i)\\bGROUP BY\\b", "\n GROUP BY")
|
||||
.replaceAll("(?i)\\bINSERT INTO\\b", "\nINSERT INTO")
|
||||
.replaceAll("(?i)\\bVALUES\\b", "\n VALUES")
|
||||
.replaceAll("(?i)\\bUPDATE\\b", "\nUPDATE")
|
||||
.replaceAll("(?i)\\bSET\\b", "\n SET")
|
||||
.replaceAll("(?i)\\bDELETE FROM\\b", "\nDELETE FROM");
|
||||
|
||||
return String.format("""
|
||||
\n┌─────────────────────────────────────────
|
||||
│ SQL [%dms]
|
||||
│%s
|
||||
└─────────────────────────────────────────
|
||||
""", elapsed, prettySQL.indent(2).stripTrailing());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
|
||||
import io.modelcontextprotocol.json.schema.jackson2.DefaultJsonSchemaValidator;
|
||||
import io.shinhanlife.dap.lib.util.ToolSchemaResolver;
|
||||
import io.shinhanlife.dap.lib.validation.ToolArgumentSchemaValidator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Common MCP Tool Schema Bean configuration.
|
||||
*/
|
||||
@Configuration
|
||||
public class ToolSchemaConfiguration {
|
||||
|
||||
@Bean
|
||||
public ToolSchemaResolver toolSchemaResolver(ObjectMapper objectMapper) {
|
||||
return new ToolSchemaResolver(objectMapper);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JsonSchemaValidator mcpJsonSchemaValidator() {
|
||||
return new DefaultJsonSchemaValidator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ToolArgumentSchemaValidator toolArgumentSchemaValidator(ObjectMapper objectMapper,
|
||||
JsonSchemaValidator jsonSchemaValidator) {
|
||||
return new ToolArgumentSchemaValidator(objectMapper, jsonSchemaValidator);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.dto;
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.mcg.dto
|
||||
* @className OperationType
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public enum OperationType {
|
||||
READ,
|
||||
WRITE
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.integration;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
// TODO: 실제 Glow Framework 의존성이 추가되면 아래 주석들을 풀고 사용하세요!
|
||||
// import io.shinhanlife.glow.communication.dto.CommonHeader;
|
||||
// import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
// import io.shinhanlife.glow.communication.module.eai.component.GlowEaiComponent;
|
||||
// import io.shinhanlife.glow.communication.module.mci.component.GlowExtMciComponent;
|
||||
// import io.shinhanlife.glow.communication.module.mci.component.GlowMciComponent;
|
||||
// import io.shinhanlife.glow.communication.util.CommonHeaderFactory;
|
||||
|
||||
/**
|
||||
* [MCI / EAI 공통 연동 래퍼(Wrapper) 템플릿]
|
||||
* 신한라이프 Glow Framework 개발표준정의서를 바탕으로 대내/대외망/EAI 통신을
|
||||
* MCP 툴에서 손쉽게 호출할 수 있도록 일원화한 컴포넌트입니다.
|
||||
*/
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.integration
|
||||
* @className GlowIntegrationCall
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class GlowIntegrationCall {
|
||||
|
||||
// 1. 실제 의존성이 주입될 프레임워크 컴포넌트들 (임시 주석 처리)
|
||||
/*
|
||||
private final GlowMciComponent mci;
|
||||
private final GlowEaiComponent eai;
|
||||
private final GlowExtMciComponent extMci;
|
||||
*/
|
||||
|
||||
/**
|
||||
* 1. 대외 MCI 호출 (타행, 금융결제원 등 외부 기관)
|
||||
* 가이드 2.2.2에 명시된 필수 파라미터(기관코드, 종별코드, 업무코드, 거래코드)를 모두 포함합니다.
|
||||
*/
|
||||
/*
|
||||
public <S, R> Transfer<R> callExtMci(String itrfId, String frbuCd, String cmouDutjCd, String cmouCssfCd, String cmouTraCd, S body, Class<R> resBody) {
|
||||
|
||||
// 1. 공통 헤더 생성
|
||||
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
|
||||
|
||||
// 2. 대외 전용 필수 코드 세팅 로직 (프레임워크 내부 스펙에 맞게 가공)
|
||||
// (예: 헤더에 해당 속성들을 주입하거나 Transfer 객체에 싣는 과정 추가)
|
||||
|
||||
// 3. Transfer 객체 빌드
|
||||
Transfer<S> req = Transfer.<S>builder()
|
||||
.header(header)
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
// 4. 대외 MCI 컴포넌트를 통해 최종 전송
|
||||
return extMci.call(req, resBody);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* 2. EAI 호출 (대내망 중계기)
|
||||
* 가이드 2.3에 명시된 대로 수신서비스 ID 없이 인터페이스 ID(itrfId)만 필수로 받습니다.
|
||||
*/
|
||||
/*
|
||||
public <S, R> Transfer<R> callEai(String itrfId, S body, Class<R> resBody) {
|
||||
|
||||
// 1. EAI는 인터페이스 ID만으로 심플하게 헤더 생성
|
||||
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
|
||||
|
||||
// 2. Transfer 객체 빌드
|
||||
Transfer<S> req = Transfer.<S>builder()
|
||||
.header(header)
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
// 3. EAI 컴포넌트를 통해 최종 전송
|
||||
return eai.call(req, resBody);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* 3. 대내 MCI 호출 (사내 시스템 간 통신)
|
||||
*/
|
||||
/*
|
||||
public <S, R> Transfer<R> callMci(String itrfId, S body, Class<R> resBody) {
|
||||
|
||||
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId);
|
||||
|
||||
Transfer<S> req = Transfer.<S>builder()
|
||||
.header(header)
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
return mci.call(req, resBody);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.integration.dto;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import java.util.List;
|
||||
|
||||
// TODO: 실제 Glow Framework 의존성이 추가되면 아래 주석을 풀고 사용하세요!
|
||||
// import io.shinhanlife.glow.communication.annotation.GlowMciFieldInfo;
|
||||
|
||||
/**
|
||||
* [대외 MCI 연동용 DTO 표준 템플릿]
|
||||
* Glow Framework 개발표준정의서(2.2.1 IO 작성) 규칙을 100% 준수한 샘플입니다.
|
||||
* 새로운 대외 통신 전문을 만들 때 이 파일을 복사해서 필드명과 길이만 수정하여 사용하세요.
|
||||
*/
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.integration.dto
|
||||
* @className SampleGlowMessage
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor(access = AccessLevel.PUBLIC) // [규칙 1] Reflection을 위한 기본 생성자 필수 (public 유지)
|
||||
public class SampleGlowMessage {
|
||||
|
||||
// [규칙 2] @GlowMciFieldInfo 선언 필수 (order: 순서)
|
||||
// @GlowMciFieldInfo(order = 1)
|
||||
private MessageHeader header;
|
||||
|
||||
// [규칙 2] @GlowMciFieldInfo 선언 필수 (order: 순서)
|
||||
// @GlowMciFieldInfo(order = 2)
|
||||
private List<MessageBody> msgDtdvValu; // 다건(List) 본문 데이터
|
||||
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor(access = AccessLevel.PUBLIC)
|
||||
public static class MessageHeader {
|
||||
|
||||
// [규칙 2] 단건 필드의 경우 length 필수 입력 (EIMS 길이와 일치해야 함)
|
||||
// @GlowMciFieldInfo(order = 1, length = 1)
|
||||
private String msgTnsmTypeCd;
|
||||
|
||||
// @GlowMciFieldInfo(order = 2, length = 8)
|
||||
private int msdvLen;
|
||||
|
||||
// [규칙 3] 다건(List) 건수 필드의 경우, target 속성에 대상 변수명("msgDtdvValu") 필수 기입!
|
||||
// @GlowMciFieldInfo(order = 3, length = 2, target = "msgDtdvValu")
|
||||
private int msgRpttCc;
|
||||
}
|
||||
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor(access = AccessLevel.PUBLIC)
|
||||
public static class MessageBody {
|
||||
|
||||
// @GlowMciFieldInfo(order = 1, length = 8)
|
||||
private String msgCd;
|
||||
|
||||
// @GlowMciFieldInfo(order = 2, length = 1)
|
||||
private String msgPrnAttrCd;
|
||||
|
||||
// @GlowMciFieldInfo(order = 3, length = 200)
|
||||
private String msgCt;
|
||||
|
||||
// @GlowMciFieldInfo(order = 4, length = 200)
|
||||
private String anxMsgCt;
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.integration.eai.component;
|
||||
|
||||
import io.shinhanlife.dap.lib.config.GlowCommunicationProperties;
|
||||
import io.shinhanlife.glow.communication.dto.CommonHeader;
|
||||
import io.shinhanlife.glow.communication.dto.Transfer;
|
||||
import io.shinhanlife.glow.communication.module.eai.component.GlowEaiComponent;
|
||||
import io.shinhanlife.glow.communication.util.CommonHeaderFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 신한라이프 내부 Glow 표준 EAI 컴포넌트 어댑터 (AXHUB)
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
|
||||
/**
|
||||
* @package io.shinhanlife.dap.lib.integration.eai.component
|
||||
* @className AxhubEaiComponent
|
||||
* @description AX HUB 시스템 처리 클래스
|
||||
* @author 0986406
|
||||
* @create 2026.09.01
|
||||
* <pre>
|
||||
* ---------- 개정이력 ----------
|
||||
* 수정일 수정자 수정내용
|
||||
* ---------- -------- ---------------------------
|
||||
* 2026.09.01 0986406 최초생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class AxhubEaiComponent {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final GlowEaiComponent eai;
|
||||
private final GlowCommunicationProperties communicationProperties;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <O> Transfer<O> syncEai(Transfer<Object> request) {
|
||||
// LOG 저장 (AXHUB 방식 로깅)
|
||||
CommonHeader reqHeader = (CommonHeader) request.getHeader();
|
||||
log.info("[AxhubEaiComponent] {} EAI 호출시작 (수신서비스: {})", reqHeader.getItrfId(), reqHeader.getRcvSvcId());
|
||||
|
||||
Transfer<O> response = (Transfer<O>) eai.sync(request);
|
||||
|
||||
log.info("[AxhubEaiComponent] {} EAI 호출종료 (수신서비스: {})", reqHeader.getItrfId(), reqHeader.getRcvSvcId());
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* EAI 호출
|
||||
*/
|
||||
public <O, I> Transfer<O> call(String itrfId, String rcvSvcId, I inputDto) throws Exception {
|
||||
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId, rcvSvcId);
|
||||
|
||||
Transfer<Object> request = Transfer.builder()
|
||||
.header(header)
|
||||
.body(inputDto)
|
||||
.build();
|
||||
|
||||
return syncEai(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* EAI 호출 (응답 타입 명시)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <O, I> Transfer<O> call(String itrfId, String rcvSvcId, I inputDto, Class<O> resBodyClass) throws Exception {
|
||||
CommonHeader header = CommonHeaderFactory.createRequestHeader(itrfId, rcvSvcId);
|
||||
|
||||
Transfer<Object> request = Transfer.builder()
|
||||
.header(header)
|
||||
.body(inputDto)
|
||||
.resBodyClass((Class<Object>) (Class<?>) resBodyClass)
|
||||
.build();
|
||||
|
||||
return syncEai(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* EAI 호출 (rcvSvcId 없는 경우)
|
||||
*/
|
||||
public <O, I> Transfer<O> call(String itrfId, I inputDTO, Class<O> resBodyClass) throws Exception {
|
||||
String className = inputDTO.getClass().getSimpleName();
|
||||
String rcvSvcId = className.replace("_I", "");
|
||||
return call(itrfId, rcvSvcId, inputDTO, resBodyClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* EAI 호출 (Response body class와 rcvSvcId 없는 경우)
|
||||
*/
|
||||
public <O, I> Transfer<O> call(String itrfId, I inputDTO) throws Exception {
|
||||
String className = inputDTO.getClass().getSimpleName();
|
||||
String rcvSvcId = className.replace("_I", "");
|
||||
return call(itrfId, rcvSvcId, inputDTO);
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.integration.http.component;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.shinhanlife.dap.lib.config.GlowCommunicationProperties;
|
||||
import io.shinhanlife.dap.lib.mcp.McpRequestHeaderContext;
|
||||
import io.shinhanlife.dap.lib.mcp.McpRequestHeaders;
|
||||
import io.shinhanlife.glow.communication.module.http.component.GlowHttpComponent;
|
||||
import io.shinhanlife.glow.communication.module.http.dto.HttpBody;
|
||||
import io.shinhanlife.glow.communication.module.http.dto.HttpHeader;
|
||||
import io.shinhanlife.glow.communication.module.http.dto.HttpTransfer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Tool Pod outbound HTTP component using the Glow HTTP client.
|
||||
* Target URL, HTTP method, content type and Pod-to-Pod behaviour are resolved from
|
||||
* {@code glow.communication.http.api-list}; business source code does not own endpoint values.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class AxhubHttpComponent {
|
||||
|
||||
private static final String ANONYMOUS_REQUEST = "AXHUB-TOOL";
|
||||
|
||||
private final GlowHttpComponent http;
|
||||
private final ObjectMapper json;
|
||||
private final GlowCommunicationProperties communicationProperties;
|
||||
private final AxhubHttpProperties properties;
|
||||
|
||||
/** Calls the exact URL configured for the API name. */
|
||||
public <T, R> R call(String apiName, T inputDto, Class<R> responseBodyClass) {
|
||||
return call(apiName, "", inputDto, responseBodyClass, 0);
|
||||
}
|
||||
|
||||
/** Calls the configured URL with an optional resource suffix. */
|
||||
public <T, R> R call(String apiName, String uri, T inputDto, Class<R> responseBodyClass) {
|
||||
return call(apiName, uri, inputDto, responseBodyClass, 0);
|
||||
}
|
||||
|
||||
public <T, R> R call(String apiName, String uri, T inputDto, Class<R> responseBodyClass, int timeout) {
|
||||
AxhubHttpProperties.ApiDefinition api = resolveApi(apiName);
|
||||
return execute(api, uri, inputDto, responseBodyClass, timeout);
|
||||
}
|
||||
|
||||
/** Calls the configured URL only when the target is marked as a business Pod. */
|
||||
public <T, R> R callBizPod(String apiName, T inputDto, Class<R> responseBodyClass) {
|
||||
AxhubHttpProperties.ApiDefinition api = resolveApi(apiName);
|
||||
if (!api.bizPod()) {
|
||||
throw new IllegalArgumentException("Configured API is not a business Pod: " + apiName);
|
||||
}
|
||||
return execute(api, "", inputDto, responseBodyClass, 0);
|
||||
}
|
||||
|
||||
private <T, R> R execute(AxhubHttpProperties.ApiDefinition api, String uri, T inputDto,
|
||||
Class<R> responseBodyClass, int timeout) {
|
||||
HttpHeader header = createHeader(api, timeout);
|
||||
String requestUri = joinPath(api.url(), uri);
|
||||
HttpTransfer<T> request = HttpTransfer.<T>http()
|
||||
.header(header)
|
||||
.domain(api.domain())
|
||||
.uri(requestUri)
|
||||
.method(api.method())
|
||||
.contentType(contentType(api))
|
||||
.responseEntity(responseBodyClass)
|
||||
.body(inputDto)
|
||||
.build();
|
||||
|
||||
log.info("[AxhubHttpComponent] Glow HTTP call. apiName={}, method={}, uri={}",
|
||||
api.name(), api.method(), requestUri);
|
||||
ResponseEntity<HttpBody> response = http.sync(request);
|
||||
return convertResponse(response.getBody(), responseBodyClass);
|
||||
}
|
||||
|
||||
private AxhubHttpProperties.ApiDefinition resolveApi(String apiName) {
|
||||
return properties.getApiList().stream()
|
||||
.filter(api -> apiName != null && apiName.equals(api.name()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException("No HTTP API configuration for name: " + apiName));
|
||||
}
|
||||
|
||||
private HttpHeader createHeader(AxhubHttpProperties.ApiDefinition api, int timeout) {
|
||||
HttpHeader header = new HttpHeader();
|
||||
if (api.bizPod()) {
|
||||
header.set("X-POD-TO-POD", "true");
|
||||
}
|
||||
McpRequestHeaders inbound = McpRequestHeaderContext.current();
|
||||
if (inbound == null) {
|
||||
header.set("X-ANONYMOUS-REQ", ANONYMOUS_REQUEST);
|
||||
} else {
|
||||
putIfPresent(header, "x-request-id", inbound.requestId());
|
||||
putIfPresent(header, "guid", inbound.guid());
|
||||
putIfPresent(header, "mcp-session-id", inbound.mcpSessionId());
|
||||
putIfPresent(header, "employee-no", inbound.employeeNo());
|
||||
putIfPresent(header, "virtual-employee-no", inbound.virtualEmployeeNo());
|
||||
}
|
||||
header.setReadTimeout(timeout == 0 ? defaultReadTimeout() : timeout);
|
||||
return header;
|
||||
}
|
||||
|
||||
private int defaultReadTimeout() {
|
||||
return communicationProperties == null || communicationProperties.getHttp() == null
|
||||
? 0 : communicationProperties.getHttp().getReadTimeout();
|
||||
}
|
||||
|
||||
private MediaType contentType(AxhubHttpProperties.ApiDefinition api) {
|
||||
return api.contentType() == null || api.contentType().isBlank()
|
||||
? MediaType.APPLICATION_JSON
|
||||
: MediaType.parseMediaType(api.contentType());
|
||||
}
|
||||
|
||||
private <R> R convertResponse(HttpBody responseBody, Class<R> responseBodyClass) {
|
||||
String content = responseBody == null ? null : responseBody.content();
|
||||
if (responseBodyClass == String.class) {
|
||||
return responseBodyClass.cast(content);
|
||||
}
|
||||
try {
|
||||
return json.readValue(content, responseBodyClass);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalStateException("Failed to convert HTTP response to " + responseBodyClass.getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void putIfPresent(HttpHeader header, String name, String value) {
|
||||
if (value != null && !value.isBlank()) {
|
||||
header.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private String joinPath(String configuredUrl, String suffix) {
|
||||
String left = configuredUrl == null ? "" : configuredUrl.replaceAll("/+$", "");
|
||||
if (suffix == null || suffix.isBlank()) {
|
||||
return left.isEmpty() ? "/" : left;
|
||||
}
|
||||
String right = suffix.startsWith("/") ? suffix : "/" + suffix;
|
||||
return left + right;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package io.shinhanlife.dap.lib.integration.http.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Glow HTTP target catalog.
|
||||
*
|
||||
* <p>Each target follows the ShinhanLife standard: name, domain, url, method,
|
||||
* content-type, and biz-pod. Target-specific values belong in application-glow*.yml.</p>
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "glow.communication.http")
|
||||
public class AxhubHttpProperties {
|
||||
|
||||
private List<ApiDefinition> apiList = new ArrayList<>();
|
||||
|
||||
public record ApiDefinition(
|
||||
String name,
|
||||
String domain,
|
||||
String url,
|
||||
HttpMethod method,
|
||||
String contentType,
|
||||
boolean bizPod
|
||||
) {
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user