From d113d1732f7c6356af6619dfaff98604fb68e5ad Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Thu, 13 Nov 2025 12:21:18 +0900
Subject: (김준회) SWP 문서리스트: OWN_DOC_NO로 스테이지 검증 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/swp/table/swp-table-toolbar.tsx | 90 ++++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 35 deletions(-)

(limited to 'lib/swp/table/swp-table-toolbar.tsx')

diff --git a/lib/swp/table/swp-table-toolbar.tsx b/lib/swp/table/swp-table-toolbar.tsx
index 013b4a13..ea5ee729 100644
--- a/lib/swp/table/swp-table-toolbar.tsx
+++ b/lib/swp/table/swp-table-toolbar.tsx
@@ -19,7 +19,7 @@ import {
   validateFileName 
 } from "./swp-upload-validation-dialog";
 import { SwpUploadedFilesDialog } from "./swp-uploaded-files-dialog";
-import { getProjectDocumentClassStages } from "@/lib/docu-list-rule/document-class/service";
+import { getDocumentClassInfoByProjectCode } from "@/lib/swp/swp-upload-server-actions";
 import type { DocumentListItem } from "@/lib/swp/document-service";
 
 interface SwpTableFilters {
@@ -40,7 +40,7 @@ interface SwpTableToolbarProps {
   vendorCode?: string;
   droppedFiles?: File[];
   onFilesProcessed?: () => void;
-  documents?: DocumentListItem[]; // 업로드 권한 검증 + DOC_TYPE 확인용 문서 목록
+  documents?: DocumentListItem[]; // 업로드 권한 검증 + DOC_CLS (Document Class) 확인용 문서 목록
   userId?: string; // 파일 취소 시 필요
 }
 
@@ -82,31 +82,25 @@ export function SwpTableToolbar({
   }>>([]);
   const [showValidationDialog, setShowValidationDialog] = useState(false);
 
-  // Document Class-Stage 매핑 (프로젝트별)
+  // EVCP DB에서 조회한 문서 정보 (vendorDocNumber → Document Class 매핑)
+  const [vendorDocNumberToDocClassMap, setVendorDocNumberToDocClassMap] = useState<Record<string, string>>({});
+  // Document Class별 허용 Stage 목록
   const [documentClassStages, setDocumentClassStages] = useState<Record<string, string[]>>({});
-  const [isLoadingDocClassStages, setIsLoadingDocClassStages] = useState(false);
 
   /**
    * 업로드 가능한 문서번호 목록 추출 (OWN_DOC_NO 기준)
+   * SWP API의 OWN_DOC_NO가 EVCP DB의 vendorDocNumber와 매핑되는지 확인
    */
   const availableDocNos = useMemo(() => {
     return documents
       .map(doc => doc.OWN_DOC_NO)
-      .filter((ownDocNo): ownDocNo is string => ownDocNo !== null && ownDocNo !== undefined);
-  }, [documents]);
-
-  /**
-   * 문서번호 → DOC_TYPE 매핑 (Stage 검증용)
-   */
-  const docNoToDocTypeMap = useMemo(() => {
-    const map: Record<string, string> = {};
-    for (const doc of documents) {
-      if (doc.OWN_DOC_NO && doc.DOC_TYPE) {
-        map[doc.OWN_DOC_NO] = doc.DOC_TYPE;
-      }
-    }
-    return map;
-  }, [documents]);
+      .filter((ownDocNo): ownDocNo is string => {
+        // OWN_DOC_NO가 있고, EVCP DB에 등록된 문서인지 확인
+        return ownDocNo !== null && 
+               ownDocNo !== undefined && 
+               vendorDocNumberToDocClassMap[ownDocNo] !== undefined;
+      });
+  }, [documents, vendorDocNumberToDocClassMap]);
 
   /**
    * 벤더 모드 여부 (벤더 코드가 있으면 벤더 모드)
@@ -114,42 +108,68 @@ export function SwpTableToolbar({
   const isVendorMode = !!vendorCode;
 
   /**
-   * 프로젝트 변경 시 Document Class-Stage 매핑 로드
+   * 프로젝트 변경 시 EVCP DB에서 문서 정보 로드
+   * - vendorDocNumber → docClass 매핑
+   * - Document Class별 허용 Stage 목록
    */
   useEffect(() => {
     if (!projNo) {
+      setVendorDocNumberToDocClassMap({});
       setDocumentClassStages({});
       return;
     }
 
     let isCancelled = false;
 
-    const loadDocumentClassStages = async () => {
+    const loadDocumentClassInfo = async () => {
       try {
-        setIsLoadingDocClassStages(true);
-        const stages = await getProjectDocumentClassStages(projNo);
+        console.log(`[SwpTableToolbar] 프로젝트 ${projNo} 문서 정보 로드 시작`);
+
+        // 서버 액션 호출
+        const result = await getDocumentClassInfoByProjectCode(projNo);
+        
         if (!isCancelled) {
-          setDocumentClassStages(stages);
-          console.log(`[SwpTableToolbar] Document Class-Stage 매핑 로드 완료:`, stages);
+          if (result.success) {
+            setVendorDocNumberToDocClassMap(result.vendorDocNumberToDocClassMap);
+            setDocumentClassStages(result.documentClassStages);
+            
+            console.log(`[SwpTableToolbar] 문서 정보 로드 완료:`, {
+              vendorDocNumbers: Object.keys(result.vendorDocNumberToDocClassMap).length,
+              documentClassStages: result.documentClassStages,
+            });
+          } else {
+            console.warn(`[SwpTableToolbar] 문서 정보 로드 실패:`, result.error);
+            setVendorDocNumberToDocClassMap({});
+            setDocumentClassStages({});
+            
+            toast({
+              variant: "destructive",
+              title: "문서 정보 로드 실패",
+              description: result.error || "문서 정보를 가져올 수 없습니다.",
+            });
+          }
         }
       } catch (error) {
         if (!isCancelled) {
-          console.error('[SwpTableToolbar] Document Class-Stage 매핑 로드 실패:', error);
+          console.error('[SwpTableToolbar] 문서 정보 로드 실패:', error);
+          setVendorDocNumberToDocClassMap({});
           setDocumentClassStages({});
-        }
-      } finally {
-        if (!isCancelled) {
-          setIsLoadingDocClassStages(false);
+          
+          toast({
+            variant: "destructive",
+            title: "문서 정보 로드 실패",
+            description: "문서 정보를 가져올 수 없습니다. 페이지를 새로고침해주세요.",
+          });
         }
       }
     };
 
-    loadDocumentClassStages();
+    loadDocumentClassInfo();
 
     return () => {
       isCancelled = true;
     };
-  }, [projNo]);
+  }, [projNo, toast]);
 
   /**
    * 드롭된 파일 처리 - useEffect로 감지하여 자동 검증
@@ -183,7 +203,7 @@ export function SwpTableToolbar({
           file.name,
           availableDocNos,
           isVendorMode,
-          docNoToDocTypeMap,
+          vendorDocNumberToDocClassMap,
           documentClassStages
         );
         return {
@@ -198,7 +218,7 @@ export function SwpTableToolbar({
       setShowValidationDialog(true);
       onFilesProcessed?.();
     }
-  }, [droppedFiles, projNo, vendorCode, toast, onFilesProcessed, availableDocNos, isVendorMode, docNoToDocTypeMap, documentClassStages]);
+  }, [droppedFiles, projNo, vendorCode, toast, onFilesProcessed, availableDocNos, isVendorMode, vendorDocNumberToDocClassMap, documentClassStages]);
 
   /**
    * 파일 업로드 핸들러
@@ -240,7 +260,7 @@ export function SwpTableToolbar({
         file.name,
         availableDocNos,
         isVendorMode,
-        docNoToDocTypeMap,
+        vendorDocNumberToDocClassMap,
         documentClassStages
       );
       return {
-- 
cgit v1.2.3

