From e0dfb55c5457aec489fc084c4567e791b4c65eb1 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 26 Mar 2025 00:37:41 +0000
Subject: 3/25 까지의 대표님 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/rfqs/table/rfqs-table.tsx | 264 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 264 insertions(+)
 create mode 100644 lib/rfqs/table/rfqs-table.tsx

(limited to 'lib/rfqs/table/rfqs-table.tsx')

diff --git a/lib/rfqs/table/rfqs-table.tsx b/lib/rfqs/table/rfqs-table.tsx
new file mode 100644
index 00000000..7d996816
--- /dev/null
+++ b/lib/rfqs/table/rfqs-table.tsx
@@ -0,0 +1,264 @@
+"use client"
+
+import * as React from "react"
+import type {
+  DataTableAdvancedFilterField,
+  DataTableFilterField,
+  DataTableRowAction,
+} from "@/types/table"
+
+import { toSentenceCase } from "@/lib/utils"
+import { useDataTable } from "@/hooks/use-data-table"
+import { DataTable } from "@/components/data-table/data-table"
+import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
+
+import { getRFQStatusIcon } from "@/lib/tasks/utils"
+import { useFeatureFlags } from "./feature-flags-provider"
+import { getColumns } from "./rfqs-table-columns"
+import { fetchRfqAttachments, fetchRfqItems, getRfqs, getRfqStatusCounts } from "../service"
+import { RfqItem, RfqWithItemCount, rfqs } from "@/db/schema/rfq"
+import { RfqsTableFloatingBar } from "./rfqs-table-floating-bar"
+import { UpdateRfqSheet } from "./update-rfq-sheet"
+import { DeleteRfqsDialog } from "./delete-rfqs-dialog"
+import { RfqsTableToolbarActions } from "./rfqs-table-toolbar-actions"
+import { RfqsItemsDialog } from "./ItemsDialog"
+import { getAllItems } from "@/lib/items/service"
+import { RfqAttachmentsSheet } from "./attachment-rfq-sheet"
+import { useRouter } from "next/navigation"
+import { RfqType } from "../validations"
+
+interface RfqsTableProps {
+  promises: Promise<
+    [
+      Awaited<ReturnType<typeof getRfqs>>,
+      Awaited<ReturnType<typeof getRfqStatusCounts>>,
+      Awaited<ReturnType<typeof getAllItems>>,
+    ]
+  >;
+  rfqType?: RfqType; // rfqType props 추가
+}
+
+export interface ExistingAttachment {
+  id: number;
+  fileName: string;
+  filePath: string;
+  createdAt?: Date;
+  vendorId?: number | null;
+  size?: number;
+}
+
+export interface ExistingItem {
+  id?: number;
+  itemCode: string;
+  description: string | null;
+  quantity: number | null;
+  uom: string | null;
+}
+
+export function RfqsTable({ promises, rfqType = RfqType.PURCHASE }: RfqsTableProps) {
+  const { featureFlags } = useFeatureFlags()
+
+  const [{ data, pageCount }, statusCounts, items] = React.use(promises)
+  const [attachmentsOpen, setAttachmentsOpen] = React.useState(false)
+  const [selectedRfqIdForAttachments, setSelectedRfqIdForAttachments] = React.useState<number | null>(null)
+  const [attachDefault, setAttachDefault] = React.useState<ExistingAttachment[]>([])
+  const [itemsDefault, setItemsDefault] = React.useState<ExistingItem[]>([])
+
+  const router = useRouter()
+
+  const itemsList = items?.map((v) => ({
+    code: v.itemCode ?? "",
+    name: v.itemName ?? "",
+  }));
+
+  const [rowAction, setRowAction] =
+    React.useState<DataTableRowAction<RfqWithItemCount> | null>(null)
+
+  const [rowData, setRowData] = React.useState<RfqWithItemCount[]>(() => data)
+
+  const [itemsModalOpen, setItemsModalOpen] = React.useState(false);
+  const [selectedRfqId, setSelectedRfqId] = React.useState<number | null>(null);
+
+
+  const selectedRfq = React.useMemo(() => {
+    return rowData.find(row => row.rfqId === selectedRfqId) || null;
+  }, [rowData, selectedRfqId]);
+
+  // rfqType에 따른 제목 계산
+  const getRfqTypeTitle = () => {
+    return rfqType === RfqType.PURCHASE ? "Purchase RFQ" : "Budgetary RFQ";
+  };
+
+  async function openItemsModal(rfqId: number) {
+    const itemList = await fetchRfqItems(rfqId)
+    setItemsDefault(itemList)
+    setSelectedRfqId(rfqId);
+    setItemsModalOpen(true);
+  }
+
+  async function openAttachmentsSheet(rfqId: number) {
+    // 4.1) Fetch current attachments from server (server action)
+    const list = await fetchRfqAttachments(rfqId) // returns ExistingAttachment[]
+    setAttachDefault(list)
+    setSelectedRfqIdForAttachments(rfqId)
+    setAttachmentsOpen(true)
+    setSelectedRfqId(rfqId);
+  }
+
+  function handleAttachmentsUpdated(rfqId: number, newCount: number, newList?: ExistingAttachment[]) {
+    // 5.1) update rowData itemCount
+    setRowData(prev =>
+      prev.map(r =>
+        r.rfqId === rfqId
+          ? { ...r, itemCount: newCount }
+          : r
+      )
+    )
+    // 5.2) if newList is provided, store it
+    if (newList) {
+      setAttachDefault(newList)
+    }
+  }
+
+  const columns = React.useMemo(() => getColumns({
+    setRowAction, router,
+    // we pass openItemsModal as a prop so the itemsColumn can call it
+    openItemsModal,
+    openAttachmentsSheet,
+    rfqType
+  }), [setRowAction, router, rfqType]);
+
+  /**
+   * This component can render either a faceted filter or a search filter based on the `options` prop.
+   */
+  const filterFields: DataTableFilterField<RfqWithItemCount>[] = [
+    {
+      id: "rfqCode",
+      label: "RFQ Code",
+      placeholder: "Filter RFQ Code...",
+    },
+    {
+      id: "status",
+      label: "Status",
+      options: rfqs.status.enumValues?.map((status) => {
+        // 명시적으로 status를 허용된 리터럴 타입으로 변환
+        const s = status as "DRAFT" | "PUBLISHED" | "EVALUATION" | "AWARDED";
+        return {
+          label: toSentenceCase(s),
+          value: s,
+          icon: getRFQStatusIcon(s),
+          count: statusCounts[s],
+        };
+      }),
+
+    }
+  ]
+
+  /**
+   * Advanced filter fields for the data table.
+   */
+  const advancedFilterFields: DataTableAdvancedFilterField<RfqWithItemCount>[] = [
+    {
+      id: "rfqCode",
+      label: "RFQ Code",
+      type: "text",
+    },
+    {
+      id: "description",
+      label: "Description",
+      type: "text",
+    },
+    {
+      id: "projectCode",
+      label: "Project Code",
+      type: "text",
+    },
+    {
+      id: "dueDate",
+      label: "Due Date",
+      type: "date",
+    },
+    {
+      id: "status",
+      label: "Status",
+      type: "multi-select",
+      options: rfqs.status.enumValues?.map((status) => {
+        // 명시적으로 status를 허용된 리터럴 타입으로 변환
+        const s = status as "DRAFT" | "PUBLISHED" | "EVALUATION" | "AWARDED";
+        return {
+          label: toSentenceCase(s),
+          value: s,
+          icon: getRFQStatusIcon(s),
+          count: statusCounts[s],
+        };
+      }),
+
+    },
+  ]
+
+  const { table } = useDataTable({
+    data,
+    columns,
+    pageCount,
+    filterFields,
+    enablePinning: true,
+    enableAdvancedFilter: true,
+    initialState: {
+      sorting: [{ id: "createdAt", desc: true }],
+      columnPinning: { right: ["actions"] },
+    },
+    getRowId: (originalRow) => String(originalRow.rfqId),
+    shallow: false,
+    clearOnDefault: true,
+  })
+
+  return (
+    <div style={{ maxWidth: '80vw' }}>
+      <DataTable
+        table={table}
+        floatingBar={<RfqsTableFloatingBar table={table} />}
+      >
+        <DataTableAdvancedToolbar
+          table={table}
+          filterFields={advancedFilterFields}
+          shallow={false}
+        >
+          <RfqsTableToolbarActions table={table} rfqType={rfqType} />
+        </DataTableAdvancedToolbar>
+      </DataTable>
+
+      <UpdateRfqSheet
+        open={rowAction?.type === "update"}
+        onOpenChange={() => setRowAction(null)}
+        rfq={rowAction?.row.original ?? null}
+        rfqType={rfqType}
+      />
+
+      <DeleteRfqsDialog
+        open={rowAction?.type === "delete"}
+        onOpenChange={() => setRowAction(null)}
+        rfqs={rowAction?.row.original ? [rowAction?.row.original] : []}
+        showTrigger={false}
+        onSuccess={() => rowAction?.row.toggleSelected(false)}
+      />
+
+      <RfqsItemsDialog
+        open={itemsModalOpen}
+        onOpenChange={setItemsModalOpen}
+        rfq={selectedRfq ?? null}
+        itemsList={itemsList}
+        defaultItems={itemsDefault}
+        rfqType={rfqType}
+      />
+
+      <RfqAttachmentsSheet
+        open={attachmentsOpen}
+        onOpenChange={setAttachmentsOpen}
+        defaultAttachments={attachDefault}
+        rfqType={rfqType}
+        rfq={selectedRfq ?? null}
+        onAttachmentsUpdated={handleAttachmentsUpdated}
+      />
+      </div>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3


From e6e98a1bed7a23d148ab97b3a7414ade4b1d236b Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 27 Mar 2025 04:30:31 +0000
Subject: 20240327 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                         |    1 +
 .../vendor-data/form/[packageId]/[formId]/page.tsx |   40 +-
 components/form-data/form-data-report-dialog.tsx   |  457 ++
 .../form-data-report-temp-upload-dialog.tsx        |  305 ++
 components/form-data/form-data-table-columns.tsx   |   77 +-
 config/poColumnsConfig.ts                          |    8 +
 db/migrations/0103_huge_wallflower.sql             |   37 +
 db/migrations/meta/0103_snapshot.json              | 4757 ++++++++++++++++++++
 db/migrations/meta/_journal.json                   |    7 +
 db/schema/contract.ts                              |   49 +-
 lib/po/table/po-table-columns.tsx                  |   95 +-
 lib/rfqs/table/rfqs-table.tsx                      |    2 +-
 lib/vendors/table/request-vendor-pg-dialog.tsx     |    4 +-
 13 files changed, 5764 insertions(+), 75 deletions(-)
 create mode 100644 components/form-data/form-data-report-dialog.tsx
 create mode 100644 components/form-data/form-data-report-temp-upload-dialog.tsx
 create mode 100644 db/migrations/0103_huge_wallflower.sql
 create mode 100644 db/migrations/meta/0103_snapshot.json

(limited to 'lib/rfqs/table/rfqs-table.tsx')

diff --git a/.gitignore b/.gitignore
index 4a325b8c..9b14c704 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,6 +54,7 @@ next-env.d.ts
 /public/uploads
 /public/vendors
 /public/profiles
+/public/vendorFormData
 /tmp
 
 # 직접 참조가 불가능해 복사가 필요했던 라이브러리 (pdftrone)
diff --git a/app/[lng]/partners/(partners)/vendor-data/form/[packageId]/[formId]/page.tsx b/app/[lng]/partners/(partners)/vendor-data/form/[packageId]/[formId]/page.tsx
index 248bd7fc..58337016 100644
--- a/app/[lng]/partners/(partners)/vendor-data/form/[packageId]/[formId]/page.tsx
+++ b/app/[lng]/partners/(partners)/vendor-data/form/[packageId]/[formId]/page.tsx
@@ -1,30 +1,37 @@
-import DynamicTable from "@/components/form-data/form-data-table"
-import { getFormData } from "@/lib/forms/services"
+import DynamicTable from "@/components/form-data/form-data-table";
+// 김준회프로입니다. 현재 이 부분에서 컴파일 에러가 발생하여 잠시 주석처리 하겠습니다.
+// import { getFormData, getFormId } from "@/lib/forms/services";
+import { getFormData } from "@/lib/forms/services";
 
 interface IndexPageProps {
   params: {
-    lng: string
-    packageId: string
-    formId: string
-  }
+    lng: string;
+    packageId: string;
+    formId: string;
+  };
 }
 
 export default async function FormPage({ params }: IndexPageProps) {
   // 1) 구조 분해 할당
-  const resolvedParams = await params
-  
+  const resolvedParams = await params;
+
   // 2) 구조 분해 할당
-  const { lng, packageId, formId } = resolvedParams
+  const { lng, packageId, formId: formCode } = resolvedParams;
 
   // 2) 변환
-  const packageIdAsNumber = Number(packageId)
+  const packageIdAsNumber = Number(packageId);
 
   // 3) DB 조회
-  const { columns, data } = await getFormData(formId, packageIdAsNumber)
+  const { columns, data } = await getFormData(formCode, packageIdAsNumber);
 
-  // 4) 예외 처리
+  // 4) formId 및 report temp file 조회
+  const { formId } = await getFormId(packageId, formCode);
+
+  // 5) 예외 처리
   if (!columns) {
-    return <p className="text-red-500">해당 폼의 메타 정보를 불러올 수 없습니다.</p>
+    return (
+      <p className="text-red-500">해당 폼의 메타 정보를 불러올 수 없습니다.</p>
+    );
   }
 
   // 5) 렌더링
@@ -32,10 +39,11 @@ export default async function FormPage({ params }: IndexPageProps) {
     <div className="space-y-6">
       <DynamicTable
         contractItemId={packageIdAsNumber}
-        formCode={formId}
+        formCode={formCode}
+        formId={formId}
         columnsJSON={columns}
         dataJSON={data}
       />
     </div>
-  )
-}
\ No newline at end of file
+  );
+}
diff --git a/components/form-data/form-data-report-dialog.tsx b/components/form-data/form-data-report-dialog.tsx
new file mode 100644
index 00000000..5ddc5e0c
--- /dev/null
+++ b/components/form-data/form-data-report-dialog.tsx
@@ -0,0 +1,457 @@
+"use client";
+
+import React, {
+  FC,
+  Dispatch,
+  SetStateAction,
+  useState,
+  useEffect,
+  useRef,
+} from "react";
+import { WebViewerInstance, Core } from "@pdftron/webviewer";
+import { useToast } from "@/hooks/use-toast";
+import prettyBytes from "pretty-bytes";
+import { X, Loader2 } from "lucide-react";
+import { Badge } from "@/components/ui/badge";
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+  DialogDescription,
+  DialogFooter,
+} from "@/components/ui/dialog";
+import { Label } from "@/components/ui/label";
+import {
+  Select,
+  SelectContent,
+  SelectGroup,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select";
+import { Button } from "@/components/ui/button";
+import { getReportTempList } from "@/lib/forms/services";
+import { DataTableColumnJSON } from "./form-data-table-columns";
+
+type ReportData = {
+  [key: string]: any;
+};
+
+interface tempFile {
+  fileName: string;
+  filePath: string;
+}
+
+interface FormDataReportDialogProps {
+  columnsJSON: DataTableColumnJSON[];
+  reportData: ReportData[];
+  setReportData: Dispatch<SetStateAction<ReportData[]>>;
+  packageId: number;
+  formId: number;
+  formCode: string;
+}
+
+export const FormDataReportDialog: FC<FormDataReportDialogProps> = ({
+  columnsJSON,
+  reportData,
+  setReportData,
+  packageId,
+  formId,
+}) => {
+  const [tempList, setTempList] = useState<tempFile[]>([]);
+  const [selectTemp, setSelectTemp] = useState<string>("");
+  const [instance, setInstance] = useState<null | WebViewerInstance>(null);
+  const [fileLoading, setFileLoading] = useState<boolean>(true);
+
+  useEffect(() => {
+    updateReportTempList(packageId, formId, setTempList);
+  }, [packageId, formId]);
+
+  const onClose = async (value: boolean) => {
+    if (fileLoading) {
+      return;
+    }
+    if (!value) {
+      setTimeout(() => cleanupHtmlStyle(), 1000);
+      setReportData([]);
+    }
+  };
+
+  const downloadFileData = async () => {
+    if (instance) {
+      const { UI, Core } = instance;
+      const { documentViewer } = Core;
+
+      const doc = documentViewer.getDocument();
+      const fileName = doc.getFilename();
+      const fileData = await doc.getFileData({
+        includeAnnotations: true, // 사용자가 추가한 폼 필드 및 입력 포함
+        // officeOptions: {
+        //   outputFormat: "docx",
+        // },
+      });
+
+      const blob = new Blob([fileData], {
+        type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+      });
+
+      const link = document.createElement("a");
+      link.href = URL.createObjectURL(blob);
+      link.download = fileName;
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+
+      // const allTabs = UI.TabManager.getAllTabs() as {
+      //   id: number;
+      //   src: Core.Document;
+      // }[];
+
+      // for (const tab of allTabs) {
+      //   // await UI.TabManager.setActiveTab(tab.id);
+      //   await activateTabAndWaitForLoad(instance, tab.id);
+      //   const tabDoc = tab.src;
+      //   const fileName = tabDoc.getFilename();
+
+      //   const fileData = await tabDoc.getFileData({
+      //     includeAnnotations: true,
+      //   });
+
+      //   console.log({ fileData });
+
+      //   const blob = new Blob([fileData], {
+      //     type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+      //   });
+
+      //   // 다운로드
+      //   // const link = document.createElement("a");
+      //   // link.href = URL.createObjectURL(blob);
+      //   // link.download = fileName;
+      //   // document.body.appendChild(link);
+      //   // link.click();
+      //   // document.body.removeChild(link);
+      // }
+    }
+  };
+
+  return (
+    <Dialog open={reportData.length > 0} onOpenChange={onClose}>
+      <DialogContent className="w-[70vw]" style={{ maxWidth: "none" }}>
+        <DialogHeader>
+          <DialogTitle>Report</DialogTitle>
+          <DialogDescription>
+            사용하시고자 하는 Report Template를 선택하여 주시기 바랍니다.
+          </DialogDescription>
+        </DialogHeader>
+        <div className="h-[60px]">
+          <Label>Report Template Select</Label>
+          <Select
+            value={selectTemp}
+            onValueChange={setSelectTemp}
+            disabled={instance === null}
+          >
+            <SelectTrigger className="w-[100%]">
+              <SelectValue placeholder="사용하시고자하는 Report Template를 선택하여 주시기 바랍니다." />
+            </SelectTrigger>
+            <SelectContent>
+              {tempList.map((c) => {
+                const { fileName, filePath } = c;
+
+                return (
+                  <SelectItem key={filePath} value={filePath}>
+                    {fileName}
+                  </SelectItem>
+                );
+              })}
+            </SelectContent>
+          </Select>
+        </div>
+        <div className="h-[calc(70vh-60px)]">
+          <ReportWebViewer
+            columnsJSON={columnsJSON}
+            reportTempPath={selectTemp}
+            reportDatas={reportData}
+            instance={instance}
+            setInstance={setInstance}
+            setFileLoading={setFileLoading}
+          />
+        </div>
+
+        <DialogFooter>
+          <Button onClick={downloadFileData} disabled={selectTemp.length === 0}>
+            다운로드
+          </Button>
+        </DialogFooter>
+      </DialogContent>
+    </Dialog>
+  );
+};
+
+interface ReportWebViewerProps {
+  columnsJSON: DataTableColumnJSON[];
+  reportTempPath: string;
+  reportDatas: ReportData[];
+  instance: null | WebViewerInstance;
+  setInstance: Dispatch<SetStateAction<WebViewerInstance | null>>;
+  setFileLoading: Dispatch<SetStateAction<boolean>>;
+}
+
+const ReportWebViewer: FC<ReportWebViewerProps> = ({
+  columnsJSON,
+  reportTempPath,
+  reportDatas,
+  instance,
+  setInstance,
+  setFileLoading,
+}) => {
+  const [viwerLoading, setViewerLoading] = useState<boolean>(true);
+  const viewer = useRef<HTMLDivElement>(null);
+  const initialized = React.useRef(false);
+  const isCancelled = React.useRef(false); // 초기화 중단용 flag
+
+  useEffect(() => {
+    if (!initialized.current) {
+      initialized.current = true;
+      isCancelled.current = false; // 다시 열릴 때는 false로 리셋
+
+      requestAnimationFrame(() => {
+        if (viewer.current) {
+          import("@pdftron/webviewer").then(({ default: WebViewer }) => {
+            console.log(isCancelled.current);
+            if (isCancelled.current) {
+              console.log("📛 WebViewer 초기화 취소됨 (Dialog 닫힘)");
+
+              return;
+            }
+
+            WebViewer(
+              {
+                path: "/pdftronWeb",
+                licenseKey: process.env.NEXT_PUBLIC_PDFTRON_WEBVIEW_KEY,
+                fullAPI: true,
+              },
+              viewer.current as HTMLDivElement
+            ).then(async (instance: WebViewerInstance) => {
+              setInstance(instance);
+              // //Tab 메뉴 사용 필요시 활성화
+              // instance.UI.enableFeatures([instance.UI.Feature.MultiTab]);
+              // instance.UI.disableElements([
+              //   "addTabButton",
+              //   "multiTabsEmptyPage",
+              // ]);
+              setViewerLoading(false);
+            });
+          });
+        }
+      });
+    }
+
+    return () => {
+      // cleanup 시에는 중단 flag 세움
+      if (instance) {
+        instance.UI.dispose();
+      }
+      setTimeout(() => cleanupHtmlStyle(), 500);
+    };
+  }, []);
+
+  useEffect(() => {
+    importReportData(
+      columnsJSON,
+      instance,
+      reportDatas,
+      reportTempPath,
+      setFileLoading
+    );
+  }, [reportTempPath, reportDatas, instance, columnsJSON]);
+
+  return (
+    <div ref={viewer} className="h-[100%]">
+      {viwerLoading && (
+        <div className="flex flex-col items-center justify-center py-12">
+          <Loader2 className="h-8 w-8 text-blue-500 animate-spin mb-4" />
+          <p className="text-sm text-muted-foreground">문서 뷰어 로딩 중...</p>
+        </div>
+      )}
+    </div>
+  );
+};
+
+const cleanupHtmlStyle = () => {
+  const htmlElement = document.documentElement;
+
+  // 기존 style 속성 가져오기
+  const originalStyle = htmlElement.getAttribute("style") || "";
+
+  // "color-scheme: light" 또는 "color-scheme: dark" 찾기
+  const colorSchemeStyle = originalStyle
+    .split(";")
+    .map((s) => s.trim())
+    .find((s) => s.startsWith("color-scheme:"));
+
+  // 새로운 스타일 적용 (color-scheme만 유지)
+  if (colorSchemeStyle) {
+    htmlElement.setAttribute("style", colorSchemeStyle + ";");
+  } else {
+    htmlElement.removeAttribute("style"); // color-scheme도 없으면 style 속성 자체 삭제
+  }
+
+  console.log("html style 삭제");
+};
+
+const stringifyAllValues = (obj: any): any => {
+  if (Array.isArray(obj)) {
+    return obj.map((item) => stringifyAllValues(item));
+  } else if (typeof obj === "object" && obj !== null) {
+    const result: any = {};
+    for (const key in obj) {
+      result[key] = stringifyAllValues(obj[key]);
+    }
+    return result;
+  } else {
+    return obj !== null && obj !== undefined ? String(obj) : "";
+  }
+};
+
+type ImportReportData = (
+  columnsJSON: DataTableColumnJSON[],
+  instance: null | WebViewerInstance,
+  reportDatas: ReportData[],
+  reportTempPath: string,
+  setFileLoading: Dispatch<SetStateAction<boolean>>
+) => void;
+
+const importReportData: ImportReportData = async (
+  columnsJSON,
+  instance,
+  reportDatas,
+  reportTempPath,
+  setFileLoading
+) => {
+  setFileLoading(true);
+  try {
+    if (instance && reportDatas.length > 0 && reportTempPath.length > 0) {
+      const { UI, Core } = instance;
+      const { documentViewer, createDocument } = Core;
+
+      const getFileData = await fetch(reportTempPath);
+      const reportFileBlob = await getFileData.blob();
+
+      const reportData = reportDatas[0];
+      const reportValue = stringifyAllValues(reportData);
+
+      const reportValueMapping: { [key: string]: any } = {};
+
+      columnsJSON.forEach((c) => {
+        const { key, label } = c;
+
+        const objKey = label.split(" ").join("_");
+
+        reportValueMapping[objKey] = reportValue[key];
+      });
+
+      const doc = await createDocument(reportFileBlob, {
+        extension: "docx",
+      });
+
+      await doc.applyTemplateValues(reportValueMapping);
+
+      documentViewer.loadDocument(doc, {
+        extension: "docx",
+        enableOfficeEditing: true,
+        officeOptions: {
+          formatOptions: {
+            applyPageBreaksToSheet: true,
+          },
+        },
+      });
+    }
+  } catch (err) {
+  } finally {
+    setFileLoading(false);
+  }
+};
+
+const importReportDataTab: ImportReportData = async (
+  columnJSON,
+  instance,
+  reportDatas,
+  reportTempPath,
+  setFileLoading
+) => {
+  setFileLoading(true);
+  try {
+    if (instance && reportDatas.length > 0 && reportTempPath.length > 0) {
+      const { UI, Core } = instance;
+      const { createDocument } = Core;
+
+      const getFileData = await fetch(reportTempPath);
+      const reportFileBlob = await getFileData.blob();
+
+      const prevTab = UI.TabManager.getAllTabs();
+
+      (prevTab as object[] as { id: number }[]).forEach((c) => {
+        const { id } = c;
+        UI.TabManager.deleteTab(id);
+      });
+
+      const fileOptions = reportDatas.map((c) => {
+        const { tagNumber } = c;
+
+        const options = {
+          filename: `${tagNumber}_report.docx`,
+        };
+
+        return { options, reportData: c };
+      });
+
+      const tabIds = [];
+
+      for (const fileOption of fileOptions) {
+        let doc = await createDocument(reportFileBlob, {
+          ...fileOption.options,
+          extension: "docx",
+        });
+
+        await doc.applyTemplateValues(
+          stringifyAllValues(fileOption.reportData)
+        );
+
+        const tab = await UI.TabManager.addTab(doc, {
+          ...fileOption.options,
+        });
+
+        tabIds.push(tab); // 탭 ID 저장
+      }
+
+      if (tabIds.length > 0) {
+        await UI.TabManager.setActiveTab(tabIds[0]);
+      }
+    }
+  } catch (err) {
+  } finally {
+    setFileLoading(false);
+  }
+};
+
+type UpdateReportTempList = (
+  packageId: number,
+  formId: number,
+  setPrevReportTemp: Dispatch<SetStateAction<tempFile[]>>
+) => void;
+
+const updateReportTempList: UpdateReportTempList = async (
+  packageId,
+  formId,
+  setTempList
+) => {
+  const tempList = await getReportTempList(packageId, formId);
+
+  setTempList(
+    tempList.map((c) => {
+      const { fileName, filePath } = c;
+      return { fileName, filePath };
+    })
+  );
+};
diff --git a/components/form-data/form-data-report-temp-upload-dialog.tsx b/components/form-data/form-data-report-temp-upload-dialog.tsx
new file mode 100644
index 00000000..b646c3e6
--- /dev/null
+++ b/components/form-data/form-data-report-temp-upload-dialog.tsx
@@ -0,0 +1,305 @@
+"use client";
+
+import React, {
+  FC,
+  Dispatch,
+  SetStateAction,
+  useState,
+  useEffect,
+} from "react";
+import { useToast } from "@/hooks/use-toast";
+import prettyBytes from "pretty-bytes";
+import { X, Loader2 } from "lucide-react";
+import { Badge } from "@/components/ui/badge";
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+  DialogDescription,
+  DialogFooter,
+} from "@/components/ui/dialog";
+import { ScrollArea } from "@/components/ui/scroll-area";
+import { Label } from "@/components/ui/label";
+import { Button } from "@/components/ui/button";
+import {
+  Dropzone,
+  DropzoneDescription,
+  DropzoneInput,
+  DropzoneTitle,
+  DropzoneUploadIcon,
+  DropzoneZone,
+} from "@/components/ui/dropzone";
+import {
+  FileList,
+  FileListAction,
+  FileListDescription,
+  FileListHeader,
+  FileListIcon,
+  FileListInfo,
+  FileListItem,
+  FileListName,
+} from "@/components/ui/file-list";
+import { getReportTempList, uploadReportTemp } from "@/lib/forms/services";
+import { VendorDataReportTemps } from "@/db/schema/vendorData";
+
+interface FormDataReportTempUploadDialogProps {
+  open: boolean;
+  setOpen: Dispatch<SetStateAction<boolean>>;
+  packageId: number;
+  formCode: string;
+  formId: number;
+  uploaderType: string;
+}
+
+// 최대 파일 크기 설정 (3000MB)
+const MAX_FILE_SIZE = 3000000;
+
+export const FormDataReportTempUploadDialog: FC<
+  FormDataReportTempUploadDialogProps
+> = ({ open, setOpen, packageId, formId, uploaderType }) => {
+  const { toast } = useToast();
+  const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
+  const [isUploading, setIsUploading] = useState(false);
+  const [uploadProgress, setUploadProgress] = useState(0);
+  const [prevReportTemp, setPrevReportTemp] = useState<VendorDataReportTemps[]>(
+    []
+  );
+
+  useEffect(() => {
+    updateReportTempList(packageId, formId, setPrevReportTemp);
+  }, [packageId, formId]);
+
+  // 드롭존 - 파일 드랍 처리
+  const handleDropAccepted = (acceptedFiles: File[]) => {
+    const newFiles = [...selectedFiles, ...acceptedFiles];
+    setSelectedFiles(newFiles);
+  };
+
+  // 드롭존 - 파일 거부(에러) 처리
+  const handleDropRejected = (fileRejections: any[]) => {
+    fileRejections.forEach((rejection) => {
+      toast({
+        variant: "destructive",
+        title: "File Error",
+        description: `${rejection.file.name}: ${
+          rejection.errors[0]?.message || "Upload failed"
+        }`,
+      });
+    });
+  };
+
+  // 파일 제거 핸들러
+  const removeFile = (index: number) => {
+    const updatedFiles = [...selectedFiles];
+    updatedFiles.splice(index, 1);
+    setSelectedFiles(updatedFiles);
+  };
+
+  const submitData = async () => {
+    setIsUploading(true);
+    setUploadProgress(0);
+    try {
+      const totalFiles = selectedFiles.length;
+      let successCount = 0;
+
+      for (let i = 0; i < totalFiles; i++) {
+        const file = selectedFiles[i];
+
+        const formData = new FormData();
+        formData.append("file", file);
+        formData.append("customFileName", file.name);
+        formData.append("uploaderType", uploaderType);
+
+        await uploadReportTemp(packageId, formId, formData);
+
+        successCount++;
+        setUploadProgress(Math.round((successCount / totalFiles) * 100));
+      }
+    } catch (err) {
+      console.error(err);
+      toast({
+        title: "Error",
+        description: "파일 업로드 중 오류가 발생했습니다.",
+        variant: "destructive",
+      });
+    } finally {
+      setIsUploading(false);
+      setUploadProgress(0);
+      updateReportTempList(packageId, formId, setPrevReportTemp);
+      setOpen(false);
+    }
+  };
+
+  return (
+    <Dialog open={open} onOpenChange={setOpen}>
+      <DialogContent className="w-[600px]" style={{ maxWidth: "none" }}>
+        <DialogHeader>
+          <DialogTitle>Report Template Upload</DialogTitle>
+          <DialogDescription>
+            사용하시고자 하는 Report Template를 업로드 하여주시기 바랍니다.
+          </DialogDescription>
+        </DialogHeader>
+        {/* {prevReportTemp.length > 0 && (
+          <>
+            <Label>Prev Report Template</Label>
+            <ScrollArea className="max-h-[100px]">
+              {prevReportTemp.map((c, i) => {
+                return <div key={i}>{i}</div>;
+              })}
+            </ScrollArea>
+          </>
+        )} */}
+
+        <Dropzone
+          maxSize={MAX_FILE_SIZE}
+          multiple={true}
+          accept={{ accept: [".docx"] }}
+          onDropAccepted={handleDropAccepted}
+          onDropRejected={handleDropRejected}
+          disabled={isUploading}
+        >
+          {({ maxSize }) => (
+            <>
+              <DropzoneZone className="flex justify-center">
+                <DropzoneInput />
+                <div className="flex items-center gap-6">
+                  <DropzoneUploadIcon />
+                  <div className="grid gap-0.5">
+                    <DropzoneTitle>파일을 여기에 드롭하세요</DropzoneTitle>
+                    <DropzoneDescription>
+                      또는 클릭하여 파일을 선택하세요. 최대 크기:{" "}
+                      {maxSize ? prettyBytes(maxSize) : "무제한"}
+                    </DropzoneDescription>
+                  </div>
+                </div>
+              </DropzoneZone>
+              <Label className="text-xs text-muted-foreground">
+                여러 파일을 선택할 수 있습니다.
+              </Label>
+            </>
+          )}
+        </Dropzone>
+
+        {selectedFiles.length > 0 && (
+          <div className="grid gap-2">
+            <div className="flex items-center justify-between">
+              <h6 className="text-sm font-semibold">
+                선택된 파일 ({selectedFiles.length})
+              </h6>
+              <Badge variant="secondary">{selectedFiles.length}개 파일</Badge>
+            </div>
+            <ScrollArea>
+              <UploadFileItem
+                selectedFiles={selectedFiles}
+                removeFile={removeFile}
+                isUploading={isUploading}
+              />
+            </ScrollArea>
+          </div>
+        )}
+
+        {isUploading && <UploadProgressBox uploadProgress={uploadProgress} />}
+        <DialogFooter>
+          <Button onClick={() => setOpen(false)}>취소</Button>
+          <Button disabled={selectedFiles.length === 0} onClick={submitData}>
+            업로드
+          </Button>
+        </DialogFooter>
+      </DialogContent>
+    </Dialog>
+  );
+};
+
+interface UploadFileItemProps {
+  selectedFiles: File[];
+  removeFile: (index: number) => void;
+  isUploading: boolean;
+}
+
+const UploadFileItem: FC<UploadFileItemProps> = ({
+  selectedFiles,
+  removeFile,
+  isUploading,
+}) => {
+  return (
+    <FileList className="max-h-[200px] gap-3">
+      {selectedFiles.map((file, index) => (
+        <FileListItem key={index} className="p-3">
+          <FileListHeader>
+            <FileListIcon />
+            <FileListInfo>
+              <FileListName>{file.name}</FileListName>
+              <FileListDescription>
+                {prettyBytes(file.size)}
+              </FileListDescription>
+            </FileListInfo>
+            <FileListAction
+              onClick={() => removeFile(index)}
+              disabled={isUploading}
+            >
+              <X className="h-4 w-4" />
+              <span className="sr-only">Remove</span>
+            </FileListAction>
+          </FileListHeader>
+        </FileListItem>
+      ))}
+    </FileList>
+  );
+};
+
+const UploadProgressBox: FC<{ uploadProgress: number }> = ({
+  uploadProgress,
+}) => {
+  return (
+    <div className="flex flex-col gap-1 mt-2">
+      <div className="flex items-center gap-2">
+        <Loader2 className="h-4 w-4 animate-spin" />
+        <span className="text-sm">{uploadProgress}% 업로드 중...</span>
+      </div>
+      <div className="h-2 w-full bg-muted rounded-full overflow-hidden">
+        <div
+          className="h-full bg-primary rounded-full transition-all"
+          style={{ width: `${uploadProgress}%` }}
+        />
+      </div>
+    </div>
+  );
+};
+
+const generateFileName = (
+  packageId: number,
+  formId: number,
+  originalFileName: string,
+  index: number,
+  totalFiles: number
+) => {
+  // Get the file extension
+  const extension = originalFileName.split(".").pop() || "";
+
+  // Base name without extension
+  const baseName = `${packageId}_${formId}`;
+
+  // For multiple files, add a suffix
+  if (totalFiles > 1) {
+    return `${baseName}_${index + 1}.${extension}`;
+  }
+
+  // For a single file, no suffix needed
+  return `${baseName}.${extension}`;
+};
+
+type UpdateReportTempList = (
+  packageId: number,
+  formId: number,
+  setPrevReportTemp: Dispatch<SetStateAction<VendorDataReportTemps[]>>
+) => void;
+
+const updateReportTempList: UpdateReportTempList = async (
+  packageId,
+  formId,
+  setPrevReportTemp
+) => {
+  const tempList = await getReportTempList(packageId, formId);
+  setPrevReportTemp(tempList);
+};
diff --git a/components/form-data/form-data-table-columns.tsx b/components/form-data/form-data-table-columns.tsx
index d44616f8..38f5cad8 100644
--- a/components/form-data/form-data-table-columns.tsx
+++ b/components/form-data/form-data-table-columns.tsx
@@ -27,24 +27,27 @@ export type ColumnType = "STRING" | "NUMBER" | "LIST"
 
 
 export interface DataTableColumnJSON {
-  key: string
+  key: string;
   /** 실제 Excel 등에서 구분용으로 쓰이는 label (고정) */
   label: string
 
   /** UI 표시용 label (예: 단위를 함께 표시) */
   displayLabel?: string
 
-  type: ColumnType
-  options?: string[]
-  uom?: string
+  type: ColumnType;
+  options?: string[];
+  uom?: string;
 }
