feat: scaffold tools from declared fields
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m39s

This commit is contained in:
jade
2026-08-09 17:50:06 +09:00
parent c0567ec1c2
commit 813c846f05
4 changed files with 196 additions and 2 deletions

View File

@@ -18,6 +18,8 @@ package io.shinhanlife.dap.mcg.presentation;
import io.shinhanlife.dap.lib.util.PodScaffolder;
import io.shinhanlife.dap.lib.util.ToolScaffolder;
import io.shinhanlife.dap.lib.util.ToolSourceUpdater;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@@ -66,8 +68,13 @@ public class ScaffoldingController {
String clientSystemCode = req.get("clientSystemCode");
String inputSchemaResource = req.get("inputSchemaResource");
String outputSchemaResource = req.get("outputSchemaResource");
List<ToolScaffolder.FieldDefinition> inputFields = parseFields(req.get("inputFields"));
List<ToolScaffolder.FieldDefinition> outputFields = parseFields(req.get("outputFields"));
if (inputFields.isEmpty()) {
inputFields = List.of(new ToolScaffolder.FieldDefinition("query", "String", "Search query", "example", false));
}
return ToolScaffolder.scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, date, register, clientSystemCode, inputSchemaResource, outputSchemaResource);
return ToolScaffolder.scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, date, register, clientSystemCode, inputSchemaResource, outputSchemaResource, inputFields, outputFields);
} catch (Exception e) {
return "오류 발생: " + e.getMessage();
}
@@ -107,4 +114,11 @@ public class ScaffoldingController {
return List.of("dap-was-oth", "dap-was-hr", "dap-was-sms");
}
}
private List<ToolScaffolder.FieldDefinition> parseFields(String source) throws Exception {
if (source == null || source.isBlank()) {
return List.of();
}
return new ObjectMapper().readValue(source, new TypeReference<List<ToolScaffolder.FieldDefinition>>() { });
}
}

View File

@@ -495,6 +495,29 @@
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label mb-0">Input Fields (JSON)</label>
<div class="d-flex gap-1">
<button type="button" class="btn-secondary-action" style="padding: 0.2rem 0.45rem; font-size: 0.72rem;" onclick="loadFieldExample('inputFields')">예제 넣기</button>
<button type="button" class="btn-secondary-action" style="padding: 0.2rem 0.45rem; font-size: 0.72rem;" onclick="copyFieldJson('inputFields')">복사</button>
</div>
</div>
<textarea id="inputFields" class="form-control" name="inputFields" rows="4" placeholder='[{"name":"employeeId","type":"String","description":"Employee ID","example":"EMP10001","required":true}]'></textarea>
</div>
<div class="col-md-6 mt-3 mt-md-0">
<div class="d-flex justify-content-between align-items-center mb-1">
<label class="form-label mb-0">Output Fields (JSON)</label>
<div class="d-flex gap-1">
<button type="button" class="btn-secondary-action" style="padding: 0.2rem 0.45rem; font-size: 0.72rem;" onclick="loadFieldExample('outputFields')">예제 넣기</button>
<button type="button" class="btn-secondary-action" style="padding: 0.2rem 0.45rem; font-size: 0.72rem;" onclick="copyFieldJson('outputFields')">복사</button>
</div>
</div>
<textarea id="outputFields" class="form-control" name="outputFields" rows="4" placeholder='[{"name":"employeeName","type":"String","description":"Employee name","example":"Hong Gildong","required":true}]'></textarea>
</div>
</div>
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">Target Module</label>
@@ -685,6 +708,33 @@
handleFormSubmit('podForm', '/api/v1/scaffold/pod');
handleFormSubmit('toolForm', '/api/v1/scaffold/tool');
const fieldExamples = {
inputFields: [
{ name: 'employeeId', type: 'String', description: 'Employee identifier', example: 'EMP10001', required: true },
{ name: 'page', type: 'Integer', description: 'Page number', example: '1', required: false }
],
outputFields: [
{ name: 'employeeName', type: 'String', description: 'Employee name', example: 'Hong Gildong', required: true }
]
};
function loadFieldExample(fieldId) {
document.getElementById(fieldId).value = JSON.stringify(fieldExamples[fieldId], null, 2);
}
async function copyFieldJson(fieldId) {
const textarea = document.getElementById(fieldId);
const value = textarea.value.trim() || JSON.stringify(fieldExamples[fieldId], null, 2);
try {
await navigator.clipboard.writeText(value);
} catch (error) {
textarea.value = value;
textarea.select();
document.execCommand('copy');
textarea.setSelectionRange(0, 0);
}
}
function loadToolList() {
const tbody = document.getElementById('toolListBody');
tbody.innerHTML = '<tr><td colspan="5" class="text-center py-5 text-muted">Loading data...</td></tr>';