feat: Refactor monolith to microservices architecture

This commit is contained in:
jade
2026-07-05 17:27:44 +09:00
parent 367a47516d
commit 10f3f0513d
200 changed files with 541 additions and 1789 deletions

View File

@@ -0,0 +1,12 @@
plugins {
id 'org.springframework.boot'
}
dependencies {
implementation project(':axhub-tool-core')
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BillingProcessReq {
@McpParameter(description = "처리할 청구 접수 번호", required = true)
private String billingId;
@McpParameter(description = "심사 승인 여부 (예: APPROVE, REJECT)")
private String approvalStatus;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BillingStatusReq {
@McpParameter(description = "조회할 청구 접수 번호", required = true)
private String billingId;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BondCheckReq {
@McpParameter(description = "확인하고자 하는 디지털 증권 발행 금액", required = true)
private Long amount;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BondIssueReq {
@McpParameter(description = "발행할 디지털 증권 금액", required = true)
private Long amount;
@McpParameter(description = "발행 대상 계좌 번호", required = true)
private String targetAccount;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ContractDetailReq {
@McpParameter(description = "고객명", required = true)
private String customerName;
@McpParameter(description = "조회할 계약 번호", required = true)
private String contractId;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ContractStatusReq {
@McpParameter(description = "고객명", required = true)
private String customerName;
@McpParameter(description = "조회할 계약 번호")
private String contractId;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CustomerDetailReq {
@McpParameter(description = "고객명", required = true)
private String customerName;
@McpParameter(description = "고객 식별 번호 (CID)")
private String customerId;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CustomerGradeReq {
@McpParameter(description = "고객 이름 (예: 김신한)", required = true)
private String customerName;
@McpParameter(description = "고객 식별 번호 (CID)")
private String customerId;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class LeaveCountReq {
@McpParameter(description = "연차 내역을 조회할 사원 번호", required = true)
private String employeeId;
}

View File

@@ -0,0 +1,16 @@
package io.shinhanlife.axhub.biz.mcp.tool.dto;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpParameter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class VacationRegisterReq {
@McpParameter(description = "연차를 등록할 사원 번호", required = true)
private String employeeId;
@McpParameter(description = "휴가 일자 (YYYY-MM-DD 형식)", required = true)
private String date;
}

View File

@@ -0,0 +1,13 @@
package io.shinhanlife.axhub.biz.mcp.tool.other;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class AxHubToolOtherApplication {
public static void main(String[] args) {
SpringApplication.run(AxHubToolOtherApplication.class, args);
}
}

View File

@@ -0,0 +1,55 @@
package io.shinhanlife.axhub.biz.mcp.tool.service;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import io.shinhanlife.axhub.biz.mcp.tool.dto.BillingStatusReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.BillingProcessReq;
@McpTool(
name = "billing_process_tool",
description = "청구 심사 및 처리 상태 툴",
group = "biz_channel",
routingType = "MCI"
)
@lombok.extern.slf4j.Slf4j
public class BillingProcessService extends AbstractMcpToolService {
@McpFunction(name = "status", description = "청구심사 상태 조회", prompt = "현재 접수된 청구건 상태를 알려줘.", mappingId = "BILL_001")
public Object getStatus(BillingStatusReq data) {
return executeBillingLogic("BILL_001", data);
}
@McpFunction(name = "process", description = "청구 처리", prompt = "현재 접수된 청구건에 대한 심사 처리를 진행해.", mappingId = "BILL_002")
public Object processBilling(BillingProcessReq data) {
return executeBillingLogic("BILL_002", data);
}
private Object executeBillingLogic(String mappingId, Object data) {
log.info("💰 [Billing] 청구 처리 전용 커스텀 전/후처리 로직 수행 시작");
Map<String, Object> payload;
if (data == null) {
payload = new HashMap<>();
} else {
ObjectMapper mapper = new ObjectMapper();
payload = mapper.convertValue(data, new TypeReference<Map<String, Object>>() {});
}
// 커스텀 전처리
payload.put("custom_injected_data", "Billing System Check OK");
log.info("💰 [Billing] 커스텀 파라미터 주입 완료");
// 부모 클래스의 레거시 공통 연동 메서드 호출 (PII 마스킹 포함)
Map<String, Object> result = executeLegacy("MCI", mappingId, payload);
// 커스텀 후처리
if ("SUCCESS".equals(result.get("status"))) {
result.put("billing_custom_insight", "청구 특화 후처리 로직이 적용되었습니다.");
}
return result;
}
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.axhub.biz.mcp.tool.service;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
import io.shinhanlife.axhub.biz.mcp.tool.dto.BondCheckReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.BondIssueReq;
@McpTool(
name = "bond_issue_tool",
description = "디지털 증권 발행 가능 여부 조회 툴",
group = "biz_support",
routingType = "EAI"
)
public class BondIssueService extends AbstractMcpToolService {
@McpFunction(name = "check", description = "발행 가능 여부 조회", prompt = "디지털 증권 발행 한도가 충분한지 확인해줘.", mappingId = "BOND_001")
public Object check(BondCheckReq data) {
return executeLegacy("EAI", "BOND_001", data);
}
@McpFunction(name = "issue", description = "증권 발행", prompt = "디지털 증권 발행 프로세스를 실행해.", mappingId = "BOND_002")
public Object issue(BondIssueReq data) {
return executeLegacy("EAI", "BOND_002", data);
}
}

View File

@@ -0,0 +1,27 @@
package io.shinhanlife.axhub.biz.mcp.tool.service;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
import io.shinhanlife.axhub.biz.mcp.tool.dto.VacationRegisterReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.LeaveCountReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.LeaveCountReq;
@McpTool(
name = "common_utility_tool",
description = "전사 공통 유틸리티 툴 (HR 및 알림)",
group = "biz_core",
routingType = "HTTP"
)
public class CommonUtilityService extends AbstractMcpToolService {
@McpFunction(name = "register_vacation", description = "휴가 등록", prompt = "내일 하루 연차 휴가를 등록해줘.", mappingId = "HR_VAC_01")
public Object registerVacation(VacationRegisterReq data) {
return executeLegacy("HTTP", "HR_VAC_01", data);
}
@McpFunction(name = "get_leave_count", description = "연차 갯수 조회", prompt = "현재 사용 가능한 남은 연차 일수를 알려줘.", mappingId = "HR_VAC_02")
public Object getLeaveCount(LeaveCountReq data) {
return executeLegacy("HTTP", "HR_VAC_02", data);
}
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.axhub.biz.mcp.tool.service;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
import io.shinhanlife.axhub.biz.mcp.tool.dto.ContractStatusReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.ContractDetailReq;
@McpTool(
name = "contract_inquiry_tool",
description = "계약 상태 및 상세 정보 조회 툴",
group = "biz_channel",
routingType = "HTTP"
)
public class ContractInquiryService extends AbstractMcpToolService {
@McpFunction(name = "status", description = "계약상태 조회", prompt = "김신한 고객의 현재 계약 상태를 조회해줘.", mappingId = "CNTR_001")
public Object getStatus(ContractStatusReq data) {
return executeLegacy("HTTP", "CNTR_001", data);
}
@McpFunction(name = "detail", description = "계약상세 조회", prompt = "김신한 고객의 계약 상세 내역을 알려줘.", mappingId = "CNTR_002")
public Object getDetail(ContractDetailReq data) {
return executeLegacy("HTTP", "CNTR_002", data);
}
}

View File

@@ -0,0 +1,25 @@
package io.shinhanlife.axhub.biz.mcp.tool.service;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpFunction;
import io.shinhanlife.axhub.biz.mcp.tool.annotation.McpTool;
import io.shinhanlife.axhub.biz.mcp.tool.dto.CustomerGradeReq;
import io.shinhanlife.axhub.biz.mcp.tool.dto.CustomerDetailReq;
@McpTool(
name = "customer_info_tool",
description = "고객 등급 및 상세 정보 조회 툴",
group = "biz_support",
routingType = "TCP"
)
public class CustomerInfoService extends AbstractMcpToolService {
@McpFunction(name = "grade", description = "고객등급 조회", prompt = "이 고객의 VIP 등급을 조회해줘.", mappingId = "CRM_001")
public Object getGrade(CustomerGradeReq req) {
return executeLegacy("TCP", "CRM_001", req);
}
@McpFunction(name = "detail", description = "고객상세 정보 조회", prompt = "이 고객의 상세 기본정보(주소, 연락처 등)를 알려줘.", mappingId = "CRM_002")
public Object getDetail(CustomerDetailReq data) {
return executeLegacy("TCP", "CRM_002", data);
}
}