-/** 
- * getColumns 함수에 필요한 props 
+/**
+ * getColumns 함수에 필요한 props
  * - TData: 테이블에 표시할 행(Row)의 타입
  */
 interface GetColumnsProps<TData> {
-  columnsJSON: DataTableColumnJSON[]
-  setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<TData> | null>>
+  columnsJSON: DataTableColumnJSON[];
+  setRowAction: React.Dispatch<
+    React.SetStateAction<DataTableRowAction<TData> | null>
+  >;
+  setReportData: React.Dispatch<React.SetStateAction<{ [key: string]: any }[]>>;
 }
 
 /**
@@ -55,8 +58,8 @@ interface GetColumnsProps<TData> {
 export function getColumns<TData extends object>({
   columnsJSON,
   setRowAction,
+  setReportData,
 }: GetColumnsProps<TData>): ColumnDef<TData>[] {
-
   // (1) 기본 컬럼들
   const baseColumns: ColumnDef<TData>[] = columnsJSON.map((col) => ({
     accessorKey: col.key,
@@ -71,7 +74,7 @@ export function getColumns<TData extends object>({
       excelHeader: col.label,
       minWidth: 80,
       paddingFactor: 1.2,
-      maxWidth: col.key ==="tagNumber"?120:150,
+      maxWidth: col.key === "tagNumber" ? 120 : 150,
     },
     // (2) 실제 셀(cell) 렌더링: type에 따라 분기 가능
     cell: ({ row }) => {
@@ -81,7 +84,9 @@ export function getColumns<TData extends object>({
       switch (col.type) {
         case "NUMBER":
           // 예: number인 경우 콤마 등 표시
-          return <div>{cellValue ? Number(cellValue).toLocaleString() : ""}</div>
+          return (
+            <div>{cellValue ? Number(cellValue).toLocaleString() : ""}</div>
+          );
 
         // case "date":
         //   // 예: 날짜 포맷팅
@@ -108,30 +113,38 @@ export function getColumns<TData extends object>({
     header: "",
     cell: ({ row }) => (
       <DropdownMenu>
-      <DropdownMenuTrigger asChild>
-        <Button
-          aria-label="Open menu"
-          variant="ghost"
-          className="flex size-8 p-0 data-[state=open]:bg-muted"
-        >
-          <Ellipsis className="size-4" aria-hidden="true" />
-        </Button>
-      </DropdownMenuTrigger>
-      <DropdownMenuContent align="end" className="w-40">
-        <DropdownMenuItem
-          onSelect={() => setRowAction({ row, type: "update" })}
-        >
-          Edit
-        </DropdownMenuItem>
-      </DropdownMenuContent>
-    </DropdownMenu>
+        <DropdownMenuTrigger asChild>
+          <Button
+            aria-label="Open menu"
+            variant="ghost"
+            className="flex size-8 p-0 data-[state=open]:bg-muted"
+          >
+            <Ellipsis className="size-4" aria-hidden="true" />
+          </Button>
+        </DropdownMenuTrigger>
+        <DropdownMenuContent align="end" className="w-40">
+          <DropdownMenuItem
+            onSelect={() => setRowAction({ row, type: "update" })}
+          >
+            Edit
+          </DropdownMenuItem>
+          <DropdownMenuItem
+            onSelect={() => {
+              const { original } = row;
+              setReportData([original]);
+            }}
+          >
+            Create Report
+          </DropdownMenuItem>
+        </DropdownMenuContent>
+      </DropdownMenu>
     ),
-    size:40,
-    meta:{
-      maxWidth:40
+    size: 40,
+    meta: {
+      // maxWidth: 40,
     },
     enablePinning: true,
-  }
+  };
 
   // (4) 최종 반환
   return [...baseColumns, actionColumn]
diff --git a/config/poColumnsConfig.ts b/config/poColumnsConfig.ts
index 6466f3e1..606c6ab4 100644
--- a/config/poColumnsConfig.ts
+++ b/config/poColumnsConfig.ts
@@ -51,6 +51,14 @@ export const poColumnsConfig: PoColumnConfig[] = [
     group: "Basic Info",
     type: "text",
   },
+  {
+    id: "esignStatus",              // db에 없는 가상 컬럼
+    label: "E-Sign Status",
+    excelHeader: "E-Sign Status",
+    group: "Basic Info",
+    type: "custom",                 // 커스텀 렌더링이 필요함을 나타냄
+    customType: "esignStatus",      // 구분이 필요한 경우 추가 필드
+  },
   {
     id: "startDate",
     label: "Start Date",
diff --git a/db/migrations/0103_huge_wallflower.sql b/db/migrations/0103_huge_wallflower.sql
new file mode 100644
index 00000000..b108d28f
--- /dev/null
+++ b/db/migrations/0103_huge_wallflower.sql
@@ -0,0 +1,37 @@
+DROP VIEW "public"."contracts_detail_view";--> statement-breakpoint
+CREATE VIEW "public"."contracts_detail_view" AS (select "contracts"."id", "contracts"."contract_no", "contracts"."contract_name", "contracts"."status", "contracts"."start_date", "contracts"."end_date", "contracts"."project_id", "projects"."code", "projects"."name", "contracts"."vendor_id", "vendors"."vendor_name", "contracts"."payment_terms", "contracts"."delivery_terms", "contracts"."delivery_date", "contracts"."delivery_location", "contracts"."currency", "contracts"."total_amount", "contracts"."discount", "contracts"."tax", "contracts"."shipping_fee", "contracts"."net_total", "contracts"."partial_shipping_allowed", "contracts"."partial_payment_allowed", "contracts"."remarks", "contracts"."version", "contracts"."created_at", "contracts"."updated_at", EXISTS (
+                SELECT 1 
+                FROM "contract_envelopes" 
+                WHERE "contract_envelopes"."contract_id" = "contracts"."id"
+            ) as "has_signature", COALESCE((
+        SELECT json_agg(
+          json_build_object(
+            'id', ce.id,
+            'envelopeId', ce.envelope_id,
+            'documentId', ce.document_id,
+            'envelopeStatus', ce.envelope_status,
+            'fileName', ce.file_name,
+            'filePath', ce.file_path,
+            'createdAt', ce.created_at,
+            'updatedAt', ce.updated_at,
+            'signers', (
+              SELECT json_agg(
+                json_build_object(
+                  'id', cs.id,
+                  'vendorContactId', cs.vendor_contact_id,
+                  'signerType', cs.signer_type,
+                  'signerEmail', cs.signer_email,
+                  'signerName', cs.signer_name,
+                  'signerPosition', cs.signer_position,
+                  'signerStatus', cs.signer_status,
+                  'signedAt', cs.signed_at
+                )
+              )
+              FROM "contract_signers" AS cs
+              WHERE cs.envelope_id = ce.id
+            )
+          )
+        )
+        FROM "contract_envelopes" AS ce
+        WHERE ce.contract_id = "contracts"."id"
+    ), '[]') as "envelopes" from "contracts" left join "projects" on "contracts"."project_id" = "projects"."id" left join "vendors" on "contracts"."vendor_id" = "vendors"."id");
\ No newline at end of file
diff --git a/db/migrations/meta/0103_snapshot.json b/db/migrations/meta/0103_snapshot.json
new file mode 100644
index 00000000..a334d505
--- /dev/null
+++ b/db/migrations/meta/0103_snapshot.json
@@ -0,0 +1,4757 @@
+{
+  "id": "c61340a1-8aed-47e6-8d5b-7528e1a5538f",
+  "prevId": "1f9424b7-fa9e-44bf-a5d1-dbceb2d9da56",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.companies": {
+      "name": "companies",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "companies_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "taxID": {
+          "name": "taxID",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.contract_envelopes": {
+      "name": "contract_envelopes",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "contract_envelopes_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_id": {
+          "name": "contract_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "envelope_id": {
+          "name": "envelope_id",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "document_id": {
+          "name": "document_id",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "envelope_status": {
+          "name": "envelope_status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "contract_envelopes_contract_id_contracts_id_fk": {
+          "name": "contract_envelopes_contract_id_contracts_id_fk",
+          "tableFrom": "contract_envelopes",
+          "tableTo": "contracts",
+          "columnsFrom": [
+            "contract_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.contract_items": {
+      "name": "contract_items",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "contract_items_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_id": {
+          "name": "contract_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "item_id": {
+          "name": "item_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "quantity": {
+          "name": "quantity",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "unit_price": {
+          "name": "unit_price",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tax_rate": {
+          "name": "tax_rate",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tax_amount": {
+          "name": "tax_amount",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_line_amount": {
+          "name": "total_line_amount",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "remark": {
+          "name": "remark",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "contract_items_contract_item_idx": {
+          "name": "contract_items_contract_item_idx",
+          "columns": [
+            {
+              "expression": "contract_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "item_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "contract_items_contract_id_contracts_id_fk": {
+          "name": "contract_items_contract_id_contracts_id_fk",
+          "tableFrom": "contract_items",
+          "tableTo": "contracts",
+          "columnsFrom": [
+            "contract_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "contract_items_contract_id_item_id_unique": {
+          "name": "contract_items_contract_id_item_id_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "contract_id",
+            "item_id"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.contract_signers": {
+      "name": "contract_signers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "contract_signers_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "envelope_id": {
+          "name": "envelope_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_contact_id": {
+          "name": "vendor_contact_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "signer_type": {
+          "name": "signer_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'VENDOR'"
+        },
+        "signer_email": {
+          "name": "signer_email",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "signer_name": {
+          "name": "signer_name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "signer_position": {
+          "name": "signer_position",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "signer_status": {
+          "name": "signer_status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'PENDING'"
+        },
+        "signed_at": {
+          "name": "signed_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "contract_signers_envelope_id_contract_envelopes_id_fk": {
+          "name": "contract_signers_envelope_id_contract_envelopes_id_fk",
+          "tableFrom": "contract_signers",
+          "tableTo": "contract_envelopes",
+          "columnsFrom": [
+            "envelope_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "contract_signers_vendor_contact_id_vendor_contacts_id_fk": {
+          "name": "contract_signers_vendor_contact_id_vendor_contacts_id_fk",
+          "tableFrom": "contract_signers",
+          "tableTo": "vendor_contacts",
+          "columnsFrom": [
+            "vendor_contact_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.contracts": {
+      "name": "contracts",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "contracts_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "project_id": {
+          "name": "project_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contract_no": {
+          "name": "contract_no",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contract_name": {
+          "name": "contract_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'ACTIVE'"
+        },
+        "start_date": {
+          "name": "start_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "end_date": {
+          "name": "end_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "payment_terms": {
+          "name": "payment_terms",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_terms": {
+          "name": "delivery_terms",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_date": {
+          "name": "delivery_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_location": {
+          "name": "delivery_location",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "currency": {
+          "name": "currency",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'KRW'"
+        },
+        "total_amount": {
+          "name": "total_amount",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "discount": {
+          "name": "discount",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tax": {
+          "name": "tax",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "shipping_fee": {
+          "name": "shipping_fee",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "net_total": {
+          "name": "net_total",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "partial_shipping_allowed": {
+          "name": "partial_shipping_allowed",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "partial_payment_allowed": {
+          "name": "partial_payment_allowed",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "remarks": {
+          "name": "remarks",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "version": {
+          "name": "version",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "contracts_project_id_projects_id_fk": {
+          "name": "contracts_project_id_projects_id_fk",
+          "tableFrom": "contracts",
+          "tableTo": "projects",
+          "columnsFrom": [
+            "project_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "contracts_vendor_id_vendors_id_fk": {
+          "name": "contracts_vendor_id_vendors_id_fk",
+          "tableFrom": "contracts",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "contracts_contract_no_unique": {
+          "name": "contracts_contract_no_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "contract_no"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.items": {
+      "name": "items",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "item_code": {
+          "name": "item_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "item_name": {
+          "name": "item_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "items_item_code_unique": {
+          "name": "items_item_code_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "item_code"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.pq_criterias": {
+      "name": "pq_criterias",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "check_point": {
+          "name": "check_point",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "remarks": {
+          "name": "remarks",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_name": {
+          "name": "group_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_criteria_attachments": {
+      "name": "vendor_criteria_attachments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_criteria_answer_id": {
+          "name": "vendor_criteria_answer_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_type": {
+          "name": "file_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_size": {
+          "name": "file_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_criteria_attachments_vendor_criteria_answer_id_vendor_pq_criteria_answers_id_fk": {
+          "name": "vendor_criteria_attachments_vendor_criteria_answer_id_vendor_pq_criteria_answers_id_fk",
+          "tableFrom": "vendor_criteria_attachments",
+          "tableTo": "vendor_pq_criteria_answers",
+          "columnsFrom": [
+            "vendor_criteria_answer_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_pq_criteria_answers": {
+      "name": "vendor_pq_criteria_answers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "criteria_id": {
+          "name": "criteria_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "answer": {
+          "name": "answer",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_pq_criteria_answers_vendor_id_vendors_id_fk": {
+          "name": "vendor_pq_criteria_answers_vendor_id_vendors_id_fk",
+          "tableFrom": "vendor_pq_criteria_answers",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "vendor_pq_criteria_answers_criteria_id_pq_criterias_id_fk": {
+          "name": "vendor_pq_criteria_answers_criteria_id_pq_criterias_id_fk",
+          "tableFrom": "vendor_pq_criteria_answers",
+          "tableTo": "pq_criterias",
+          "columnsFrom": [
+            "criteria_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_pq_review_logs": {
+      "name": "vendor_pq_review_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_pq_criteria_answer_id": {
+          "name": "vendor_pq_criteria_answer_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "reviewer_comment": {
+          "name": "reviewer_comment",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "reviewer_name": {
+          "name": "reviewer_name",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_pq_review_logs_vendor_pq_criteria_answer_id_vendor_pq_criteria_answers_id_fk": {
+          "name": "vendor_pq_review_logs_vendor_pq_criteria_answer_id_vendor_pq_criteria_answers_id_fk",
+          "tableFrom": "vendor_pq_review_logs",
+          "tableTo": "vendor_pq_criteria_answers",
+          "columnsFrom": [
+            "vendor_pq_criteria_answer_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.projects": {
+      "name": "projects",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "type": {
+          "name": "type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'ship'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.cbe_evaluations": {
+      "name": "cbe_evaluations",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "evaluated_by": {
+          "name": "evaluated_by",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "evaluated_at": {
+          "name": "evaluated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "result": {
+          "name": "result",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost": {
+          "name": "total_cost",
+          "type": "numeric(18, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "currency": {
+          "name": "currency",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'USD'"
+        },
+        "payment_terms": {
+          "name": "payment_terms",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "incoterms": {
+          "name": "incoterms",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_schedule": {
+          "name": "delivery_schedule",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "notes": {
+          "name": "notes",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "cbe_evaluations_rfq_id_rfqs_id_fk": {
+          "name": "cbe_evaluations_rfq_id_rfqs_id_fk",
+          "tableFrom": "cbe_evaluations",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "cbe_evaluations_vendor_id_vendors_id_fk": {
+          "name": "cbe_evaluations_vendor_id_vendors_id_fk",
+          "tableFrom": "cbe_evaluations",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "cbe_evaluations_evaluated_by_users_id_fk": {
+          "name": "cbe_evaluations_evaluated_by_users_id_fk",
+          "tableFrom": "cbe_evaluations",
+          "tableTo": "users",
+          "columnsFrom": [
+            "evaluated_by"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.rfq_attachments": {
+      "name": "rfq_attachments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "evaluation_id": {
+          "name": "evaluation_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cbe_id": {
+          "name": "cbe_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "comment_id": {
+          "name": "comment_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "rfq_attachments_rfq_id_rfqs_id_fk": {
+          "name": "rfq_attachments_rfq_id_rfqs_id_fk",
+          "tableFrom": "rfq_attachments",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_attachments_vendor_id_vendors_id_fk": {
+          "name": "rfq_attachments_vendor_id_vendors_id_fk",
+          "tableFrom": "rfq_attachments",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_attachments_evaluation_id_rfq_evaluations_id_fk": {
+          "name": "rfq_attachments_evaluation_id_rfq_evaluations_id_fk",
+          "tableFrom": "rfq_attachments",
+          "tableTo": "rfq_evaluations",
+          "columnsFrom": [
+            "evaluation_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_attachments_cbe_id_cbe_evaluations_id_fk": {
+          "name": "rfq_attachments_cbe_id_cbe_evaluations_id_fk",
+          "tableFrom": "rfq_attachments",
+          "tableTo": "cbe_evaluations",
+          "columnsFrom": [
+            "cbe_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_attachments_comment_id_rfq_comments_id_fk": {
+          "name": "rfq_attachments_comment_id_rfq_comments_id_fk",
+          "tableFrom": "rfq_attachments",
+          "tableTo": "rfq_comments",
+          "columnsFrom": [
+            "comment_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.rfq_comments": {
+      "name": "rfq_comments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "comment_text": {
+          "name": "comment_text",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "commented_by": {
+          "name": "commented_by",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "evaluation_id": {
+          "name": "evaluation_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cbe_id": {
+          "name": "cbe_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "rfq_comments_rfq_id_rfqs_id_fk": {
+          "name": "rfq_comments_rfq_id_rfqs_id_fk",
+          "tableFrom": "rfq_comments",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_comments_vendor_id_vendors_id_fk": {
+          "name": "rfq_comments_vendor_id_vendors_id_fk",
+          "tableFrom": "rfq_comments",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_comments_commented_by_users_id_fk": {
+          "name": "rfq_comments_commented_by_users_id_fk",
+          "tableFrom": "rfq_comments",
+          "tableTo": "users",
+          "columnsFrom": [
+            "commented_by"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_comments_evaluation_id_rfq_evaluations_id_fk": {
+          "name": "rfq_comments_evaluation_id_rfq_evaluations_id_fk",
+          "tableFrom": "rfq_comments",
+          "tableTo": "rfq_evaluations",
+          "columnsFrom": [
+            "evaluation_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_comments_cbe_id_cbe_evaluations_id_fk": {
+          "name": "rfq_comments_cbe_id_cbe_evaluations_id_fk",
+          "tableFrom": "rfq_comments",
+          "tableTo": "cbe_evaluations",
+          "columnsFrom": [
+            "cbe_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.rfq_evaluations": {
+      "name": "rfq_evaluations",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "eval_type": {
+          "name": "eval_type",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "result": {
+          "name": "result",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "notes": {
+          "name": "notes",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "rfq_evaluations_rfq_id_rfqs_id_fk": {
+          "name": "rfq_evaluations_rfq_id_rfqs_id_fk",
+          "tableFrom": "rfq_evaluations",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "rfq_evaluations_vendor_id_vendors_id_fk": {
+          "name": "rfq_evaluations_vendor_id_vendors_id_fk",
+          "tableFrom": "rfq_evaluations",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.rfq_items": {
+      "name": "rfq_items",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "item_code": {
+          "name": "item_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "quantity": {
+          "name": "quantity",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "uom": {
+          "name": "uom",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "rfq_items_rfq_id_rfqs_id_fk": {
+          "name": "rfq_items_rfq_id_rfqs_id_fk",
+          "tableFrom": "rfq_items",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "rfq_items_item_code_items_item_code_fk": {
+          "name": "rfq_items_item_code_items_item_code_fk",
+          "tableFrom": "rfq_items",
+          "tableTo": "items",
+          "columnsFrom": [
+            "item_code"
+          ],
+          "columnsTo": [
+            "item_code"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.rfqs": {
+      "name": "rfqs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_code": {
+          "name": "rfq_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "project_id": {
+          "name": "project_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "description": {
+          "name": "description",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "due_date": {
+          "name": "due_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'DRAFT'"
+        },
+        "rfq_type": {
+          "name": "rfq_type",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'PURCHASE'"
+        },
+        "parent_rfq_id": {
+          "name": "parent_rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_by": {
+          "name": "created_by",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "rfqs_project_id_projects_id_fk": {
+          "name": "rfqs_project_id_projects_id_fk",
+          "tableFrom": "rfqs",
+          "tableTo": "projects",
+          "columnsFrom": [
+            "project_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        },
+        "rfqs_created_by_users_id_fk": {
+          "name": "rfqs_created_by_users_id_fk",
+          "tableFrom": "rfqs",
+          "tableTo": "users",
+          "columnsFrom": [
+            "created_by"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        },
+        "rfqs_parent_rfq_id_rfqs_id_fk": {
+          "name": "rfqs_parent_rfq_id_rfqs_id_fk",
+          "tableFrom": "rfqs",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "parent_rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "rfqs_rfq_code_unique": {
+          "name": "rfqs_rfq_code_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "rfq_code"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_commercial_responses": {
+      "name": "vendor_commercial_responses",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "response_id": {
+          "name": "response_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "total_price": {
+          "name": "total_price",
+          "type": "numeric(18, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "currency": {
+          "name": "currency",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'USD'"
+        },
+        "payment_terms": {
+          "name": "payment_terms",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "incoterms": {
+          "name": "incoterms",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_period": {
+          "name": "delivery_period",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "warranty_period": {
+          "name": "warranty_period",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "validity_period": {
+          "name": "validity_period",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "price_breakdown": {
+          "name": "price_breakdown",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "commercial_notes": {
+          "name": "commercial_notes",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_commercial_responses_response_id_vendor_responses_id_fk": {
+          "name": "vendor_commercial_responses_response_id_vendor_responses_id_fk",
+          "tableFrom": "vendor_commercial_responses",
+          "tableTo": "vendor_responses",
+          "columnsFrom": [
+            "response_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_response_attachments": {
+      "name": "vendor_response_attachments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "response_id": {
+          "name": "response_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "technical_response_id": {
+          "name": "technical_response_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "commercial_response_id": {
+          "name": "commercial_response_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_type": {
+          "name": "file_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "attachment_type": {
+          "name": "attachment_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "description": {
+          "name": "description",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "uploaded_at": {
+          "name": "uploaded_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "uploaded_by": {
+          "name": "uploaded_by",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_response_attachments_response_id_vendor_responses_id_fk": {
+          "name": "vendor_response_attachments_response_id_vendor_responses_id_fk",
+          "tableFrom": "vendor_response_attachments",
+          "tableTo": "vendor_responses",
+          "columnsFrom": [
+            "response_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "vendor_response_attachments_technical_response_id_vendor_technical_responses_id_fk": {
+          "name": "vendor_response_attachments_technical_response_id_vendor_technical_responses_id_fk",
+          "tableFrom": "vendor_response_attachments",
+          "tableTo": "vendor_technical_responses",
+          "columnsFrom": [
+            "technical_response_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "vendor_response_attachments_commercial_response_id_vendor_commercial_responses_id_fk": {
+          "name": "vendor_response_attachments_commercial_response_id_vendor_commercial_responses_id_fk",
+          "tableFrom": "vendor_response_attachments",
+          "tableTo": "vendor_commercial_responses",
+          "columnsFrom": [
+            "commercial_response_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_responses": {
+      "name": "vendor_responses",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "rfq_id": {
+          "name": "rfq_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "response_status": {
+          "name": "response_status",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'REVIEWING'"
+        },
+        "notes": {
+          "name": "notes",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "responded_by": {
+          "name": "responded_by",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "responded_at": {
+          "name": "responded_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "vendor_response_unique": {
+          "name": "vendor_response_unique",
+          "columns": [
+            {
+              "expression": "rfq_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "vendor_responses_rfq_id_rfqs_id_fk": {
+          "name": "vendor_responses_rfq_id_rfqs_id_fk",
+          "tableFrom": "vendor_responses",
+          "tableTo": "rfqs",
+          "columnsFrom": [
+            "rfq_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "vendor_responses_vendor_id_vendors_id_fk": {
+          "name": "vendor_responses_vendor_id_vendors_id_fk",
+          "tableFrom": "vendor_responses",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_technical_responses": {
+      "name": "vendor_technical_responses",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "response_id": {
+          "name": "response_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "summary": {
+          "name": "summary",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "notes": {
+          "name": "notes",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_technical_responses_response_id_vendor_responses_id_fk": {
+          "name": "vendor_technical_responses_response_id_vendor_responses_id_fk",
+          "tableFrom": "vendor_technical_responses",
+          "tableTo": "vendor_responses",
+          "columnsFrom": [
+            "response_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tasks": {
+      "name": "tasks",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "varchar(30)",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "concat('TASK-', to_char(nextval('tasks_code_seq'), 'FM0000'))"
+        },
+        "title": {
+          "name": "title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'todo'"
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'bug'"
+        },
+        "priority": {
+          "name": "priority",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'low'"
+        },
+        "archived": {
+          "name": "archived",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "current_timestamp"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "tasks_code_unique": {
+          "name": "tasks_code_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "code"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.otps": {
+      "name": "otps",
+      "schema": "",
+      "columns": {
+        "email": {
+          "name": "email",
+          "type": "varchar(256)",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(6)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "otpToken": {
+          "name": "otpToken",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "otp_expires": {
+          "name": "otp_expires",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.permissions": {
+      "name": "permissions",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "permissions_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "permission_key": {
+          "name": "permission_key",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.role_permissions": {
+      "name": "role_permissions",
+      "schema": "",
+      "columns": {
+        "role_id": {
+          "name": "role_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "permission_id": {
+          "name": "permission_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "role_permissions_role_id_roles_id_fk": {
+          "name": "role_permissions_role_id_roles_id_fk",
+          "tableFrom": "role_permissions",
+          "tableTo": "roles",
+          "columnsFrom": [
+            "role_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "role_permissions_permission_id_permissions_id_fk": {
+          "name": "role_permissions_permission_id_permissions_id_fk",
+          "tableFrom": "role_permissions",
+          "tableTo": "permissions",
+          "columnsFrom": [
+            "permission_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.roles": {
+      "name": "roles",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "roles_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "name": {
+          "name": "name",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "domain": {
+          "name": "domain",
+          "type": "user_domain",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "company_id": {
+          "name": "company_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "''"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "roles_company_id_vendors_id_fk": {
+          "name": "roles_company_id_vendors_id_fk",
+          "tableFrom": "roles",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "company_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.user_roles": {
+      "name": "user_roles",
+      "schema": "",
+      "columns": {
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "role_id": {
+          "name": "role_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "user_roles_user_id_users_id_fk": {
+          "name": "user_roles_user_id_users_id_fk",
+          "tableFrom": "user_roles",
+          "tableTo": "users",
+          "columnsFrom": [
+            "user_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "user_roles_role_id_roles_id_fk": {
+          "name": "user_roles_role_id_roles_id_fk",
+          "tableFrom": "user_roles",
+          "tableTo": "roles",
+          "columnsFrom": [
+            "role_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "users_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "email": {
+          "name": "email",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "company_id": {
+          "name": "company_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "domain": {
+          "name": "domain",
+          "type": "user_domain",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'partners'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "image_url": {
+          "name": "image_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "users_company_id_vendors_id_fk": {
+          "name": "users_company_id_vendors_id_fk",
+          "tableFrom": "users",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "company_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "users_email_unique": {
+          "name": "users_email_unique",
+          "nullsNotDistinct": false,
+          "columns": [
+            "email"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.form_entries": {
+      "name": "form_entries",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "form_code": {
+          "name": "form_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "data": {
+          "name": "data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contract_item_id": {
+          "name": "contract_item_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "form_entries_contract_item_id_contract_items_id_fk": {
+          "name": "form_entries_contract_item_id_contract_items_id_fk",
+          "tableFrom": "form_entries",
+          "tableTo": "contract_items",
+          "columnsFrom": [
+            "contract_item_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.form_metas": {
+      "name": "form_metas",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "form_code": {
+          "name": "form_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_name": {
+          "name": "form_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "columns": {
+          "name": "columns",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.forms": {
+      "name": "forms",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "forms_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_item_id": {
+          "name": "contract_item_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_code": {
+          "name": "form_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_name": {
+          "name": "form_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "contract_item_form_code_unique": {
+          "name": "contract_item_form_code_unique",
+          "columns": [
+            {
+              "expression": "contract_item_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "form_code",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "forms_contract_item_id_contract_items_id_fk": {
+          "name": "forms_contract_item_id_contract_items_id_fk",
+          "tableFrom": "forms",
+          "tableTo": "contract_items",
+          "columnsFrom": [
+            "contract_item_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.form_templates": {
+      "name": "form_templates",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "form_id": {
+          "name": "form_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "form_templates_form_id_forms_id_fk": {
+          "name": "form_templates_form_id_forms_id_fk",
+          "tableFrom": "form_templates",
+          "tableTo": "forms",
+          "columnsFrom": [
+            "form_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tag_classes": {
+      "name": "tag_classes",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "tag_classes_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "tag_type_code": {
+          "name": "tag_type_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "tag_classes_tag_type_code_tag_types_code_fk": {
+          "name": "tag_classes_tag_type_code_tag_types_code_fk",
+          "tableFrom": "tag_classes",
+          "tableTo": "tag_types",
+          "columnsFrom": [
+            "tag_type_code"
+          ],
+          "columnsTo": [
+            "code"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tag_subfield_options": {
+      "name": "tag_subfield_options",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "attributes_id": {
+          "name": "attributes_id",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "tag_subfield_options_attributes_id_tag_subfields_attributes_id_fk": {
+          "name": "tag_subfield_options_attributes_id_tag_subfields_attributes_id_fk",
+          "tableFrom": "tag_subfield_options",
+          "tableTo": "tag_subfields",
+          "columnsFrom": [
+            "attributes_id"
+          ],
+          "columnsTo": [
+            "attributes_id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tag_subfields": {
+      "name": "tag_subfields",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "tag_type_code": {
+          "name": "tag_type_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "attributes_id": {
+          "name": "attributes_id",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "attributes_description": {
+          "name": "attributes_description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "expression": {
+          "name": "expression",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delimiter": {
+          "name": "delimiter",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "tag_subfields_tag_type_code_tag_types_code_fk": {
+          "name": "tag_subfields_tag_type_code_tag_types_code_fk",
+          "tableFrom": "tag_subfields",
+          "tableTo": "tag_types",
+          "columnsFrom": [
+            "tag_type_code"
+          ],
+          "columnsTo": [
+            "code"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {
+        "uniq_tag_type_attribute": {
+          "name": "uniq_tag_type_attribute",
+          "nullsNotDistinct": false,
+          "columns": [
+            "tag_type_code",
+            "attributes_id"
+          ]
+        }
+      },
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tag_type_class_form_mappings": {
+      "name": "tag_type_class_form_mappings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "tag_type_label": {
+          "name": "tag_type_label",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "class_label": {
+          "name": "class_label",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_code": {
+          "name": "form_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_name": {
+          "name": "form_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tag_types": {
+      "name": "tag_types",
+      "schema": "",
+      "columns": {
+        "code": {
+          "name": "code",
+          "type": "varchar(50)",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.tags": {
+      "name": "tags",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "tags_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_item_id": {
+          "name": "contract_item_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_id": {
+          "name": "form_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tag_no": {
+          "name": "tag_no",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "tag_type": {
+          "name": "tag_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "class": {
+          "name": "class",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "tags_contract_item_id_contract_items_id_fk": {
+          "name": "tags_contract_item_id_contract_items_id_fk",
+          "tableFrom": "tags",
+          "tableTo": "contract_items",
+          "columnsFrom": [
+            "contract_item_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "tags_form_id_forms_id_fk": {
+          "name": "tags_form_id_forms_id_fk",
+          "tableFrom": "tags",
+          "tableTo": "forms",
+          "columnsFrom": [
+            "form_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "set null",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_data_report_temps": {
+      "name": "vendor_data_report_temps",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "contract_item_id": {
+          "name": "contract_item_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "form_id": {
+          "name": "form_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_data_report_temps_contract_item_id_contract_items_id_fk": {
+          "name": "vendor_data_report_temps_contract_item_id_contract_items_id_fk",
+          "tableFrom": "vendor_data_report_temps",
+          "tableTo": "contract_items",
+          "columnsFrom": [
+            "contract_item_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        },
+        "vendor_data_report_temps_form_id_forms_id_fk": {
+          "name": "vendor_data_report_temps_form_id_forms_id_fk",
+          "tableFrom": "vendor_data_report_temps",
+          "tableTo": "forms",
+          "columnsFrom": [
+            "form_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.view_tag_subfields": {
+      "name": "view_tag_subfields",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "tag_type_code": {
+          "name": "tag_type_code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "tag_type_description": {
+          "name": "tag_type_description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "attributes_id": {
+          "name": "attributes_id",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "attributes_description": {
+          "name": "attributes_description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "expression": {
+          "name": "expression",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delimiter": {
+          "name": "delimiter",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.document_attachments": {
+      "name": "document_attachments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "document_attachments_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "revision_id": {
+          "name": "revision_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_type": {
+          "name": "file_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_size": {
+          "name": "file_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "document_attachments_revision_id_revisions_id_fk": {
+          "name": "document_attachments_revision_id_revisions_id_fk",
+          "tableFrom": "document_attachments",
+          "tableTo": "revisions",
+          "columnsFrom": [
+            "revision_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.documents": {
+      "name": "documents",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "documents_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_id": {
+          "name": "contract_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "doc_number": {
+          "name": "doc_number",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "title": {
+          "name": "title",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'ACTIVE'"
+        },
+        "issued_date": {
+          "name": "issued_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_contract_doc_status": {
+          "name": "unique_contract_doc_status",
+          "columns": [
+            {
+              "expression": "contract_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "doc_number",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "status",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "documents_contract_id_contracts_id_fk": {
+          "name": "documents_contract_id_contracts_id_fk",
+          "tableFrom": "documents",
+          "tableTo": "contracts",
+          "columnsFrom": [
+            "contract_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.issue_stages": {
+      "name": "issue_stages",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "issue_stages_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "document_id": {
+          "name": "document_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "stage_name": {
+          "name": "stage_name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "plan_date": {
+          "name": "plan_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "actual_date": {
+          "name": "actual_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_document_stage": {
+          "name": "unique_document_stage",
+          "columns": [
+            {
+              "expression": "document_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "stage_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "issue_stages_document_id_documents_id_fk": {
+          "name": "issue_stages_document_id_documents_id_fk",
+          "tableFrom": "issue_stages",
+          "tableTo": "documents",
+          "columnsFrom": [
+            "document_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.revisions": {
+      "name": "revisions",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "revisions_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "issue_stage_id": {
+          "name": "issue_stage_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "revision": {
+          "name": "revision",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "uploader_type": {
+          "name": "uploader_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'vendor'"
+        },
+        "uploader_id": {
+          "name": "uploader_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "uploader_name": {
+          "name": "uploader_name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "comment": {
+          "name": "comment",
+          "type": "varchar(500)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "approved_date": {
+          "name": "approved_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_stage_rev": {
+          "name": "unique_stage_rev",
+          "columns": [
+            {
+              "expression": "issue_stage_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "revision",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_attachments": {
+      "name": "vendor_attachments",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "file_name": {
+          "name": "file_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "file_path": {
+          "name": "file_path",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "attachment_type": {
+          "name": "attachment_type",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'GENERAL'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_attachments_vendor_id_vendors_id_fk": {
+          "name": "vendor_attachments_vendor_id_vendors_id_fk",
+          "tableFrom": "vendor_attachments",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_contacts": {
+      "name": "vendor_contacts",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contact_name": {
+          "name": "contact_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contact_position": {
+          "name": "contact_position",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "contact_email": {
+          "name": "contact_email",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contact_phone": {
+          "name": "contact_phone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_primary": {
+          "name": "is_primary",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_contacts_vendor_id_vendors_id_fk": {
+          "name": "vendor_contacts_vendor_id_vendors_id_fk",
+          "tableFrom": "vendor_contacts",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendor_possible_items": {
+      "name": "vendor_possible_items",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "item_code": {
+          "name": "item_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {
+        "vendor_possible_items_vendor_id_vendors_id_fk": {
+          "name": "vendor_possible_items_vendor_id_vendors_id_fk",
+          "tableFrom": "vendor_possible_items",
+          "tableTo": "vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "no action",
+          "onUpdate": "no action"
+        },
+        "vendor_possible_items_item_code_items_item_code_fk": {
+          "name": "vendor_possible_items_item_code_items_item_code_fk",
+          "tableFrom": "vendor_possible_items",
+          "tableTo": "items",
+          "columnsFrom": [
+            "item_code"
+          ],
+          "columnsTo": [
+            "item_code"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.vendors": {
+      "name": "vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_name": {
+          "name": "vendor_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_code": {
+          "name": "vendor_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tax_id": {
+          "name": "tax_id",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "address": {
+          "name": "address",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "country": {
+          "name": "country",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "phone": {
+          "name": "phone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "email": {
+          "name": "email",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website": {
+          "name": "website",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'PENDING_REVIEW'"
+        },
+        "representative_name": {
+          "name": "representative_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "representative_birth": {
+          "name": "representative_birth",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "representative_email": {
+          "name": "representative_email",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "representative_phone": {
+          "name": "representative_phone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "corporate_registration_number": {
+          "name": "corporate_registration_number",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "credit_agency": {
+          "name": "credit_agency",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "credit_rating": {
+          "name": "credit_rating",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cash_flow_rating": {
+          "name": "cash_flow_rating",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.user_domain": {
+      "name": "user_domain",
+      "schema": "public",
+      "values": [
+        "evcp",
+        "partners"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {
+    "public.contracts_detail_view": {
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": true,
+          "notNull": true,
+          "identity": {
+            "type": "always",
+            "name": "contracts_detail_view_id_seq",
+            "schema": "public",
+            "increment": "1",
+            "startWith": "1",
+            "minValue": "1",
+            "maxValue": "2147483647",
+            "cache": "1",
+            "cycle": false
+          }
+        },
+        "contract_no": {
+          "name": "contract_no",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "contract_name": {
+          "name": "contract_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'ACTIVE'"
+        },
+        "start_date": {
+          "name": "start_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "end_date": {
+          "name": "end_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "project_id": {
+          "name": "project_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "code": {
+          "name": "code",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "vendor_name": {
+          "name": "vendor_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "payment_terms": {
+          "name": "payment_terms",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_terms": {
+          "name": "delivery_terms",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_date": {
+          "name": "delivery_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "delivery_location": {
+          "name": "delivery_location",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "currency": {
+          "name": "currency",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'KRW'"
+        },
+        "total_amount": {
+          "name": "total_amount",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "discount": {
+          "name": "discount",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tax": {
+          "name": "tax",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "shipping_fee": {
+          "name": "shipping_fee",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "net_total": {
+          "name": "net_total",
+          "type": "numeric(12, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "partial_shipping_allowed": {
+          "name": "partial_shipping_allowed",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "partial_payment_allowed": {
+          "name": "partial_payment_allowed",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "remarks": {
+          "name": "remarks",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "version": {
+          "name": "version",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "definition": "select \"contracts\".\"id\", \"contracts\".\"contract_no\", \"contracts\".\"contract_name\", \"contracts\".\"status\", \"contracts\".\"start_date\", \"contracts\".\"end_date\", \"contracts\".\"project_id\", \"projects\".\"code\", \"projects\".\"name\", \"contracts\".\"vendor_id\", \"vendors\".\"vendor_name\", \"contracts\".\"payment_terms\", \"contracts\".\"delivery_terms\", \"contracts\".\"delivery_date\", \"contracts\".\"delivery_location\", \"contracts\".\"currency\", \"contracts\".\"total_amount\", \"contracts\".\"discount\", \"contracts\".\"tax\", \"contracts\".\"shipping_fee\", \"contracts\".\"net_total\", \"contracts\".\"partial_shipping_allowed\", \"contracts\".\"partial_payment_allowed\", \"contracts\".\"remarks\", \"contracts\".\"version\", \"contracts\".\"created_at\", \"contracts\".\"updated_at\", EXISTS (\n                SELECT 1 \n                FROM \"contract_envelopes\" \n                WHERE \"contract_envelopes\".\"contract_id\" = \"contracts\".\"id\"\n            ) as \"has_signature\", COALESCE((\n        SELECT json_agg(\n          json_build_object(\n            'id', ce.id,\n            'envelopeId', ce.envelope_id,\n            'documentId', ce.document_id,\n            'envelopeStatus', ce.envelope_status,\n            'fileName', ce.file_name,\n            'filePath', ce.file_path,\n            'createdAt', ce.created_at,\n            'updatedAt', ce.updated_at,\n            'signers', (\n              SELECT json_agg(\n                json_build_object(\n                  'id', cs.id,\n                  'vendorContactId', cs.vendor_contact_id,\n                  'signerType', cs.signer_type,\n                  'signerEmail', cs.signer_email,\n                  'signerName', cs.signer_name,\n                  'signerPosition', cs.signer_position,\n                  'signerStatus', cs.signer_status,\n                  'signedAt', cs.signed_at\n                )\n              )\n              FROM \"contract_signers\" AS cs\n              WHERE cs.envelope_id = ce.id\n            )\n          )\n        )\n        FROM \"contract_envelopes\" AS ce\n        WHERE ce.contract_id = \"contracts\".\"id\"\n    ), '[]') as \"envelopes\" from \"contracts\" left join \"projects\" on \"contracts\".\"project_id\" = \"projects\".\"id\" left join \"vendors\" on \"contracts\".\"vendor_id\" = \"vendors\".\"id\"",
+      "name": "contracts_detail_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.cbe_view": {
+      "columns": {},
+      "definition": "select \"cbe_evaluations\".\"id\" as \"cbe_id\", \"cbe_evaluations\".\"rfq_id\" as \"rfq_id\", \"cbe_evaluations\".\"vendor_id\" as \"vendor_id\", \"cbe_evaluations\".\"total_cost\" as \"total_cost\", \"cbe_evaluations\".\"currency\" as \"currency\", \"cbe_evaluations\".\"payment_terms\" as \"payment_terms\", \"cbe_evaluations\".\"incoterms\" as \"incoterms\", \"cbe_evaluations\".\"result\" as \"result\", \"cbe_evaluations\".\"notes\" as \"notes\", \"cbe_evaluations\".\"evaluated_by\" as \"evaluated_by\", \"cbe_evaluations\".\"evaluated_at\" as \"evaluated_at\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"description\" as \"rfq_description\", \"vendors\".\"vendor_name\" as \"vendor_name\", \"vendors\".\"vendor_code\" as \"vendor_code\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\", \"users\".\"name\" as \"evaluator_name\", \"users\".\"email\" as \"evaluator_email\" from \"cbe_evaluations\" inner join \"rfqs\" on \"cbe_evaluations\".\"rfq_id\" = \"rfqs\".\"id\" inner join \"vendors\" on \"cbe_evaluations\".\"vendor_id\" = \"vendors\".\"id\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\" left join \"users\" on \"cbe_evaluations\".\"evaluated_by\" = \"users\".\"id\"",
+      "name": "cbe_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.rfqs_view": {
+      "columns": {},
+      "definition": "select \"rfqs\".\"id\" as \"rfq_id\", \"rfqs\".\"status\" as \"status\", \"rfqs\".\"created_at\" as \"created_at\", \"rfqs\".\"updated_at\" as \"updated_at\", \"rfqs\".\"created_by\" as \"created_by\", \"rfqs\".\"rfq_type\" as \"rfq_type\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"description\" as \"description\", \"rfqs\".\"due_date\" as \"due_date\", \"rfqs\".\"parent_rfq_id\" as \"parent_rfq_id\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\", \"users\".\"email\" as \"user_email\", \"users\".\"name\" as \"user_name\", (\n          SELECT COUNT(*) \n          FROM \"rfq_items\" \n          WHERE \"rfq_items\".\"rfq_id\" = \"rfqs\".\"id\"\n        ) as \"item_count\", (\n          SELECT COUNT(*) \n          FROM \"rfq_attachments\" \n          WHERE \"rfq_attachments\".\"rfq_id\" = \"rfqs\".\"id\"\n        ) as \"attachment_count\" from \"rfqs\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\" left join \"users\" on \"rfqs\".\"created_by\" = \"users\".\"id\"",
+      "name": "rfqs_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_cbe_view": {
+      "columns": {},
+      "definition": "select \"vendors\".\"id\" as \"vendor_id\", \"vendors\".\"vendor_name\" as \"vendor_name\", \"vendors\".\"vendor_code\" as \"vendor_code\", \"vendors\".\"address\" as \"address\", \"vendors\".\"country\" as \"country\", \"vendors\".\"email\" as \"email\", \"vendors\".\"website\" as \"website\", \"vendors\".\"status\" as \"vendor_status\", \"vendor_responses\".\"id\" as \"vendor_response_id\", \"vendor_responses\".\"rfq_id\" as \"rfq_id\", \"vendor_responses\".\"response_status\" as \"rfq_vendor_status\", \"vendor_responses\".\"updated_at\" as \"rfq_vendor_updated\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"rfq_type\" as \"rfq_type\", \"rfqs\".\"description\" as \"description\", \"rfqs\".\"due_date\" as \"due_date\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\", \"cbe_evaluations\".\"id\" as \"cbe_id\", \"cbe_evaluations\".\"result\" as \"cbe_result\", \"cbe_evaluations\".\"notes\" as \"cbe_note\", \"cbe_evaluations\".\"updated_at\" as \"cbe_updated\", \"cbe_evaluations\".\"total_cost\" as \"total_cost\", \"cbe_evaluations\".\"currency\" as \"currency\", \"cbe_evaluations\".\"payment_terms\" as \"payment_terms\", \"cbe_evaluations\".\"incoterms\" as \"incoterms\", \"cbe_evaluations\".\"delivery_schedule\" as \"delivery_schedule\" from \"vendors\" left join \"vendor_responses\" on \"vendor_responses\".\"vendor_id\" = \"vendors\".\"id\" left join \"rfqs\" on \"vendor_responses\".\"rfq_id\" = \"rfqs\".\"id\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\" left join \"cbe_evaluations\" on (\"cbe_evaluations\".\"vendor_id\" = \"vendors\".\"id\" and \"cbe_evaluations\".\"rfq_id\" = \"vendor_responses\".\"rfq_id\")",
+      "name": "vendor_cbe_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_responses_view": {
+      "columns": {},
+      "definition": "select \"vendor_responses\".\"id\" as \"response_id\", \"vendor_responses\".\"rfq_id\" as \"rfq_id\", \"vendor_responses\".\"vendor_id\" as \"vendor_id\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"description\" as \"rfq_description\", \"rfqs\".\"due_date\" as \"rfq_due_date\", \"rfqs\".\"status\" as \"rfq_status\", \"rfqs\".\"rfq_type\" as \"rfq_type\", \"rfqs\".\"created_at\" as \"rfq_created_at\", \"rfqs\".\"updated_at\" as \"rfq_updated_at\", \"rfqs\".\"created_by\" as \"rfq_created_by\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\", \"vendors\".\"vendor_name\" as \"vendor_name\", \"vendors\".\"vendor_code\" as \"vendor_code\", \"vendor_responses\".\"response_status\" as \"response_status\", \"vendor_responses\".\"responded_at\" as \"responded_at\", CASE WHEN \"vendor_technical_responses\".\"id\" IS NOT NULL THEN TRUE ELSE FALSE END as \"has_technical_response\", \"vendor_technical_responses\".\"id\" as \"technical_response_id\", CASE WHEN \"vendor_commercial_responses\".\"id\" IS NOT NULL THEN TRUE ELSE FALSE END as \"has_commercial_response\", \"vendor_commercial_responses\".\"id\" as \"commercial_response_id\", \"vendor_commercial_responses\".\"total_price\" as \"total_price\", \"vendor_commercial_responses\".\"currency\" as \"currency\", \"rfq_evaluations\".\"id\" as \"tbe_id\", \"rfq_evaluations\".\"result\" as \"tbe_result\", \"cbe_evaluations\".\"id\" as \"cbe_id\", \"cbe_evaluations\".\"result\" as \"cbe_result\", (\n          SELECT COUNT(*) \n          FROM \"vendor_response_attachments\" \n          WHERE \"vendor_response_attachments\".\"response_id\" = \"vendor_responses\".\"id\"\n        ) as \"attachment_count\" from \"vendor_responses\" inner join \"rfqs\" on \"vendor_responses\".\"rfq_id\" = \"rfqs\".\"id\" inner join \"vendors\" on \"vendor_responses\".\"vendor_id\" = \"vendors\".\"id\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\" left join \"vendor_technical_responses\" on \"vendor_technical_responses\".\"response_id\" = \"vendor_responses\".\"id\" left join \"vendor_commercial_responses\" on \"vendor_commercial_responses\".\"response_id\" = \"vendor_responses\".\"id\" left join \"rfq_evaluations\" on (\"rfq_evaluations\".\"rfq_id\" = \"vendor_responses\".\"rfq_id\" and \"rfq_evaluations\".\"vendor_id\" = \"vendor_responses\".\"vendor_id\" and \"rfq_evaluations\".\"eval_type\" = 'TBE') left join \"cbe_evaluations\" on (\"cbe_evaluations\".\"rfq_id\" = \"vendor_responses\".\"rfq_id\" and \"cbe_evaluations\".\"vendor_id\" = \"vendor_responses\".\"vendor_id\")",
+      "name": "vendor_responses_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_rfq_view": {
+      "columns": {},
+      "definition": "select \"vendors\".\"id\" as \"vendor_id\", \"vendors\".\"vendor_name\" as \"vendor_name\", \"vendors\".\"vendor_code\" as \"vendor_code\", \"vendors\".\"address\" as \"address\", \"vendors\".\"country\" as \"country\", \"vendors\".\"email\" as \"email\", \"vendors\".\"website\" as \"website\", \"vendors\".\"status\" as \"vendor_status\", \"vendor_responses\".\"rfq_id\" as \"rfq_id\", \"vendor_responses\".\"response_status\" as \"rfq_vendor_status\", \"vendor_responses\".\"updated_at\" as \"rfq_vendor_updated\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"description\" as \"description\", \"rfqs\".\"due_date\" as \"due_date\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\" from \"vendors\" left join \"vendor_responses\" on \"vendor_responses\".\"vendor_id\" = \"vendors\".\"id\" left join \"rfqs\" on \"vendor_responses\".\"rfq_id\" = \"rfqs\".\"id\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\"",
+      "name": "vendor_rfq_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_tbe_view": {
+      "columns": {},
+      "definition": "select \"vendors\".\"id\" as \"vendor_id\", \"vendors\".\"vendor_name\" as \"vendor_name\", \"vendors\".\"vendor_code\" as \"vendor_code\", \"vendors\".\"address\" as \"address\", \"vendors\".\"country\" as \"country\", \"vendors\".\"email\" as \"email\", \"vendors\".\"website\" as \"website\", \"vendors\".\"status\" as \"vendor_status\", \"vendor_responses\".\"id\" as \"vendor_response_id\", \"vendor_responses\".\"rfq_id\" as \"rfq_id\", \"vendor_responses\".\"response_status\" as \"rfq_vendor_status\", \"vendor_responses\".\"updated_at\" as \"rfq_vendor_updated\", \"rfqs\".\"rfq_code\" as \"rfq_code\", \"rfqs\".\"rfq_type\" as \"rfq_type\", \"rfqs\".\"description\" as \"description\", \"rfqs\".\"due_date\" as \"due_date\", \"projects\".\"id\" as \"project_id\", \"projects\".\"code\" as \"project_code\", \"projects\".\"name\" as \"project_name\", \"rfq_evaluations\".\"id\" as \"tbe_id\", \"rfq_evaluations\".\"result\" as \"tbe_result\", \"rfq_evaluations\".\"notes\" as \"tbe_note\", \"rfq_evaluations\".\"updated_at\" as \"tbe_updated\" from \"vendors\" left join \"vendor_responses\" on \"vendor_responses\".\"vendor_id\" = \"vendors\".\"id\" left join \"rfqs\" on \"vendor_responses\".\"rfq_id\" = \"rfqs\".\"id\" left join \"projects\" on \"rfqs\".\"project_id\" = \"projects\".\"id\" left join \"rfq_evaluations\" on (\"rfq_evaluations\".\"vendor_id\" = \"vendors\".\"id\" and \"rfq_evaluations\".\"eval_type\" = 'TBE' and \"rfq_evaluations\".\"rfq_id\" = \"vendor_responses\".\"rfq_id\")",
+      "name": "vendor_tbe_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.role_view": {
+      "columns": {},
+      "definition": "select \"roles\".\"id\" as \"id\", \"roles\".\"name\" as \"name\", \"roles\".\"description\" as \"description\", \"roles\".\"domain\" as \"domain\", \"roles\".\"created_at\" as \"created_at\", \"vendors\".\"id\" as \"company_id\", \"vendors\".\"vendor_name\" as \"company_name\", COUNT(\"users\".\"id\") as \"user_count\" from \"roles\" left join \"user_roles\" on \"user_roles\".\"role_id\" = \"roles\".\"id\" left join \"users\" on \"users\".\"id\" = \"user_roles\".\"user_id\" left join \"vendors\" on \"roles\".\"company_id\" = \"vendors\".\"id\" group by \"roles\".\"id\", \"vendors\".\"id\"",
+      "name": "role_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.user_view": {
+      "columns": {},
+      "definition": "select \"users\".\"id\" as \"user_id\", \"users\".\"name\" as \"user_name\", \"users\".\"email\" as \"user_email\", \"users\".\"domain\" as \"user_domain\", \"users\".\"image_url\" as \"user_image\", \"vendors\".\"id\" as \"company_id\", \"vendors\".\"vendor_name\" as \"company_name\", \n      array_agg(\"roles\".\"name\")\n     as \"roles\", \"users\".\"created_at\" as \"created_at\" from \"users\" left join \"vendors\" on \"users\".\"company_id\" = \"vendors\".\"id\" left join \"user_roles\" on \"users\".\"id\" = \"user_roles\".\"user_id\" left join \"roles\" on \"user_roles\".\"role_id\" = \"roles\".\"id\" group by \"users\".\"id\", \"vendors\".\"id\"",
+      "name": "user_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.document_stages_view": {
+      "columns": {
+        "document_id": {
+          "name": "document_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "doc_number": {
+          "name": "doc_number",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "title": {
+          "name": "title",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "issued_date": {
+          "name": "issued_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "contract_id": {
+          "name": "contract_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "stage_count": {
+          "name": "stage_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "stage_list": {
+          "name": "stage_list",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true
+        }
+      },
+      "definition": "\n  SELECT\n    d.id AS document_id,\n    d.doc_number,\n    d.title,\n    d.status,\n    d.issued_date,\n    d.contract_id,\n\n    (\n      SELECT COUNT(*)\n      FROM issue_stages\n      WHERE document_id = d.id\n    ) AS stage_count,\n\n    COALESCE( \n      (\n        SELECT json_agg(i.stage_name)\n        FROM issue_stages i\n        WHERE i.document_id = d.id\n      ), \n      '[]'\n    ) AS stage_list,\n\n    d.created_at,\n    d.updated_at\n  FROM documents d\n",
+      "name": "document_stages_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_documents_view": {
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "doc_number": {
+          "name": "doc_number",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "title": {
+          "name": "title",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status": {
+          "name": "status",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "issued_date": {
+          "name": "issued_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "contract_id": {
+          "name": "contract_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "latest_stage_id": {
+          "name": "latest_stage_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_stage_name": {
+          "name": "latest_stage_name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_stage_plan_date": {
+          "name": "latest_stage_plan_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_stage_actual_date": {
+          "name": "latest_stage_actual_date",
+          "type": "date",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_revision_id": {
+          "name": "latest_revision_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_revision": {
+          "name": "latest_revision",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_revision_uploader_type": {
+          "name": "latest_revision_uploader_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latest_revision_uploader_name": {
+          "name": "latest_revision_uploader_name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "attachment_count": {
+          "name": "attachment_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": true
+        }
+      },
+      "definition": "\n    SELECT \n      d.id, \n      d.doc_number,\n      d.title,\n      d.status,\n      d.issued_date,\n  \n      d.contract_id,\n  \n      (\n        SELECT id FROM issue_stages\n        WHERE document_id = d.id\n        ORDER BY created_at DESC LIMIT 1\n      ) AS latest_stage_id,\n      (\n        SELECT stage_name FROM issue_stages\n        WHERE document_id = d.id\n        ORDER BY created_at DESC LIMIT 1\n      ) AS latest_stage_name,\n      (\n        SELECT plan_date FROM issue_stages\n        WHERE document_id = d.id\n        ORDER BY created_at DESC LIMIT 1\n      ) AS latest_stage_plan_date,\n      (\n        SELECT actual_date FROM issue_stages\n        WHERE document_id = d.id\n        ORDER BY created_at DESC LIMIT 1\n      ) AS latest_stage_actual_date,\n  \n      (\n        SELECT r.id FROM revisions r\n        JOIN issue_stages i ON r.issue_stage_id = i.id\n        WHERE i.document_id = d.id\n        ORDER BY r.created_at DESC LIMIT 1\n      ) AS latest_revision_id,\n      (\n        SELECT r.revision FROM revisions r\n        JOIN issue_stages i ON r.issue_stage_id = i.id\n        WHERE i.document_id = d.id\n        ORDER BY r.created_at DESC LIMIT 1\n      ) AS latest_revision,\n      (\n        SELECT r.uploader_type FROM revisions r\n        JOIN issue_stages i ON r.issue_stage_id = i.id\n        WHERE i.document_id = d.id\n        ORDER BY r.created_at DESC LIMIT 1\n      ) AS latest_revision_uploader_type,\n      (\n        SELECT r.uploader_name FROM revisions r\n        JOIN issue_stages i ON r.issue_stage_id = i.id\n        WHERE i.document_id = d.id\n        ORDER BY r.created_at DESC LIMIT 1\n      ) AS latest_revision_uploader_name,\n  \n      (\n        SELECT COUNT(*) FROM document_attachments a\n        JOIN revisions r ON a.revision_id = r.id\n        JOIN issue_stages i ON r.issue_stage_id = i.id\n        WHERE i.document_id = d.id\n      ) AS attachment_count,\n  \n      d.created_at,\n      d.updated_at\n    FROM documents d\n    JOIN contracts c ON d.contract_id = c.id\n  ",
+      "name": "vendor_documents_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    },
+    "public.vendor_items_view": {
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "item_name": {
+          "name": "item_name",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "item_code": {
+          "name": "item_code",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "now()"
+        }
+      },
+      "definition": "select \"vendor_possible_items\".\"id\", \"vendor_possible_items\".\"vendor_id\", \"items\".\"item_name\", \"items\".\"item_code\", \"items\".\"description\", \"vendor_possible_items\".\"created_at\", \"vendor_possible_items\".\"updated_at\" from \"vendor_possible_items\" left join \"items\" on \"vendor_possible_items\".\"item_code\" = \"items\".\"item_code\"",
+      "name": "vendor_items_view",
+      "schema": "public",
+      "isExisting": false,
+      "materialized": false
+    }
+  },
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}
\ No newline at end of file
diff --git a/db/migrations/meta/_journal.json b/db/migrations/meta/_journal.json
index 708f1976..26a15dcf 100644
--- a/db/migrations/meta/_journal.json
+++ b/db/migrations/meta/_journal.json
@@ -722,6 +722,13 @@
       "when": 1742964981809,
       "tag": "0102_melodic_blob",
       "breakpoints": true
+    },
+    {
+      "idx": 103,
+      "version": "7",
+      "when": 1743043253528,
+      "tag": "0103_huge_wallflower",
+      "breakpoints": true
     }
   ]
 }
\ No newline at end of file
diff --git a/db/schema/contract.ts b/db/schema/contract.ts
index 3c29f0d0..10721b4d 100644
--- a/db/schema/contract.ts
+++ b/db/schema/contract.ts
@@ -135,31 +135,31 @@ export const contractEnvelopes = pgTable("contract_envelopes", {
 // 하나의 Envelope에 여러 서명자(사인 요청 대상)가 있을 수 있음
 export const contractSigners = pgTable("contract_signers", {
     id: integer("id").primaryKey().generatedAlwaysAsIdentity(),
-    
+
     // Envelope와 1:N 관계
     envelopeId: integer("envelope_id")
         .notNull()
         .references(() => contractEnvelopes.id, { onDelete: "cascade" }),
-    
+
     // Reference to vendor_contacts table (optional - if signer is from vendor contacts)
     vendorContactId: integer("vendor_contact_id")
         .references(() => vendorContacts.id),
-    
+
     // Is this signer from the requester (company) side or vendor side
-    signerType: varchar("signer_type", { 
+    signerType: varchar("signer_type", {
         length: 20,
         enum: ["REQUESTER", "VENDOR"]
     }).notNull().default("VENDOR"),
-    
+
     // 서명자 정보 (manual entry or populated from vendor contact)
     signerEmail: varchar("signer_email", { length: 255 }).notNull(),
     signerName: varchar("signer_name", { length: 100 }).notNull(),
     signerPosition: varchar("signer_position", { length: 100 }),
-    
+
     // 서명자별 상태 (sent, delivered, signed, declined, etc.)
     signerStatus: varchar("signer_status", { length: 50 }).default("PENDING"),
     signedAt: timestamp("signed_at"),
-    
+
     // 생성/수정 시각
     createdAt: timestamp("created_at").defaultNow().notNull(),
     updatedAt: timestamp("updated_at").defaultNow().notNull(),
@@ -210,13 +210,46 @@ export const contractsDetailView = pgView("contracts_detail_view").as((qb) => {
             // Timestamps
             createdAt: contracts.createdAt,
             updatedAt: contracts.updatedAt,
-            
+
             // Electronic signature status - ADDED .as('has_signature') here
             hasSignature: sql<boolean>`EXISTS (
                 SELECT 1 
                 FROM ${contractEnvelopes} 
                 WHERE ${contractEnvelopes.contractId} = ${contracts.id}
             )`.as('has_signature'),
+            // --- 전자서명 이력 (Envelope) + 서명자(Signer)를 JSON 으로 중첩한 배열 ---
+            envelopes: sql<string>`COALESCE((
+        SELECT json_agg(
+          json_build_object(
+            'id', ce.id,
+            'envelopeId', ce.envelope_id,
+            'documentId', ce.document_id,
+            'envelopeStatus', ce.envelope_status,
+            'fileName', ce.file_name,
+            'filePath', ce.file_path,
+            'createdAt', ce.created_at,
+            'updatedAt', ce.updated_at,
+            'signers', (
+              SELECT json_agg(
+                json_build_object(
+                  'id', cs.id,
+                  'vendorContactId', cs.vendor_contact_id,
+                  'signerType', cs.signer_type,
+                  'signerEmail', cs.signer_email,
+                  'signerName', cs.signer_name,
+                  'signerPosition', cs.signer_position,
+                  'signerStatus', cs.signer_status,
+                  'signedAt', cs.signed_at
+                )
+              )
+              FROM ${contractSigners} AS cs
+              WHERE cs.envelope_id = ce.id
+            )
+          )
+        )
+        FROM ${contractEnvelopes} AS ce
+        WHERE ce.contract_id = ${contracts.id}
+    ), '[]')`.as("envelopes")
         })
         .from(contracts)
         .leftJoin(projects, eq(contracts.projectId, projects.id))
diff --git a/lib/po/table/po-table-columns.tsx b/lib/po/table/po-table-columns.tsx
index c2c01136..a13b2acf 100644
--- a/lib/po/table/po-table-columns.tsx
+++ b/lib/po/table/po-table-columns.tsx
@@ -91,16 +91,77 @@ export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<Contrac
   // 3-1) groupMap: { [groupName]: ColumnDef<ContractDetail>[] }
   const groupMap: Record<string, ColumnDef<ContractDetail>[]> = {};
 
-  poColumnsConfig.forEach((cfg) => {
-    // Use "_noGroup" if no group is specified
-    const groupName = cfg.group || "_noGroup";
+ // (1) JSON config를 읽어서 ColumnDef를 생성하는 부분 (일부 발췌)
+poColumnsConfig.forEach((cfg) => {
+  const groupName = cfg.group || "_noGroup"
+  if (!groupMap[groupName]) {
+    groupMap[groupName] = []
+  }
 
-    if (!groupMap[groupName]) {
-      groupMap[groupName] = [];
-    }
+  let childCol: ColumnDef<ContractDetail>
+
+  if (cfg.type === "custom" && cfg.customType === "esignStatus") {
+    // ========================================
+    // (2) 전자서명 전용 커스텀 컬럼
+    // ========================================
+    childCol = {
+      id: cfg.id,
+      header: ({ column }) => (
+        <DataTableColumnHeaderSimple column={column} title={cfg.label} />
+      ),
+      // 여기서 row.original.envelopes 등 활용하여 최신 전자서명 상태 표시
+      cell: ({ row }) => {
+        const data = row.original
+        if (!data.envelopes || data.envelopes.length === 0) {
+          return (
+            <div className="text-sm text-gray-500">
+              No E-Sign
+            </div>
+          )
+        }
+
+        // envelopes가 여러 개 있으면 최신(가장 최근 updatedAt) 가져오기
+        const sorted = [...data.envelopes].sort((a, b) => {
+          const dateA = new Date(a.updatedAt)
+          const dateB = new Date(b.updatedAt)
+          return dateB.getTime() - dateA.getTime()
+        })
+        const latest = sorted[0]
 
-    // Child column definition
-    const childCol: ColumnDef<ContractDetail> = {
+        // 상태에 따라 다른 UI 색상/아이콘
+        const status = latest.envelopeStatus // "sent", "completed", ...
+        const colorMap: Record<string, string> = {
+          completed: "text-green-600",
+          sent: "text-blue-600",
+          voided: "text-red-600",
+          // ...
+        }
+        const colorClass = colorMap[status] || "text-gray-700"
+
+        return (
+          <Button
+            onClick={() => {
+              // 다이얼로그 열기 등
+              // 예: setRowAction({ row, type: "esign-detail" })
+              setRowAction({ row, type: "esign-detail" })
+            }}
+            className={`underline underline-offset-2 ${colorClass}`}
+          >
+            {status}
+          </Button>
+        )
+      },
+      meta: {
+        excelHeader: cfg.excelHeader,
+        group: cfg.group,
+        type: cfg.type,
+      },
+    }
+  } else {
+    // ========================================
+    // (3) 일반 컬럼 (type: text/date/number 등)
+    // ========================================
+    childCol = {
       accessorKey: cfg.id,
       enableResizing: true,
       header: ({ column }) => (
@@ -112,17 +173,19 @@ export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<Contrac
         type: cfg.type,
       },
       cell: ({ row, cell }) => {
-        if (cfg.id === "createdAt" || cfg.id === "updatedAt") {
-          const dateVal = cell.getValue() as Date;
-          return formatDate(dateVal);
+        // 날짜 포맷, 숫자 포맷 등 처리
+        if (cfg.type === "date") {
+          const dateVal = cell.getValue() as Date
+          return formatDate(dateVal)
         }
-
-        return row.getValue(cfg.id) ?? "";
+        // ...
+        return row.getValue(cfg.id) ?? ""
       },
-    };
+    }
+  }
 
-    groupMap[groupName].push(childCol);
-  });
+  groupMap[groupName].push(childCol)
+})
 
   // ----------------------------------------------------------------
   // 3-2) Create actual parent columns (groups) from the groupMap
diff --git a/lib/rfqs/table/rfqs-table.tsx b/lib/rfqs/table/rfqs-table.tsx
index 7d996816..48c04930 100644
--- a/lib/rfqs/table/rfqs-table.tsx
+++ b/lib/rfqs/table/rfqs-table.tsx
@@ -213,7 +213,7 @@ export function RfqsTable({ promises, rfqType = RfqType.PURCHASE }: RfqsTablePro
   })
 
   return (
-    <div style={{ maxWidth: '80vw' }}>
+    <div style={{ maxWidth: '100vw' }}>
       <DataTable
         table={table}
         floatingBar={<RfqsTableFloatingBar table={table} />}
diff --git a/lib/vendors/table/request-vendor-pg-dialog.tsx b/lib/vendors/table/request-vendor-pg-dialog.tsx
index b417f846..de23ad9b 100644
--- a/lib/vendors/table/request-vendor-pg-dialog.tsx
+++ b/lib/vendors/table/request-vendor-pg-dialog.tsx
@@ -70,7 +70,7 @@ export function RequestPQVendorsDialog({
           <DialogTrigger asChild>
             <Button variant="outline" size="sm" className="gap-2">
               <SendHorizonal className="size-4" aria-hidden="true" />
-              Request ({vendors.length})
+              PQ Request ({vendors.length})
             </Button>
           </DialogTrigger>
         ) : null}
@@ -114,7 +114,7 @@ export function RequestPQVendorsDialog({
         <DrawerTrigger asChild>
           <Button variant="outline" size="sm" className="gap-2">
             <Check className="size-4" aria-hidden="true" />
-            Request ({vendors.length})
+            PQ Request ({vendors.length})
           </Button>
         </DrawerTrigger>
       ) : null}
-- 
cgit v1.2.3

