559 lines
27 KiB
Java
559 lines
27 KiB
Java
package com.erp.controller;
|
|
|
|
import com.erp.dto.ApiResponse;
|
|
import com.erp.service.FlowService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Flow API Controller
|
|
* Base path: /api/flows
|
|
*
|
|
* Definitions : POST/GET/GET-detail/PUT/DELETE /definitions[/:id]
|
|
* Steps : GET/POST /definitions/:flowId/steps
|
|
* PUT/DELETE /steps/:stepId
|
|
* Connections : GET /connections/:flowId
|
|
* POST /connections
|
|
* DELETE /connections/:connectionId
|
|
* Execution : GET /:flowId/step/:stepId/count|list|column-labels
|
|
* GET /:flowId/steps/counts
|
|
* PUT /:flowId/step/:stepId/data/:recordId
|
|
* Data move : POST /move, /move-batch
|
|
* Audit : GET /audit/:flowId, /audit/:flowId/:recordId
|
|
* Procedures : GET /procedures, /procedures/:name/parameters
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/api/flows")
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class FlowController {
|
|
|
|
private final FlowService service;
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Definitions
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@GetMapping("/definitions")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowDefinitionList(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@RequestParam Map<String, Object> params) {
|
|
params.put("company_code", companyCode);
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowDefinitionList(params)));
|
|
}
|
|
|
|
@GetMapping("/definitions/{id}")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> getFlowDefinitionInfo(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("id") int id) {
|
|
Map<String, Object> detail = service.getFlowDefinitionInfo(id, companyCode);
|
|
if (detail == null) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow definition not found"));
|
|
}
|
|
return ResponseEntity.ok(ApiResponse.success(detail));
|
|
}
|
|
|
|
@PostMapping("/definitions")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> insertFlowDefinition(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@RequestAttribute("user_id") String userId,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
if (body.get("name") == null) {
|
|
return ResponseEntity.status(400).body(ApiResponse.error("Name is required"));
|
|
}
|
|
|
|
// 테이블 존재 확인 (REST API / multi 제외)
|
|
String tableName = (String) body.get("table_name");
|
|
String dbSource = (String) body.getOrDefault("db_source_type", "internal");
|
|
boolean skipCheck = "restapi".equals(dbSource)
|
|
|| "multi_restapi".equals(dbSource)
|
|
|| "multi_external_db".equals(dbSource)
|
|
|| (tableName != null && (tableName.startsWith("_restapi_")
|
|
|| tableName.startsWith("_multi_")));
|
|
|
|
if (tableName != null && !skipCheck && !service.checkTableExists(tableName)) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("Table '" + tableName + "' does not exist"));
|
|
}
|
|
|
|
try {
|
|
Map<String, Object> created = service.insertFlowDefinition(body, userId, companyCode);
|
|
return ResponseEntity.ok(ApiResponse.success(created));
|
|
} catch (Exception e) {
|
|
log.error("플로우 정의 생성 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to create flow definition"));
|
|
}
|
|
}
|
|
|
|
@PutMapping("/definitions/{id}")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> updateFlowDefinition(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("id") int id,
|
|
@RequestBody Map<String, Object> body) {
|
|
if (service.getFlowDefinitionById(id, companyCode) == null) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow definition not found"));
|
|
}
|
|
try {
|
|
Map<String, Object> updated = service.updateFlowDefinition(id, body, companyCode);
|
|
return ResponseEntity.ok(ApiResponse.success(updated));
|
|
} catch (Exception e) {
|
|
log.error("플로우 정의 수정 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to update flow definition"));
|
|
}
|
|
}
|
|
|
|
@DeleteMapping("/definitions/{id}")
|
|
public ResponseEntity<ApiResponse<Void>> deleteFlowDefinition(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("id") int id) {
|
|
boolean deleted = service.deleteFlowDefinition(id, companyCode);
|
|
if (!deleted) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow definition not found"));
|
|
}
|
|
return ResponseEntity.ok(ApiResponse.success(null, "Flow definition deleted successfully"));
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Steps (under /definitions/:flowId/steps or /steps/:stepId)
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@GetMapping("/definitions/{flowId}/steps")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowStepList(
|
|
@PathVariable("flow_id") int flowId) {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowStepList(flowId)));
|
|
}
|
|
|
|
@PostMapping("/definitions/{flowId}/steps")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> insertFlowStep(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("flow_id") int flowId,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
if (body.get("step_name") == null || body.get("step_order") == null) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("stepName and stepOrder are required"));
|
|
}
|
|
// 플로우 소유권 확인
|
|
if (service.getFlowDefinitionById(flowId, companyCode) == null) {
|
|
return ResponseEntity.status(404)
|
|
.body(ApiResponse.error("Flow definition not found or access denied"));
|
|
}
|
|
try {
|
|
Map<String, Object> step = service.insertFlowStep(flowId, body);
|
|
return ResponseEntity.ok(ApiResponse.success(step));
|
|
} catch (Exception e) {
|
|
log.error("플로우 스텝 생성 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to create flow step"));
|
|
}
|
|
}
|
|
|
|
@PutMapping("/steps/{stepId}")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> updateFlowStep(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("step_id") int stepId,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
// 스텝 소유권 검증: 스텝이 속한 플로우가 요청자 회사 소유인지 확인
|
|
Map<String, Object> existingStep = service.getFlowStepById(stepId);
|
|
if (existingStep != null) {
|
|
int flowDefId = toInt(existingStep.get("flow_definition_id"), 0);
|
|
if (service.getFlowDefinitionById(flowDefId, companyCode) == null) {
|
|
return ResponseEntity.status(403)
|
|
.body(ApiResponse.error("Access denied: flow does not belong to your company"));
|
|
}
|
|
}
|
|
|
|
try {
|
|
Map<String, Object> step = service.updateFlowStep(stepId, body);
|
|
if (step == null) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow step not found"));
|
|
}
|
|
return ResponseEntity.ok(ApiResponse.success(step));
|
|
} catch (Exception e) {
|
|
log.error("플로우 스텝 수정 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to update flow step"));
|
|
}
|
|
}
|
|
|
|
@DeleteMapping("/steps/{stepId}")
|
|
public ResponseEntity<ApiResponse<Void>> deleteFlowStep(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("step_id") int stepId) {
|
|
|
|
Map<String, Object> existingStep = service.getFlowStepById(stepId);
|
|
if (existingStep != null) {
|
|
int flowDefId = toInt(existingStep.get("flow_definition_id"), 0);
|
|
if (service.getFlowDefinitionById(flowDefId, companyCode) == null) {
|
|
return ResponseEntity.status(403)
|
|
.body(ApiResponse.error("Access denied: flow does not belong to your company"));
|
|
}
|
|
}
|
|
|
|
boolean deleted = service.deleteFlowStep(stepId);
|
|
if (!deleted) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow step not found"));
|
|
}
|
|
return ResponseEntity.ok(ApiResponse.success(null, "Flow step deleted successfully"));
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Connections
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@GetMapping("/connections/{flowId}")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowConnectionList(
|
|
@PathVariable("flow_id") int flowId) {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowConnectionList(flowId)));
|
|
}
|
|
|
|
@PostMapping("/connections")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> insertFlowConnection(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
Object flowDefIdRaw = body.get("flow_definition_id");
|
|
Object fromRaw = body.get("from_step_id");
|
|
Object toRaw = body.get("to_step_id");
|
|
|
|
if (flowDefIdRaw == null || fromRaw == null || toRaw == null) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("flowDefinitionId, fromStepId, and toStepId are required"));
|
|
}
|
|
|
|
int flowDefId = toInt(flowDefIdRaw, 0);
|
|
int fromStepId = toInt(fromRaw, 0);
|
|
int toStepId = toInt(toRaw, 0);
|
|
|
|
// 플로우 소유권 확인
|
|
if (service.getFlowDefinitionById(flowDefId, companyCode) == null) {
|
|
return ResponseEntity.status(404)
|
|
.body(ApiResponse.error("Flow definition not found or access denied"));
|
|
}
|
|
// 스텝 소속 검증
|
|
Map<String, Object> fromStep = service.getFlowStepById(fromStepId);
|
|
Map<String, Object> toStep = service.getFlowStepById(toStepId);
|
|
if (fromStep == null || !String.valueOf(fromStep.get("flow_definition_id")).equals(String.valueOf(flowDefId))
|
|
|| toStep == null || !String.valueOf(toStep.get("flow_definition_id")).equals(String.valueOf(flowDefId))) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("fromStepId and toStepId must belong to the specified flow"));
|
|
}
|
|
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(service.insertFlowConnection(body)));
|
|
} catch (Exception e) {
|
|
log.error("플로우 연결 생성 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to create connection"));
|
|
}
|
|
}
|
|
|
|
@DeleteMapping("/connections/{connectionId}")
|
|
public ResponseEntity<ApiResponse<Void>> deleteFlowConnection(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@PathVariable("connection_id") int connectionId) {
|
|
|
|
Map<String, Object> existingConn = service.getFlowConnectionById(connectionId);
|
|
if (existingConn != null) {
|
|
int flowDefId = toInt(existingConn.get("flow_definition_id"), 0);
|
|
if (service.getFlowDefinitionById(flowDefId, companyCode) == null) {
|
|
return ResponseEntity.status(403)
|
|
.body(ApiResponse.error("Access denied: flow does not belong to your company"));
|
|
}
|
|
}
|
|
boolean deleted = service.deleteFlowConnection(connectionId);
|
|
if (!deleted) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Connection not found"));
|
|
}
|
|
return ResponseEntity.ok(ApiResponse.success(null, "Connection deleted successfully"));
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Execution
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@GetMapping("/{flowId}/step/{stepId}/count")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> getFlowStepDataCount(
|
|
@PathVariable("flow_id") int flowId,
|
|
@PathVariable("step_id") int stepId) {
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowStepDataCount(flowId, stepId)));
|
|
} catch (Exception e) {
|
|
log.error("스텝 카운트 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get step data count"));
|
|
}
|
|
}
|
|
|
|
@GetMapping("/{flowId}/step/{stepId}/list")
|
|
public ResponseEntity<ApiResponse<Object>> getFlowStepDataList(
|
|
@PathVariable("flow_id") int flowId,
|
|
@PathVariable("step_id") int stepId,
|
|
@RequestParam(defaultValue = "1") int page,
|
|
@RequestParam(defaultValue = "20") int pageSize) {
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(
|
|
service.getFlowStepDataList(flowId, stepId, page, pageSize)));
|
|
} catch (Exception e) {
|
|
log.error("스텝 데이터 목록 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get step data list"));
|
|
}
|
|
}
|
|
|
|
@GetMapping("/{flowId}/step/{stepId}/column-labels")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> getFlowColumnLabelList(
|
|
@PathVariable("flow_id") int flowId,
|
|
@PathVariable("step_id") int stepId) {
|
|
try {
|
|
Map<String, Object> step = service.getFlowStepById(stepId);
|
|
if (step == null) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Step not found"));
|
|
}
|
|
Map<String, Object> flow = service.getFlowDefinitionById(flowId, "*");
|
|
if (flow == null) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error("Flow definition not found"));
|
|
}
|
|
Map<String, Object> labels = service.getFlowColumnLabelList(flowId, stepId);
|
|
return ResponseEntity.ok(ApiResponse.success(labels != null ? labels : Map.of()));
|
|
} catch (Exception e) {
|
|
log.error("컬럼 라벨 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get step column labels"));
|
|
}
|
|
}
|
|
|
|
@GetMapping("/{flowId}/steps/counts")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> getFlowStepCountList(
|
|
@PathVariable("flow_id") int flowId) {
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowStepCountList(flowId)));
|
|
} catch (Exception e) {
|
|
log.error("전체 스텝 카운트 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get all step counts"));
|
|
}
|
|
}
|
|
|
|
@PutMapping("/{flowId}/step/{stepId}/data/{recordId}")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> updateFlowStepData(
|
|
@RequestAttribute("company_code") String companyCode,
|
|
@RequestAttribute("user_id") String userId,
|
|
@PathVariable("flow_id") int flowId,
|
|
@PathVariable("step_id") int stepId,
|
|
@PathVariable("record_id") String recordId,
|
|
@RequestBody Map<String, Object> updateData) {
|
|
|
|
if (updateData == null || updateData.isEmpty()) {
|
|
return ResponseEntity.status(400).body(ApiResponse.error("Update data is required"));
|
|
}
|
|
try {
|
|
Map<String, Object> result =
|
|
service.updateFlowStepData(flowId, stepId, recordId, updateData, userId, companyCode);
|
|
return ResponseEntity.ok(ApiResponse.success(result, "Data updated successfully"));
|
|
} catch (IllegalArgumentException e) {
|
|
return ResponseEntity.status(404).body(ApiResponse.error(e.getMessage()));
|
|
} catch (Exception e) {
|
|
log.error("스텝 데이터 수정 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to update step data"));
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Data Move
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@PostMapping("/move")
|
|
public ResponseEntity<ApiResponse<Void>> moveData(
|
|
@RequestAttribute("user_id") String userId,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
Object flowId = body.get("flow_id");
|
|
Object fromStepId = body.get("from_step_id");
|
|
Object recordId = body.get("record_id");
|
|
Object toStepId = body.get("to_step_id");
|
|
|
|
if (flowId == null || fromStepId == null || recordId == null || toStepId == null) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("flowId, fromStepId, recordId, and toStepId are required"));
|
|
}
|
|
try {
|
|
service.moveDataToStep(
|
|
toInt(flowId, 0), toInt(fromStepId, 0), toInt(toStepId, 0),
|
|
recordId.toString(), userId, (String) body.get("note"));
|
|
return ResponseEntity.ok(ApiResponse.success(null, "Data moved successfully"));
|
|
} catch (Exception e) {
|
|
log.error("데이터 이동 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to move data"));
|
|
}
|
|
}
|
|
|
|
@PostMapping("/move-batch")
|
|
public ResponseEntity<ApiResponse<Map<String, Object>>> moveBatchData(
|
|
@RequestAttribute("user_id") String userId,
|
|
@RequestBody Map<String, Object> body) {
|
|
|
|
Object flowId = body.get("flow_id");
|
|
Object fromStepId = body.get("from_step_id");
|
|
Object toStepId = body.get("to_step_id");
|
|
Object dataIds = body.get("data_ids");
|
|
|
|
if (flowId == null || fromStepId == null || toStepId == null
|
|
|| !(dataIds instanceof List)) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error(
|
|
"flowId, fromStepId, toStepId, and dataIds (array) are required"));
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
List<Object> ids = (List<Object>) dataIds;
|
|
|
|
try {
|
|
Map<String, Object> result = service.moveBatchData(
|
|
toInt(flowId, 0), toInt(fromStepId, 0), toInt(toStepId, 0), ids, userId);
|
|
|
|
long successCount = ids.stream()
|
|
.filter(id -> result.get("results") instanceof List<?> list
|
|
&& list.stream().anyMatch(r ->
|
|
r instanceof Map<?, ?> m
|
|
&& Boolean.TRUE.equals(m.get("success"))
|
|
&& id.toString().equals(String.valueOf(m.get("id")))))
|
|
.count();
|
|
long failureCount = ids.size() - successCount;
|
|
|
|
boolean overallSuccess = (boolean) result.get("success");
|
|
String message = overallSuccess
|
|
? successCount + "건의 데이터를 성공적으로 이동했습니다"
|
|
: successCount + "건 성공, " + failureCount + "건 실패";
|
|
|
|
Map<String, Object> data = new java.util.LinkedHashMap<>();
|
|
data.put("success_count", successCount);
|
|
data.put("failure_count", failureCount);
|
|
data.put("total", ids.size());
|
|
result.put("message", message);
|
|
result.put("data", data);
|
|
|
|
return ResponseEntity.ok(ApiResponse.success(result));
|
|
} catch (Exception e) {
|
|
log.error("배치 데이터 이동 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to move batch data"));
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Audit Logs
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
/** GET /audit/:flowId — 플로우 전체 이력 */
|
|
@GetMapping("/audit/{flowId}")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowAuditLogList(
|
|
@PathVariable("flow_id") int flowId,
|
|
@RequestParam(defaultValue = "100") int limit) {
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowAuditLogList(flowId, limit)));
|
|
} catch (Exception e) {
|
|
log.error("플로우 감사 로그 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get flow audit logs"));
|
|
}
|
|
}
|
|
|
|
/** GET /audit/:flowId/:recordId — 특정 레코드 이력 */
|
|
@GetMapping("/audit/{flowId}/{recordId}")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowAuditLogListByRecord(
|
|
@PathVariable("flow_id") int flowId,
|
|
@PathVariable("record_id") String recordId) {
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowAuditLogListByRecord(flowId, recordId)));
|
|
} catch (Exception e) {
|
|
log.error("감사 로그 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "Failed to get audit logs"));
|
|
}
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════════════
|
|
// Procedures
|
|
// ══════════════════════════════════════════════════════════
|
|
|
|
@GetMapping("/procedures")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowProcedureList(
|
|
@RequestParam(required = false) String dbSource,
|
|
@RequestParam(required = false) Integer connectionId,
|
|
@RequestParam(required = false) String schema) {
|
|
|
|
if (dbSource != null && !"internal".equals(dbSource) && !"external".equals(dbSource)) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("dbSource는 internal 또는 external이어야 합니다"));
|
|
}
|
|
if ("external".equals(dbSource) && connectionId == null) {
|
|
return ResponseEntity.status(400)
|
|
.body(ApiResponse.error("외부 DB 조회 시 connectionId가 필요합니다"));
|
|
}
|
|
|
|
try {
|
|
// 현재 구현은 internal DB만 지원 (external은 별도 연결 관리가 필요)
|
|
return ResponseEntity.ok(ApiResponse.success(service.getFlowProcedureList(schema)));
|
|
} catch (Exception e) {
|
|
log.error("프로시저 목록 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "프로시저 목록 조회에 실패했습니다"));
|
|
}
|
|
}
|
|
|
|
@GetMapping("/procedures/{name}/parameters")
|
|
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getFlowProcedureParameterList(
|
|
@PathVariable("name") String name,
|
|
@RequestParam(required = false) String dbSource,
|
|
@RequestParam(required = false) Integer connectionId,
|
|
@RequestParam(required = false) String schema) {
|
|
|
|
if (name == null || name.isBlank()) {
|
|
return ResponseEntity.status(400).body(ApiResponse.error("프로시저 이름이 필요합니다"));
|
|
}
|
|
try {
|
|
return ResponseEntity.ok(ApiResponse.success(
|
|
service.getFlowProcedureParameterList(name, schema)));
|
|
} catch (Exception e) {
|
|
log.error("프로시저 파라미터 조회 실패", e);
|
|
return ResponseEntity.status(500)
|
|
.body(ApiResponse.error(e.getMessage() != null ? e.getMessage()
|
|
: "프로시저 파라미터 조회에 실패했습니다"));
|
|
}
|
|
}
|
|
|
|
// ── private helper ────────────────────────────────────────
|
|
private int toInt(Object val, int defaultVal) {
|
|
if (val == null) return defaultVal;
|
|
try { return Integer.parseInt(val.toString()); }
|
|
catch (NumberFormatException e) { return defaultVal; }
|
|
}
|
|
}
|