fix: 같은 도메인에 새 엔드포인트 추가 시 코드 생성 오류 수정

- Controller는 항상 재생성 (모든 엔드포인트 합산 파일)
- Service/DTO는 이미 존재하면 스킵, force=true면 재생성

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
HYOJIN 2026-03-27 09:23:50 +09:00
부모 dbbf8628c5
커밋 6391683959
4개의 변경된 파일21개의 추가작업 그리고 203개의 파일을 삭제

파일 보기

@ -1,39 +0,0 @@
package com.snp.batch.jobs.web.compliance.controller;
import com.snp.batch.jobs.web.compliance.dto.ComplianceBypassDto;
import com.snp.batch.jobs.web.compliance.service.ComplianceBypassService;
import com.snp.batch.common.web.ApiResponse;
import com.snp.batch.common.web.controller.BaseBypassController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* IMO 기반 선박 Compliance 조회 bypass API
* S&P Maritime API에서 데이터를 실시간 조회하여 그대로 반환
*/
@RestController
@RequestMapping("/api/compliance")
@RequiredArgsConstructor
@Tag(name = "Compliance", description = "IMO 기반 선박 Compliance 조회 bypass API")
public class ComplianceController extends BaseBypassController {
private final ComplianceBypassService complianceBypassService;
@Operation(
summary = "IMO 기반 선박 Compliance 조회 조회",
description = "S&P API에서 IMO 기반 선박 Compliance 조회 데이터를 요청하고 응답을 그대로 반환합니다."
)
@GetMapping("/CompliancesByImos")
public ResponseEntity<ApiResponse<List<ComplianceBypassDto>>> getComplianceData(@Parameter(description = "IMO(최대 100개)")
@RequestParam(required = true) String imos) {
return execute(() -> complianceBypassService.getComplianceData(imos));
}
}

파일 보기

@ -1,122 +0,0 @@
package com.snp.batch.jobs.web.compliance.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ComplianceBypassDto {
@JsonProperty("dateAmended")
private String dateAmended;
@JsonProperty("legalOverall")
private Integer legalOverall;
@JsonProperty("lrimoShipNo")
private String lrimoShipNo;
@JsonProperty("shipBESSanctionList")
private Integer shipBESSanctionList;
@JsonProperty("shipDarkActivityIndicator")
private Integer shipDarkActivityIndicator;
@JsonProperty("shipDetailsNoLongerMaintained")
private Integer shipDetailsNoLongerMaintained;
@JsonProperty("shipEUSanctionList")
private Integer shipEUSanctionList;
@JsonProperty("shipFlagDisputed")
private Integer shipFlagDisputed;
@JsonProperty("shipFlagSanctionedCountry")
private Integer shipFlagSanctionedCountry;
@JsonProperty("shipHistoricalFlagSanctionedCountry")
private Integer shipHistoricalFlagSanctionedCountry;
@JsonProperty("shipOFACAdvisoryList")
private Integer shipOFACAdvisoryList;
@JsonProperty("shipOFACNonSDNSanctionList")
private Integer shipOFACNonSDNSanctionList;
@JsonProperty("shipOFACSanctionList")
private Integer shipOFACSanctionList;
@JsonProperty("shipOwnerAustralianSanctionList")
private Integer shipOwnerAustralianSanctionList;
@JsonProperty("shipOwnerBESSanctionList")
private Integer shipOwnerBESSanctionList;
@JsonProperty("shipOwnerCanadianSanctionList")
private Integer shipOwnerCanadianSanctionList;
@JsonProperty("shipOwnerEUSanctionList")
private Integer shipOwnerEUSanctionList;
@JsonProperty("shipOwnerFATFJurisdiction")
private Integer shipOwnerFATFJurisdiction;
@JsonProperty("shipOwnerHistoricalOFACSanctionedCountry")
private Integer shipOwnerHistoricalOFACSanctionedCountry;
@JsonProperty("shipOwnerOFACSSIList")
private Integer shipOwnerOFACSSIList;
@JsonProperty("shipOwnerOFACSanctionList")
private Integer shipOwnerOFACSanctionList;
@JsonProperty("shipOwnerOFACSanctionedCountry")
private Integer shipOwnerOFACSanctionedCountry;
@JsonProperty("shipOwnerParentCompanyNonCompliance")
private Integer shipOwnerParentCompanyNonCompliance;
@JsonProperty("shipOwnerParentFATFJurisdiction")
private String shipOwnerParentFATFJurisdiction;
@JsonProperty("shipOwnerParentOFACSanctionedCountry")
private String shipOwnerParentOFACSanctionedCountry;
@JsonProperty("shipOwnerSwissSanctionList")
private Integer shipOwnerSwissSanctionList;
@JsonProperty("shipOwnerUAESanctionList")
private Integer shipOwnerUAESanctionList;
@JsonProperty("shipOwnerUNSanctionList")
private Integer shipOwnerUNSanctionList;
@JsonProperty("shipSTSPartnerNonComplianceLast12m")
private Integer shipSTSPartnerNonComplianceLast12m;
@JsonProperty("shipSanctionedCountryPortCallLast12m")
private Integer shipSanctionedCountryPortCallLast12m;
@JsonProperty("shipSanctionedCountryPortCallLast3m")
private Integer shipSanctionedCountryPortCallLast3m;
@JsonProperty("shipSanctionedCountryPortCallLast6m")
private Integer shipSanctionedCountryPortCallLast6m;
@JsonProperty("shipSecurityLegalDisputeEvent")
private Integer shipSecurityLegalDisputeEvent;
@JsonProperty("shipSwissSanctionList")
private Integer shipSwissSanctionList;
@JsonProperty("shipUNSanctionList")
private Integer shipUNSanctionList;
}

