summaryrefslogtreecommitdiff
path: root/lib/sedp/sync-form.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sedp/sync-form.ts')
-rw-r--r--lib/sedp/sync-form.ts503
1 files changed, 306 insertions, 197 deletions
diff --git a/lib/sedp/sync-form.ts b/lib/sedp/sync-form.ts
index 2cb677b7..c293c98e 100644
--- a/lib/sedp/sync-form.ts
+++ b/lib/sedp/sync-form.ts
@@ -1,6 +1,6 @@
// src/lib/cron/syncTagFormMappings.ts
import db from "@/db/db";
-import { projects, tagTypes, tagClasses, tagTypeClassFormMappings, formMetas, forms, contractItems, items, contracts } from '@/db/schema';
+import { projects, tagTypes, tagClasses, tagTypeClassFormMappings, formMetas, forms, contractItems, items, contracts, templateItems } from '@/db/schema';
import { eq, and, inArray, ilike } from 'drizzle-orm';
import { getSEDPToken } from "./sedp-token";
@@ -37,6 +37,51 @@ interface FormRecord {
createdAt: Date;
updatedAt: Date;
}
+
+interface TemplateItem {
+ TMPL_ID: string;
+ NAME: string;
+ TMPL_TYPE: string;
+ SPR_LST_SETUP: {
+ ACT_SHEET: string;
+ HIDN_SHEETS: Array<string>;
+ CONTENT?: string;
+ DATA_SHEETS: Array<{
+ SHEET_NAME: string;
+ REG_TYPE_ID: string;
+ MAP_CELL_ATT: Array<{
+ ATT_ID: string;
+ IN: string;
+ }>;
+ }>;
+ };
+ GRD_LST_SETUP: {
+ REG_TYPE_ID: string;
+ SPR_ITM_IDS: Array<string>;
+ ATTS: Array<{
+ ATT_ID: string;
+ ALIAS: string;
+ HEAD_TEXT: string;
+ HIDN_YN: boolean;
+ SEQ:number;
+ DFLT_YN:boolean;
+ }>;
+ };
+ SPR_ITM_LST_SETUP: {
+ ACT_SHEET: string;
+ HIDN_SHEETS: Array<string>;
+ CONTENT?: string;
+ DATA_SHEETS: Array<{
+ SHEET_NAME: string;
+ REG_TYPE_ID: string;
+ MAP_CELL_ATT: Array<{
+ ATT_ID: string;
+ IN: string;
+ }>;
+ }>;
+ };
+}
+
interface Register {
PROJ_NO: string;
TYPE_ID: string;
@@ -75,6 +120,42 @@ interface LinkAttribute {
UOM_ID: string | null;
}
+interface newRegister {
+ PROJ_NO: string;
+ MAP_ID: string;
+ EP_ID: string;
+ CATEGORY: string;
+ BYPASS: boolean;
+ REG_TYPE_ID: string;
+ TOOL_ID: string;
+ TOOL_TYPE: string;
+ MAP_CLS: {
+ TOOL_ATT_NAME: string;
+ ITEMS: ClassItmes[];
+ };
+ MAP_ATT: MapAttribute[];
+ MAP_TMPLS: string[];
+ CRTER_NO: string;
+ CRTE_DTM: string;
+ CHGER_NO: string;
+ _id: string;
+}
+
+
+
+interface ClassItmes {
+ SEDP_OBJ_CLS_ID: string;
+ TOOL_VALS: string;
+ ISDEFALUT: boolean;
+}
+
+interface MapAttribute {
+ SEDP_ATT_ID: string;
+ TOOL_ATT_NAME: string;
+ KEY_YN: boolean;
+ INOUT: string | null;
+}
+
interface Attribute {
PROJ_NO: string;
ATT_ID: string;
@@ -167,6 +248,9 @@ interface FormColumn {
uom?: string;
uomId?: string;
shi?: Boolean;
+ hidden?: boolean;
+ seq?: number;
+ head?: string;
}
// 아이템 코드 추출 함수
@@ -249,6 +333,63 @@ async function getDefaulTAttributes(): Promise<string[]> {
}
}
+async function fetchTemplateFromSEDP(projectCode: string, formCode: string): Promise<TemplateItem[]> {
+ try {
+ // Get the token
+ const apiKey = await getSEDPToken();
+
+ // Make the API call
+ const response = await fetch(
+ `${SEDP_API_BASE_URL}/Template/GetByRegisterID`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'accept': '*/*',
+ 'ApiKey': apiKey,
+ 'ProjectNo': projectCode
+ },
+ body: JSON.stringify({
+ WithContent: true,
+ ProjectNo: projectCode,
+ REG_TYPE_ID: formCode
+ })
+ }
+ );
+
+ if (!response.ok) {
+ if (response.status === 404) {
+ console.warn(`템플릿을 찾을 수 없음: ${formCode}`);
+ return [];
+ }
+ const errorText = await response.text();
+ throw new Error(`SEDP Template API request failed: ${response.status} ${response.statusText} - ${errorText}`);
+ }
+
+ // 안전하게 JSON 파싱
+ try {
+ const data = await response.json();
+ // 데이터가 배열인지 확인
+ const templates: TemplateItem[] = Array.isArray(data) ? data : [data];
+ return templates.filter(template => template && template.TMPL_ID);
+ } catch (parseError) {
+ console.error(`템플릿 응답 파싱 실패:`, parseError);
+ // 응답 내용 로깅
+ try {
+ const text = await response.clone().text();
+ console.log(`응답 내용: ${text.substring(0, 200)}${text.length > 200 ? '...' : ''}`);
+ } catch (textError) {
+ console.error('응답 내용 로깅 실패:', textError);
+ }
+ return [];
+ }
+ } catch (error: any) {
+ console.error('Error calling SEDP Template API:', error);
+ console.warn(`템플릿 가져오기 실패 (${formCode}): ${error.message || 'Unknown error'}`);
+ return [];
+ }
+}
+
// 레지스터 데이터 가져오기
async function getRegisters(projectCode: string): Promise<Register[]> {
try {
@@ -315,6 +456,55 @@ async function getRegisters(projectCode: string): Promise<Register[]> {
}
}
+async function getNewRegisters(projectCode: string): Promise<newRegister[]> {
+ try {
+ // 토큰(API 키) 가져오기
+ const apiKey = await getSEDPToken();
+
+ const response = await fetch(
+ `${SEDP_API_BASE_URL}/AdapterDataMapping/GetByToolID`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'accept': '*/*',
+ 'ApiKey': apiKey,
+ 'ProjectNo': projectCode
+ },
+ body: JSON.stringify({
+ ProjectNo: projectCode,
+ "TOOL_ID": "eVCP"
+ })
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error(`새 레지스터 요청 실패: ${response.status} ${response.statusText}`);
+ }
+
+ // 안전하게 JSON 파싱
+ let data;
+ try {
+ data = await response.json();
+ } catch (parseError) {
+ console.error(`프로젝트 ${projectCode}의 새 레지스터 응답 파싱 실패:`, parseError);
+ // 응답 내용 로깅
+ const text = await response.clone().text();
+ console.log(`응답 내용: ${text.substring(0, 200)}${text.length > 200 ? '...' : ''}`);
+ throw new Error(`새 레지스터 응답 파싱 실패: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
+ }
+
+ // 결과를 배열로 변환 (단일 객체인 경우 배열로 래핑)
+ let registers: newRegister[] = Array.isArray(data) ? data : [data];
+
+ console.log(`프로젝트 ${projectCode}에서 ${registers.length}개의 새 레지스터를 가져왔습니다.`);
+ return registers;
+ } catch (error) {
+ console.error(`프로젝트 ${projectCode}의 새 레지스터 가져오기 실패:`, error);
+ throw error;
+ }
+}
+
// 프로젝트의 모든 속성을 가져와 맵으로 반환
async function getAttributes(projectCode: string): Promise<Map<string, Attribute>> {
try {
@@ -716,249 +906,167 @@ async function getContractItemsByItemCodes(itemCodes: string[], projectId: numbe
}
}
-// 데이터베이스에 태그 타입 클래스 폼 매핑 및 폼 메타 저장
-async function saveFormMappingsAndMetas(
+// UPDATED: saveFormMappingsAndMetas()
+// ------------------------------------
+// Primary loop is **newRegisters**‑first; legacy **registers** are consulted
+// only for supplemental details.
+//
+// 2025‑07‑09 fix: newRegister.MAP_CLS is a **single object**, not an array.
+// Updated class‑ID extraction accordingly.
+//
+export async function saveFormMappingsAndMetas(
projectId: number,
projectCode: string,
- registers: Register[]
+ registers: Register[], // legacy SEDP Register list (supplemental)
+ newRegisters: newRegister[] // AdapterDataMapping list (primary)
): Promise<number> {
try {
- // 프로젝트의 태그 타입과 클래스 가져오기
- const tagTypeRecords = await db.select()
- .from(tagTypes)
- .where(eq(tagTypes.projectId, projectId));
+ /* ------------------------------------------------------------------ */
+ /* 1. Prepare look‑up structures & common data */
+ /* ------------------------------------------------------------------ */
- const tagClassRecords = await db.select()
- .from(tagClasses)
- .where(eq(tagClasses.projectId, projectId));
+ const tagTypeRecords = await db.select().from(tagTypes).where(eq(tagTypes.projectId, projectId));
+ const tagClassRecords = await db.select().from(tagClasses).where(eq(tagClasses.projectId, projectId));
+ const tagTypeMap = new Map(tagTypeRecords.map(t => [t.code, t]));
+ const tagClassMap = new Map(tagClassRecords.map(c => [c.code, c]));
- // 태그 타입과 클래스 매핑
- const tagTypeMap = new Map(tagTypeRecords.map(type => [type.code, type]));
- const tagClassMap = new Map(tagClassRecords.map(cls => [cls.code, cls]));
+ const registerMap = new Map(registers.map(r => [r.TYPE_ID, r]));
- // 모든 속성, 코드 리스트, UOM을 한 번에 가져와 반복 API 호출 방지
const attributeMap = await getAttributes(projectCode);
- const codeListMap = await getCodeLists(projectCode);
- const uomMap = await getUOMs(projectCode);
-
- // 기본 속성 가져오기
+ const codeListMap = await getCodeLists(projectCode);
+ const uomMap = await getUOMs(projectCode);
const defaultAttributes = await getDefaulTAttributes();
- // 모든 register에서 itemCode를 추출하여 한 번에 조회
- const allItemCodes: string[] = [];
- registers.forEach(register => {
- if (register.REMARK) {
- const itemCodes = extractItemCodes(register.REMARK);
- allItemCodes.push(...itemCodes);
- }
- });
-
- // 중복 제거
- const uniqueItemCodes = [...new Set(allItemCodes)];
-
- // 모든 itemCode에 대한 contractItemId 조회
- const itemCodeToContractItemId = await getContractItemsByItemCodes(uniqueItemCodes , projectId);
-
- console.log(`${uniqueItemCodes.length}개의 고유 itemCode 중 ${itemCodeToContractItemId.size}개의 contractItem을 찾았습니다`);
+ /* ------------------------------------------------------------------ */
+ /* 2. Contract‑item look‑up (TOOL_TYPE) */
+ /* ------------------------------------------------------------------ */
+ const uniqueItemCodes = [...new Set(newRegisters.filter(nr => nr.TOOL_TYPE).map(nr => nr.TOOL_TYPE as string))];
+ const itemCodeToContractItemId = await getContractItemsByItemCodes(uniqueItemCodes, projectId);
- // 저장할 데이터 준비
+ /* ------------------------------------------------------------------ */
+ /* 3. Buffers for bulk insert */
+ /* ------------------------------------------------------------------ */
const mappingsToSave: TagTypeClassFormMapping[] = [];
const formMetasToSave: FormMeta[] = [];
const formsToSave: FormRecord[] = [];
-
- // 폼이 있는 contractItemId 트래킹
const contractItemIdsWithForms = new Set<number>();
+ const templateDataByFormCode: Map<string, TemplateItem[]> = new Map();
- // 각 register 처리
- for (const register of registers) {
- // 삭제된 register 건너뛰기
- if (register.DELETED) continue;
+ /* ------------------------------------------------------------------ */
+ /* 4. Iterate over newRegisters */
+ /* ------------------------------------------------------------------ */
+ for (const newReg of newRegisters) {
+ const formCode = newReg.REG_TYPE_ID;
+ const legacy = registerMap.get(formCode);
- // REMARK에서 itemCodes 추출
+ /* ---------- 4‑a. templates ------------------------------------ */
+ let templates: TemplateItem[] = [];
+ try {
+ const fetched = await fetchTemplateFromSEDP(projectCode, formCode);
+ templates = fetched.filter(t => (newReg.MAP_TMPLS?.length ? newReg.MAP_TMPLS.includes(t.TMPL_ID) : true));
+ if (templates.length) templateDataByFormCode.set(formCode, templates);
+ } catch (e) {
+ console.warn(`템플릿 가져오기 실패 (${formCode})`, e);
+ }
+ const templateAttrMap = new Map<string, { hidden: boolean; seq: number; head: string }>();
+ templates.forEach(t => t.GRD_LST_SETUP?.ATTS?.forEach(att => {
+ if (!templateAttrMap.has(att.ATT_ID)) templateAttrMap.set(att.ATT_ID, { hidden: att.HIDN_YN, seq: att.SEQ, head: att.HEAD_TEXT });
+ }));
- // 폼 메타용 columns 구성
+ /* ---------- 4‑b. columns -------------------------------------- */
const columns: FormColumn[] = [];
-
- for (const linkAtt of register.LNK_ATT) {
- let attribute = null;
-
- // 기본 속성인지 확인
- if (defaultAttributes && defaultAttributes.includes(linkAtt.ATT_ID)) {
- // 기본 속성에 대한 기본 attribute 객체 생성
- attribute = {
- DESC: linkAtt.ATT_ID,
- VAL_TYPE: 'STRING'
- };
- } else {
- // 맵에서 속성 조회
- attribute = attributeMap.get(linkAtt.ATT_ID);
-
- // 속성을 찾지 못한 경우 다음으로 넘어감
- if (!attribute) continue;
+ for (const mapAtt of newReg.MAP_ATT) {
+ const attId = mapAtt.SEDP_ATT_ID;
+ const attribute = defaultAttributes.includes(attId) ? { DESC: attId, VAL_TYPE: "STRING" } as Partial<Attribute> : attributeMap.get(attId);
+ if (!attribute) continue;
+
+ const tmplMeta = templateAttrMap.get(attId);
+ const isShi = mapAtt.INOUT === "OUT";
+
+ let uomSymbol: string | undefined; let uomId: string | undefined;
+ if (legacy?.LNK_ATT) {
+ const l = legacy.LNK_ATT.find(a => a.ATT_ID === attId);
+ if (l?.UOM_ID) { const u = uomMap.get(l.UOM_ID); if (u) { uomSymbol = u.SYMBOL; uomId = u.UOM_ID; } }
}
- // 컬럼 정보 생성
- const column: FormColumn = {
- key: linkAtt.ATT_ID,
- label: attribute.DESC,
- type: (attribute.VAL_TYPE === 'LIST' || attribute.VAL_TYPE === 'DYNAMICLIST')
- ? 'LIST'
- : (attribute.VAL_TYPE || 'STRING'),
- shi: attribute.REMARK?.toLocaleLowerCase() === "shi"
+ const col: FormColumn = {
+ key: attId,
+ label: attribute.DESC as string,
+ type: (attribute.VAL_TYPE === "LIST" || attribute.VAL_TYPE === "DYNAMICLIST") ? "LIST" : (attribute.VAL_TYPE || "STRING"),
+ shi: isShi,
+ hidden: tmplMeta?.hidden ?? false,
+ seq: tmplMeta?.seq ?? 0,
+ head: tmplMeta?.head ?? "",
+ ...(uomSymbol ? { uom: uomSymbol, uomId } : {})
};
- // 리스트 타입에 대한 옵션 추가 (기본 속성이 아닌 경우)
- if (!defaultAttributes.includes(linkAtt.ATT_ID) &&
- (attribute.VAL_TYPE === 'LIST' || attribute.VAL_TYPE === 'DYNAMICLIST') &&
- attribute.CL_ID) {
-
- // 맵에서 코드 리스트 조회
- const codeList = codeListMap.get(attribute.CL_ID);
-
- if (codeList && codeList.VALUES) {
- const options = [...new Set(
- codeList.VALUES
- .filter(value => value.USE_YN)
- .map(value => value.VALUE)
- )];
-
- if (options.length > 0) {
- column.options = options;
- }
- }
+ if (!defaultAttributes.includes(attId) && (attribute.VAL_TYPE === "LIST" || attribute.VAL_TYPE === "DYNAMICLIST") && attribute.CL_ID) {
+ const cl = codeListMap.get(attribute.CL_ID);
+ if (cl?.VALUES?.length) col.options = [...new Set(cl.VALUES.filter(v => v.USE_YN).map(v => v.VALUE))];
}
- // UOM 정보 추가
- if (linkAtt.UOM_ID) {
- const uom = uomMap.get(linkAtt.UOM_ID);
-
- if (uom) {
- column.uom = uom.SYMBOL;
- column.uomId = uom.UOM_ID;
- }
- }
-
- columns.push(column);
- }
-
- // 컬럼이 없으면 건너뛰기
- if (columns.length === 0) {
- console.log(`폼 ${register.TYPE_ID} (${register.DESC})에 컬럼이 없어 건너뜁니다`);
- continue;
+ columns.push(col);
}
+ if (!columns.length) { console.log(`폼 ${formCode} 건너뜀 (컬럼 없음)`); continue; }
+ columns.sort((a, b) => (a.seq ?? 999999) - (b.seq ?? 999999));
- // 폼 메타 데이터 준비
- formMetasToSave.push({
- projectId,
- formCode: register.TYPE_ID,
- formName: register.DESC,
- columns: JSON.stringify(columns),
- createdAt: new Date(),
- updatedAt: new Date()
- });
-
- // 클래스 매핑 처리
- for (const classId of register.MAP_CLS_ID) {
- const tagClass = tagClassMap.get(classId);
-
- if (!tagClass) {
- console.warn(`프로젝트 ID ${projectId}에서 클래스 ID ${classId}를 찾을 수 없습니다`);
- continue;
- }
-
- const tagTypeCode = tagClass.tagTypeCode;
- const tagType = tagTypeMap.get(tagTypeCode);
-
- if (!tagType) {
- console.warn(`프로젝트 ID ${projectId}에서 태그 타입 ${tagTypeCode}를 찾을 수 없습니다`);
- continue;
- }
+ formMetasToSave.push({ projectId, formCode, formName: legacy?.DESC || formCode, columns: JSON.stringify(columns), createdAt: new Date(), updatedAt: new Date() });
- // 매핑 정보 저장
- mappingsToSave.push({
- projectId,
- tagTypeLabel: tagType.description,
- classLabel: tagClass.label,
- formCode: register.TYPE_ID,
- formName: register.DESC,
- remark: register.REMARK,
- ep: register.EP_ID,
- createdAt: new Date(),
- updatedAt: new Date()
- });
+ /* ---------- 4‑c. class mappings -------------------------------- */
+ const classIds = new Set<string>();
+ if (newReg.MAP_CLS?.ITEMS?.length) {
+ newReg.MAP_CLS.ITEMS.forEach(it => classIds.add(it.SEDP_OBJ_CLS_ID));
}
- const itemCodes = extractItemCodes(register.REMARK || '');
- if (!itemCodes.length) {
- console.log(`Register ${register.TYPE_ID} (${register.DESC})의 REMARK에 유효한 itemCode가 없습니다`);
- continue;
- }
- // 폼 레코드 준비
- for (const itemCode of itemCodes) {
- const contractItemId = itemCodeToContractItemId.get(itemCode);
-
- if (!contractItemId) {
- console.warn(`itemCode: ${itemCode}에 대한 contractItemId를 찾을 수 없습니다`);
- continue;
- }
-
- // 폼이 있는 contractItemId 추적
- contractItemIdsWithForms.add(contractItemId);
+ classIds.forEach(classId => {
+ const cls = tagClassMap.get(classId);
+ if (!cls) { console.warn(`클래스 ${classId} 없음`); return; }
+ const tp = tagTypeMap.get(cls.tagTypeCode);
+ if (!tp) { console.warn(`태그 타입 ${cls.tagTypeCode} 없음`); return; }
+ mappingsToSave.push({ projectId, tagTypeLabel: tp.description, classLabel: cls.label, formCode, formName: legacy?.DESC || formCode, remark: newReg.TOOL_TYPE || null, ep: newReg.EP_ID || legacy?.EP_ID || "", createdAt: new Date(), updatedAt: new Date() });
+ });
- formsToSave.push({
- contractItemId,
- formCode: register.TYPE_ID,
- formName: register.DESC,
- eng: true,
- createdAt: new Date(),
- updatedAt: new Date()
- });
+ /* ---------- 4‑d. contractItem ↔ form --------------------------- */
+ if (newReg.TOOL_TYPE) {
+ const cId = itemCodeToContractItemId.get(newReg.TOOL_TYPE);
+ if (cId) { contractItemIdsWithForms.add(cId); formsToSave.push({ contractItemId: cId, formCode, formName: legacy?.DESC || formCode, eng: true, createdAt: new Date(), updatedAt: new Date() }); }
+ else console.warn(`itemCode ${newReg.TOOL_TYPE} 의 contractItemId 없음`);
}
}
- // 트랜잭션으로 모든 작업 처리
+ /* ------------------------------------------------------------------ */
+ /* 5. DB transaction */
+ /* ------------------------------------------------------------------ */
let totalSaved = 0;
-
- await db.transaction(async (tx) => {
- // 기존 데이터 삭제
+ await db.transaction(async tx => {
+ const old = await tx.select({ id: tagTypeClassFormMappings.id }).from(tagTypeClassFormMappings).where(eq(tagTypeClassFormMappings.projectId, projectId));
+ if (old.length) await tx.delete(templateItems).where(inArray(templateItems.formMappingId, old.map(o => o.id)));
await tx.delete(tagTypeClassFormMappings).where(eq(tagTypeClassFormMappings.projectId, projectId));
await tx.delete(formMetas).where(eq(formMetas.projectId, projectId));
+ if (contractItemIdsWithForms.size) await tx.delete(forms).where(inArray(forms.contractItemId, [...contractItemIdsWithForms]));
- // 해당 contractItemId에 대한 기존 폼 삭제
- if (contractItemIdsWithForms.size > 0) {
- await tx.delete(forms).where(inArray(forms.contractItemId, [...contractItemIdsWithForms]));
- }
-
- // 매핑 저장
- if (mappingsToSave.length > 0) {
- await tx.insert(tagTypeClassFormMappings).values(mappingsToSave);
- totalSaved += mappingsToSave.length;
- console.log(`프로젝트 ID ${projectId}에 대해 ${mappingsToSave.length}개의 태그 타입-클래스-폼 매핑을 저장했습니다`);
- }
+ const savedMappings = mappingsToSave.length ? await tx.insert(tagTypeClassFormMappings).values(mappingsToSave).returning({ id: tagTypeClassFormMappings.id, formCode: tagTypeClassFormMappings.formCode }) : [];
+ totalSaved += mappingsToSave.length;
- // 폼 메타 저장
- if (formMetasToSave.length > 0) {
- await tx.insert(formMetas).values(formMetasToSave);
- totalSaved += formMetasToSave.length;
- console.log(`프로젝트 ID ${projectId}에 대해 ${formMetasToSave.length}개의 폼 메타 레코드를 저장했습니다`);
+ if (savedMappings.length) {
+ const rows: any[] = [];
+ savedMappings.forEach(m => (templateDataByFormCode.get(m.formCode) || []).forEach(t => rows.push({ formMappingId: m.id, tmplId: t.TMPL_ID, name: t.NAME, tmplType: t.TMPL_TYPE, sprLstSetup: t.SPR_LST_SETUP, grdLstSetup: t.GRD_LST_SETUP, sprItmLstSetup: t.SPR_ITM_LST_SETUP, description: `Template for form ${m.formCode}`, isActive: true, createdAt: new Date(), updatedAt: new Date() })));
+ if (rows.length) { await tx.insert(templateItems).values(rows); totalSaved += rows.length; }
}
- // 폼 레코드 저장
- if (formsToSave.length > 0) {
- await tx.insert(forms).values(formsToSave);
- totalSaved += formsToSave.length;
- console.log(`프로젝트 ID ${projectId}에 대해 ${formsToSave.length}개의 폼 레코드를 저장했습니다`);
- }
+ if (formMetasToSave.length) { await tx.insert(formMetas).values(formMetasToSave); totalSaved += formMetasToSave.length; }
+ if (formsToSave.length) { await tx.insert(forms).values(formsToSave); totalSaved += formsToSave.length; }
});
return totalSaved;
- } catch (error) {
- console.error(`폼 매핑 및 메타 저장 실패 (프로젝트 ID: ${projectId}):`, error);
- throw error;
+ } catch (err) {
+ console.error(`폼 매핑 및 메타 저장 실패 (프로젝트 ID:${projectId})`, err);
+ throw err;
}
}
+
// 메인 동기화 함수
export async function syncTagFormMappings() {
try {
@@ -973,9 +1081,10 @@ export async function syncTagFormMappings() {
try {
// 레지스터 데이터 가져오기
const registers = await getRegisters(project.code);
+ const newRegisters = await getNewRegisters(project.code);
// 데이터베이스에 저장
- const count = await saveFormMappingsAndMetas(project.id, project.code, registers);
+ const count = await saveFormMappingsAndMetas(project.id, project.code, registers, newRegisters);
return {
project: project.code,
success: true,