From 5b98819191d2e9ebc3434a65e9351e8f628e3808 Mon Sep 17 00:00:00 2001
From: dohyeons
Date: Thu, 27 Nov 2025 12:08:18 +0900
Subject: [PATCH] =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EB=B0=B0=EC=B9=98=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20API?=
=?UTF-8?q?=20=EC=9D=91=EB=8B=B5=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20?=
=?UTF-8?q?=EB=B0=8F=20access=5Ftoken=20=EB=A7=A4=ED=95=91=20=ED=8E=B8?=
=?UTF-8?q?=EC=A7=91=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?=
=?UTF-8?q?=EA=B0=9C=EC=84=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../(main)/admin/batchmng/edit/[id]/page.tsx | 201 +++++++++++++++++-
1 file changed, 193 insertions(+), 8 deletions(-)
diff --git a/frontend/app/(main)/admin/batchmng/edit/[id]/page.tsx b/frontend/app/(main)/admin/batchmng/edit/[id]/page.tsx
index 5f87e0d0..4c1d9fba 100644
--- a/frontend/app/(main)/admin/batchmng/edit/[id]/page.tsx
+++ b/frontend/app/(main)/admin/batchmng/edit/[id]/page.tsx
@@ -7,12 +7,24 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { RefreshCw, Save, ArrowLeft, Plus, Trash2 } from "lucide-react";
import { toast } from "sonner";
-import { BatchAPI, BatchConfig, BatchMapping, ConnectionInfo } from "@/lib/api/batch";
+import {
+ BatchAPI,
+ BatchConfig,
+ BatchMapping,
+ ConnectionInfo,
+} from "@/lib/api/batch";
+import { BatchManagementAPI } from "@/lib/api/batchManagement";
interface BatchColumnInfo {
column_name: string;
@@ -66,6 +78,9 @@ export default function BatchEditPage() {
// 배치 타입 감지
const [batchType, setBatchType] = useState<'db-to-db' | 'restapi-to-db' | 'db-to-restapi' | null>(null);
+ // REST API 미리보기 상태
+ const [apiPreviewData, setApiPreviewData] = useState([]);
+
// 페이지 로드 시 배치 정보 조회
useEffect(() => {
@@ -335,6 +350,86 @@ export default function BatchEditPage() {
setMappings([...mappings, newMapping]);
};
+ // REST API → DB 매핑 추가
+ const addRestapiToDbMapping = () => {
+ if (!batchConfig || !batchConfig.batch_mappings || batchConfig.batch_mappings.length === 0) {
+ return;
+ }
+
+ const first = batchConfig.batch_mappings[0] as any;
+
+ const newMapping: BatchMapping = {
+ // FROM: REST API (기존 설정 그대로 복사)
+ from_connection_type: "restapi" as any,
+ from_connection_id: first.from_connection_id,
+ from_table_name: first.from_table_name,
+ from_column_name: "",
+ from_column_type: "",
+ // TO: DB (기존 설정 그대로 복사)
+ to_connection_type: first.to_connection_type as any,
+ to_connection_id: first.to_connection_id,
+ to_table_name: first.to_table_name,
+ to_column_name: "",
+ to_column_type: "",
+ mapping_type: (first.mapping_type as any) || "direct",
+ mapping_order: mappings.length + 1,
+ };
+
+ setMappings((prev) => [...prev, newMapping]);
+ };
+
+ // REST API 데이터 미리보기 (수정 화면용)
+ const previewRestApiData = async () => {
+ if (!mappings || mappings.length === 0) {
+ toast.error("미리보기할 REST API 매핑이 없습니다.");
+ return;
+ }
+
+ const first: any = mappings[0];
+
+ if (!first.from_api_url || !first.from_table_name) {
+ toast.error("API URL과 엔드포인트 정보가 없습니다.");
+ return;
+ }
+
+ try {
+ const method =
+ (first.from_api_method as "GET" | "POST" | "PUT" | "DELETE") || "GET";
+
+ const paramInfo =
+ first.from_api_param_type &&
+ first.from_api_param_name &&
+ first.from_api_param_value
+ ? {
+ paramType: first.from_api_param_type as "url" | "query",
+ paramName: first.from_api_param_name as string,
+ paramValue: first.from_api_param_value as string,
+ paramSource:
+ (first.from_api_param_source as "static" | "dynamic") ||
+ "static",
+ }
+ : undefined;
+
+ const result = await BatchManagementAPI.previewRestApiData(
+ first.from_api_url,
+ first.from_api_key || "",
+ first.from_table_name,
+ method,
+ paramInfo,
+ first.from_api_body || undefined
+ );
+
+ setApiPreviewData(result.samples || []);
+
+ toast.success(
+ `API 데이터 미리보기 완료! ${result.fields.length}개 필드, ${result.samples.length}개 레코드`
+ );
+ } catch (error) {
+ console.error("REST API 미리보기 오류:", error);
+ toast.error("API 데이터 미리보기에 실패했습니다.");
+ }
+ };
+
// 매핑 삭제
const removeMapping = (index: number) => {
const updatedMappings = mappings.filter((_, i) => i !== index);
@@ -637,6 +732,37 @@ export default function BatchEditPage() {
배치가 실행될 때 이 내용이 그대로 전송됩니다.
+
+ {/* API 데이터 미리보기 */}
+
+
+
+ {apiPreviewData.length > 0 && (
+
+
+ 샘플 데이터 (최대 3개)
+
+
+ {apiPreviewData.slice(0, 3).map((item, index) => (
+
+ {JSON.stringify(item, null, 2)}
+
+ ))}
+
+
+ )}
+
)}
@@ -687,6 +813,12 @@ export default function BatchEditPage() {
매핑 추가
)}
+ {batchType === 'restapi-to-db' && (
+
+ )}
@@ -791,20 +923,73 @@ export default function BatchEditPage() {
매핑 #{index + 1}
-
- API 필드: {mapping.from_column_name} → DB 컬럼: {mapping.to_column_name}
-
+ {mapping.from_column_name && mapping.to_column_name && (
+
+ API 필드: {mapping.from_column_name} → DB 컬럼: {mapping.to_column_name}
+
+ )}
+