diff --git a/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx b/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx index 939bb5d5..ba206683 100644 --- a/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx +++ b/frontend/lib/registry/components/universal-form-modal/UniversalFormModalComponent.tsx @@ -380,6 +380,16 @@ export function UniversalFormModalComponent({ const handleBeforeFormSave = (event: Event) => { if (!(event instanceof CustomEvent) || !event.detail?.formData) return; + // 필수값 검증 실행 + const validation = validateRequiredFields(); + if (!validation.valid) { + event.detail.validationFailed = true; + event.detail.validationErrors = validation.missingFields; + toast.error(`필수 항목을 입력해주세요: ${validation.missingFields.join(", ")}`); + console.log("[UniversalFormModal] 필수값 검증 실패:", validation.missingFields); + return; // 검증 실패 시 데이터 병합 중단 + } + // 설정에 정의된 필드 columnName 목록 수집 const configuredFields = new Set(); config.sections.forEach((section) => { diff --git a/frontend/lib/utils/buttonActions.ts b/frontend/lib/utils/buttonActions.ts index a4b6074c..edc6861a 100644 --- a/frontend/lib/utils/buttonActions.ts +++ b/frontend/lib/utils/buttonActions.ts @@ -542,6 +542,8 @@ export class ButtonActionExecutor { const beforeSaveEventDetail = { formData: context.formData, skipDefaultSave: false, + validationFailed: false, + validationErrors: [] as string[], }; window.dispatchEvent( new CustomEvent("beforeFormSave", { @@ -552,6 +554,12 @@ export class ButtonActionExecutor { // 약간의 대기 시간을 주어 이벤트 핸들러가 formData를 업데이트할 수 있도록 함 await new Promise((resolve) => setTimeout(resolve, 100)); + // 검증 실패 시 저장 중단 + if (beforeSaveEventDetail.validationFailed) { + console.log("❌ [handleSave] 검증 실패로 저장 중단:", beforeSaveEventDetail.validationErrors); + return false; + } + // 🔧 skipDefaultSave 플래그 확인 - SelectedItemsDetailInput 등에서 자체 UPSERT 처리 시 기본 저장 건너뛰기 if (beforeSaveEventDetail.skipDefaultSave) { console.log("🚫 [handleSave] skipDefaultSave=true - 기본 저장 로직 건너뛰기 (컴포넌트에서 자체 처리)");