package com.snp.batch.global.controller; import com.snp.batch.common.web.ApiResponse; import com.snp.batch.global.dto.BypassConfigRequest; import com.snp.batch.global.dto.BypassConfigResponse; import com.snp.batch.global.dto.BypassFieldDto; import com.snp.batch.global.dto.CodeGenerationResult; import com.snp.batch.global.model.BypassApiConfig; import com.snp.batch.global.repository.BypassApiConfigRepository; import com.snp.batch.service.BypassCodeGenerator; import com.snp.batch.service.BypassConfigService; import com.snp.batch.service.JsonSchemaParser; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.Map; /** * BYPASS API 설정 관리 및 코드 생성 컨트롤러 */ @Slf4j @RestController @RequestMapping("/api/bypass-config") @RequiredArgsConstructor @Tag(name = "Bypass Config", description = "BYPASS API 설정 관리 및 코드 생성") public class BypassConfigController { private final BypassConfigService bypassConfigService; private final BypassCodeGenerator bypassCodeGenerator; private final JsonSchemaParser jsonSchemaParser; private final BypassApiConfigRepository configRepository; @Operation(summary = "설정 목록 조회") @GetMapping public ResponseEntity>> getConfigs() { return ResponseEntity.ok(ApiResponse.success(bypassConfigService.getConfigs())); } @Operation(summary = "설정 상세 조회") @GetMapping("/{id}") public ResponseEntity> getConfig(@PathVariable Long id) { return ResponseEntity.ok(ApiResponse.success(bypassConfigService.getConfig(id))); } @Operation(summary = "설정 등록") @PostMapping public ResponseEntity> createConfig( @RequestBody BypassConfigRequest request) { return ResponseEntity.ok(ApiResponse.success(bypassConfigService.createConfig(request))); } @Operation(summary = "설정 수정") @PutMapping("/{id}") public ResponseEntity> updateConfig( @PathVariable Long id, @RequestBody BypassConfigRequest request) { return ResponseEntity.ok(ApiResponse.success(bypassConfigService.updateConfig(id, request))); } @Operation(summary = "설정 삭제") @DeleteMapping("/{id}") public ResponseEntity> deleteConfig(@PathVariable Long id) { bypassConfigService.deleteConfig(id); return ResponseEntity.ok(ApiResponse.success("삭제 완료", null)); } @Operation( summary = "코드 생성", description = "등록된 설정의 도메인 전체를 기반으로 Controller, Service, DTO Java 소스 코드를 생성합니다. 같은 도메인의 모든 설정을 하나의 Controller로 합칩니다." ) @PostMapping("/{id}/generate") public ResponseEntity> generateCode( @PathVariable Long id, @RequestParam(defaultValue = "false") boolean force) { try { BypassApiConfig config = configRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("설정을 찾을 수 없습니다: " + id)); // 같은 도메인의 모든 설정을 조회하여 함께 생성 List domainConfigs = configRepository.findByDomainNameOrderById(config.getDomainName()); CodeGenerationResult result = bypassCodeGenerator.generate(domainConfigs, force); // 같은 도메인의 모든 설정을 generated로 마킹 domainConfigs.forEach(c -> bypassConfigService.markAsGenerated(c.getId())); return ResponseEntity.ok(ApiResponse.success(result)); } catch (IllegalStateException e) { return ResponseEntity.badRequest().body(ApiResponse.error(e.getMessage())); } catch (Exception e) { log.error("코드 생성 실패", e); return ResponseEntity.internalServerError().body(ApiResponse.error("코드 생성 실패: " + e.getMessage())); } } @Operation( summary = "JSON 샘플 파싱", description = "JSON 샘플에서 DTO 필드 목록을 추출합니다." ) @PostMapping("/parse-json") public ResponseEntity>> parseJson(@RequestBody String jsonSample) { try { List fields = jsonSchemaParser.parse(jsonSample); return ResponseEntity.ok(ApiResponse.success(fields)); } catch (Exception e) { return ResponseEntity.badRequest().body(ApiResponse.error("JSON 파싱 실패: " + e.getMessage())); } } @Operation( summary = "WebClient 빈 목록", description = "사용 가능한 WebClient 빈 이름 목록을 반환합니다." ) @GetMapping("/webclient-beans") public ResponseEntity>>> getWebclientBeans() { List> beans = List.of( Map.of("name", "maritimeApiWebClient", "description", "Ship API (shipsapi.maritime.spglobal.com)"), Map.of("name", "maritimeAisApiWebClient", "description", "AIS API (aisapi.maritime.spglobal.com)"), Map.of("name", "maritimeServiceApiWebClient", "description", "Web Service API (webservices.maritime.spglobal.com)") ); return ResponseEntity.ok(ApiResponse.success(beans)); } }