- DTO 생성 제거: 모든 BYPASS API가 JsonNode로 응답 패스스루 - bypass_api_field 테이블 관련 코드 삭제 (Entity, Repository, DTO, JsonSchemaParser) - 코드 생성기: Service만 생성 (DTO 없음), JsonNode 반환 - 프론트엔드: 3단계 → 2단계 폼 축소 (기본 정보 + 파라미터) - BypassStepFields, responseType 관련 코드 전면 제거 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
154 lines
4.2 KiB
Java
154 lines
4.2 KiB
Java
package com.snp.batch.global.model;
|
|
|
|
import jakarta.persistence.*;
|
|
import lombok.*;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* BYPASS API 설정 정보를 저장하는 엔티티
|
|
* 외부 API를 동적으로 프록시하기 위한 설정 메타데이터
|
|
*
|
|
* JPA를 사용하므로 @PrePersist, @PreUpdate로 감사 필드 자동 설정
|
|
*/
|
|
@Entity
|
|
@Table(name = "bypass_api_config",
|
|
uniqueConstraints = {
|
|
@UniqueConstraint(name = "uk_bypass_config_domain_endpoint", columnNames = {"domain_name", "endpoint_name"})
|
|
},
|
|
indexes = {
|
|
@Index(name = "idx_bypass_config_domain_name", columnList = "domain_name")
|
|
}
|
|
)
|
|
@Getter
|
|
@Setter
|
|
@Builder
|
|
@NoArgsConstructor
|
|
@AllArgsConstructor
|
|
public class BypassApiConfig {
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
/**
|
|
* 도메인명 (패키지명/URL 경로)
|
|
* 예: "ship-info", "port-data"
|
|
*/
|
|
@Column(name = "domain_name", nullable = false, length = 50)
|
|
private String domainName;
|
|
|
|
/**
|
|
* 엔드포인트명 (externalPath의 마지막 세그먼트에서 자동 추출)
|
|
* 예: "CompliancesByImos", "CompanyCompliancesByImos"
|
|
*/
|
|
@Column(name = "endpoint_name", nullable = false, length = 100)
|
|
private String endpointName;
|
|
|
|
/**
|
|
* 표시명
|
|
* 예: "선박 정보 API", "항만 데이터 API"
|
|
*/
|
|
@Column(name = "display_name", nullable = false, length = 100)
|
|
private String displayName;
|
|
|
|
/**
|
|
* WebClient 빈 이름
|
|
* 예: "maritimeWebClient", "portWebClient"
|
|
*/
|
|
@Column(name = "webclient_bean", nullable = false, length = 100)
|
|
private String webclientBean;
|
|
|
|
/**
|
|
* 외부 API 경로
|
|
* 예: "/api/v1/ships/{imoNumber}"
|
|
*/
|
|
@Column(name = "external_path", nullable = false, length = 500)
|
|
private String externalPath;
|
|
|
|
/**
|
|
* HTTP 메서드
|
|
* 예: "GET", "POST"
|
|
*/
|
|
@Column(name = "http_method", nullable = false, length = 10)
|
|
@Builder.Default
|
|
private String httpMethod = "GET";
|
|
|
|
/**
|
|
* 설명
|
|
*/
|
|
@Column(name = "description", length = 1000)
|
|
private String description;
|
|
|
|
/**
|
|
* 코드 생성 완료 여부
|
|
*/
|
|
@Column(name = "generated", nullable = false)
|
|
@Builder.Default
|
|
private Boolean generated = false;
|
|
|
|
/**
|
|
* 코드 생성 일시
|
|
*/
|
|
@Column(name = "generated_at")
|
|
private LocalDateTime generatedAt;
|
|
|
|
/**
|
|
* 생성 일시 (감사 필드)
|
|
*/
|
|
@Column(name = "created_at", nullable = false, updatable = false)
|
|
private LocalDateTime createdAt;
|
|
|
|
/**
|
|
* 수정 일시 (감사 필드)
|
|
*/
|
|
@Column(name = "updated_at", nullable = false)
|
|
private LocalDateTime updatedAt;
|
|
|
|
/**
|
|
* API 파라미터 목록
|
|
*/
|
|
@OneToMany(mappedBy = "config", cascade = CascadeType.ALL, orphanRemoval = true)
|
|
@Builder.Default
|
|
private List<BypassApiParam> params = new ArrayList<>();
|
|
|
|
/**
|
|
* 엔티티 저장 전 자동 호출 (INSERT 시)
|
|
* endpointName이 null이면 externalPath에서 자동 추출 (마이그레이션 대응)
|
|
*/
|
|
@PrePersist
|
|
protected void onCreate() {
|
|
LocalDateTime now = LocalDateTime.now();
|
|
this.createdAt = now;
|
|
this.updatedAt = now;
|
|
if (this.endpointName == null || this.endpointName.isEmpty()) {
|
|
this.endpointName = extractEndpointName(this.externalPath);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 엔티티 업데이트 전 자동 호출 (UPDATE 시)
|
|
* endpointName이 null이면 externalPath에서 자동 추출 (마이그레이션 대응)
|
|
*/
|
|
private static String extractEndpointName(String externalPath) {
|
|
if (externalPath == null || externalPath.isEmpty()) {
|
|
return "";
|
|
}
|
|
String[] segments = externalPath.split("/");
|
|
return segments[segments.length - 1];
|
|
}
|
|
|
|
/**
|
|
* 엔티티 업데이트 전 자동 호출 (UPDATE 시)
|
|
*/
|
|
@PreUpdate
|
|
protected void onUpdate() {
|
|
this.updatedAt = LocalDateTime.now();
|
|
if (this.endpointName == null || this.endpointName.isEmpty()) {
|
|
this.endpointName = extractEndpointName(this.externalPath);
|
|
}
|
|
}
|
|
}
|