파일 보기

@ -1,35 +0,0 @@
package com.snp.batch.jobs.web.compliance.service;
import com.snp.batch.jobs.web.compliance.dto.ComplianceBypassDto;
import com.snp.batch.common.web.service.BaseBypassService;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
/**
* IMO 기반 선박 Compliance 조회 bypass 서비스
* 외부 Maritime API에서 데이터를 실시간 조회하여 그대로 반환
*/
@Service
public class ComplianceBypassService extends BaseBypassService<ComplianceBypassDto> {
public ComplianceBypassService(
@Qualifier("maritimeServiceApiWebClient") WebClient webClient) {
super(webClient, "/RiskAndCompliance/CompliancesByImos", "IMO 기반 선박 Compliance 조회",
new ParameterizedTypeReference<>() {},
new ParameterizedTypeReference<>() {});
}
/**
* IMO 기반 선박 Compliance 조회 데이터를 조회합니다.
*
* @return IMO 기반 선박 Compliance 조회
*/
public List<ComplianceBypassDto> getComplianceData(String imos) {
return fetchGetList(uri -> uri.path(getApiPath())
.queryParam("imos", imos)
.build());
}
}

파일 보기

@ -50,20 +50,34 @@ public class BypassCodeGenerator {
for (BypassApiConfig config : configs) { for (BypassApiConfig config : configs) {
String endpointName = config.getEndpointName(); String endpointName = config.getEndpointName();
String dtoCode = generateDtoCode(domain, endpointName, config.getFields()); String dtoPath = basePath + "/dto/" + endpointName + "Dto.java";
String serviceCode = generateServiceCode(domain, endpointName, config, config.getParams()); String servicePath = basePath + "/service/" + endpointName + "Service.java";
Path dtoFilePath = writeFile(basePath + "/dto/" + endpointName + "Dto.java", dtoCode, force); // Service/DTO: 이미 존재하면 스킵 (force=true면 재생성)
Path serviceFilePath = writeFile(basePath + "/service/" + endpointName + "Service.java", serviceCode, force); if (!force && Files.exists(Path.of(dtoPath))) {
log.info("DTO 파일 이미 존재, 스킵: {}", dtoPath);
dtoPaths.add(dtoPath);
} else {
String dtoCode = generateDtoCode(domain, endpointName, config.getFields());
Path dtoFilePath = writeFile(dtoPath, dtoCode, true);
dtoPaths.add(dtoFilePath.toString());
}
dtoPaths.add(dtoFilePath.toString()); if (!force && Files.exists(Path.of(servicePath))) {
servicePaths.add(serviceFilePath.toString()); log.info("Service 파일 이미 존재, 스킵: {}", servicePath);
servicePaths.add(servicePath);
} else {
String serviceCode = generateServiceCode(domain, endpointName, config, config.getParams());
Path serviceFilePath = writeFile(servicePath, serviceCode, true);
servicePaths.add(serviceFilePath.toString());
}
} }
// Controller: 모든 엔드포인트를 합치므로 항상 재생성
String controllerCode = generateControllerCode(domain, configs); String controllerCode = generateControllerCode(domain, configs);
String domainCapitalized = capitalize(domain); String domainCapitalized = capitalize(domain);
Path controllerFilePath = writeFile( Path controllerFilePath = writeFile(
basePath + "/controller/" + domainCapitalized + "Controller.java", controllerCode, force); basePath + "/controller/" + domainCapitalized + "Controller.java", controllerCode, true);
log.info("코드 생성 완료 - domain: {}, endpoints: {}, controller: {}", log.info("코드 생성 완료 - domain: {}, endpoints: {}, controller: {}",
domain, configs.stream().map(BypassApiConfig::getEndpointName).toList(), controllerFilePath); domain, configs.stream().map(BypassApiConfig::getEndpointName).toList(), controllerFilePath);