From e7818a457371849e29519497ebf046f385f05ab6 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 15 Sep 2025 01:23:00 +0000
Subject: (김준회) AVL 기능 구현 1차 및 벤더풀 E/B 구분 개선
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/avl/table/standard-avl-table.tsx | 380 +++++++++++++++++++++++++++++++++++
 1 file changed, 380 insertions(+)
 create mode 100644 lib/avl/table/standard-avl-table.tsx

(limited to 'lib/avl/table/standard-avl-table.tsx')

diff --git a/lib/avl/table/standard-avl-table.tsx b/lib/avl/table/standard-avl-table.tsx
new file mode 100644
index 00000000..924b972a
--- /dev/null
+++ b/lib/avl/table/standard-avl-table.tsx
@@ -0,0 +1,380 @@
+"use client"
+
+import * as React from "react"
+import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, type ColumnDef } from "@tanstack/react-table"
+import { DataTable } from "@/components/data-table/data-table"
+import { Button } from "@/components/ui/button"
+import { Checkbox } from "@/components/ui/checkbox"
+import { getStandardAvlVendorInfo } from "../service"
+import { GetStandardAvlSchema } from "../validations"
+import { AvlDetailItem } from "../types"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import { Search } from "lucide-react"
+import { toast } from "sonner"
+
+// 검색 옵션들
+const constructionSectorOptions = [
+  { value: "all", label: "전체" },
+  { value: "조선", label: "조선" },
+  { value: "해양", label: "해양" },
+]
+
+const shipTypeOptions = [
+  { value: "all", label: "전체" },
+  { value: "컨테이너선", label: "컨테이너선" },
+  { value: "유조선", label: "유조선" },
+  { value: "LNG선", label: "LNG선" },
+  { value: "LPG선", label: "LPG선" },
+  { value: "벌크선", label: "벌크선" },
+  { value: "여객선", label: "여객선" },
+]
+
+const avlKindOptions = [
+  { value: "all", label: "전체" },
+  { value: "표준", label: "표준" },
+  { value: "특별", label: "특별" },
+  { value: "임시", label: "임시" },
+]
+
+const htDivisionOptions = [
+  { value: "all", label: "전체" },
+  { value: "H", label: "Hull (H)" },
+  { value: "T", label: "Topside (T)" },
+]
+
+// 선종별 표준 AVL 테이블에서는 AvlDetailItem을 사용
+export type StandardAvlItem = AvlDetailItem
+
+interface StandardAvlTableProps {
+  onSelectionChange?: (count: number) => void
+  resetCounter?: number
+  constructionSector?: string // 공사부문 필터
+  shipType?: string // 선종 필터
+  avlKind?: string // AVL 종류 필터
+  htDivision?: string // H/T 구분 필터
+}
+
+// 선종별 표준 AVL 테이블 컬럼
+const standardAvlColumns: ColumnDef<StandardAvlItem>[] = [
+  {
+    id: "select",
+    header: ({ table }) => (
+      <Checkbox
+        checked={
+          table.getIsAllPageRowsSelected() ||
+          (table.getIsSomePageRowsSelected() && "indeterminate")
+        }
+        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+        aria-label="Select all"
+      />
+    ),
+    cell: ({ row, table }) => {
+      // 선종별 표준 AVL 테이블의 단일 선택 핸들러
+      const handleRowSelection = (checked: boolean) => {
+        if (checked) {
+          // 다른 모든 행의 선택 해제
+          table.getRowModel().rows.forEach(r => {
+            if (r !== row && r.getIsSelected()) {
+              r.toggleSelected(false)
+            }
+          })
+        }
+        // 현재 행 선택/해제
+        row.toggleSelected(checked)
+      }
+
+      return (
+        <Checkbox
+          checked={row.getIsSelected()}
+          onCheckedChange={handleRowSelection}
+          aria-label="Select row"
+        />
+      )
+    },
+    enableSorting: false,
+    enableHiding: false,
+    size: 50,
+  },
+  {
+    accessorKey: "no",
+    header: "No.",
+    size: 60,
+  },
+  {
+    accessorKey: "disciplineName",
+    header: "설계공종",
+    size: 120,
+  },
+  {
+    accessorKey: "avlVendorName",
+    header: "AVL 등재업체명",
+    size: 140,
+  },
+  {
+    accessorKey: "materialGroupCode",
+    header: "자재그룹 코드",
+    size: 120,
+  },
+  {
+    accessorKey: "materialGroupName",
+    header: "자재그룹 명",
+    size: 130,
+  },
+  {
+    accessorKey: "vendorCode",
+    header: "협력업체 코드",
+    size: 120,
+  },
+  {
+    accessorKey: "vendorName",
+    header: "협력업체 명",
+    size: 130,
+  },
+  {
+    accessorKey: "headquarterLocation",
+    header: "본사 위치 (국가)",
+    size: 140,
+  },
+  {
+    accessorKey: "tier",
+    header: "등급 (Tier)",
+    size: 120,
+  },
+]
+
+export function StandardAvlTable({
+  onSelectionChange,
+  resetCounter,
+  constructionSector: initialConstructionSector,
+  shipType: initialShipType,
+  avlKind: initialAvlKind,
+  htDivision: initialHtDivision
+}: StandardAvlTableProps) {
+  const [data, setData] = React.useState<StandardAvlItem[]>([])
+  const [loading, setLoading] = React.useState(false)
+  const [pageCount, setPageCount] = React.useState(0)
+
+  // 검색 상태
+  const [searchConstructionSector, setSearchConstructionSector] = React.useState(initialConstructionSector || "all")
+  const [searchShipType, setSearchShipType] = React.useState(initialShipType || "all")
+  const [searchAvlKind, setSearchAvlKind] = React.useState(initialAvlKind || "all")
+  const [searchHtDivision, setSearchHtDivision] = React.useState(initialHtDivision || "all")
+
+  // 데이터 로드 함수
+  const loadData = React.useCallback(async (searchParams: Partial<GetStandardAvlSchema>) => {
+    try {
+      setLoading(true)
+      const params: GetStandardAvlSchema = {
+        page: searchParams.page ?? 1,
+        perPage: searchParams.perPage ?? 10,
+        sort: searchParams.sort ?? [{ id: "no", desc: false }],
+        constructionSector: searchConstructionSector === "all" ? "" : searchConstructionSector || "",
+        shipType: searchShipType === "all" ? "" : searchShipType || "",
+        avlKind: searchAvlKind === "all" ? "" : searchAvlKind || "",
+        htDivision: searchHtDivision === "all" ? "" : searchHtDivision || "",
+        search: "",
+        ...searchParams,
+      }
+      const result = await getStandardAvlVendorInfo(params)
+      setData(result.data)
+      setPageCount(result.pageCount)
+    } catch (error) {
+      console.error("선종별 표준 AVL 데이터 로드 실패:", error)
+      setData([])
+      setPageCount(0)
+    } finally {
+      setLoading(false)
+    }
+  }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
+
+  // 검색 핸들러
+  const handleSearch = React.useCallback(() => {
+    loadData({})
+  }, [loadData])
+
+  // 검색 초기화 핸들러
+  const handleResetSearch = React.useCallback(() => {
+    setSearchConstructionSector("all")
+    setSearchShipType("all")
+    setSearchAvlKind("all")
+    setSearchHtDivision("all")
+    loadData({})
+  }, [loadData])
+
+  // 초기 데이터 로드
+  React.useEffect(() => {
+    loadData({})
+  }, [loadData])
+
+  const table = useReactTable({
+    data,
+    columns: standardAvlColumns,
+    getCoreRowModel: getCoreRowModel(),
+    getPaginationRowModel: getPaginationRowModel(),
+    getSortedRowModel: getSortedRowModel(),
+    getFilteredRowModel: getFilteredRowModel(),
+    manualPagination: true,
+    pageCount,
+    initialState: {
+      pagination: {
+        pageSize: 10,
+      },
+    },
+    onPaginationChange: (updater) => {
+      const newState = typeof updater === 'function' ? updater(table.getState().pagination) : updater
+      loadData({
+        page: newState.pageIndex + 1,
+        perPage: newState.pageSize,
+      })
+    },
+  })
+
+  // 선택 상태 변경 시 콜백 호출
+  React.useEffect(() => {
+    onSelectionChange?.(table.getFilteredSelectedRowModel().rows.length)
+  }, [table.getFilteredSelectedRowModel().rows.length, onSelectionChange])
+
+  // 선택 해제 요청이 오면 모든 선택 해제
+  React.useEffect(() => {
+    if (resetCounter && resetCounter > 0) {
+      table.toggleAllPageRowsSelected(false)
+    }
+  }, [resetCounter, table])
+
+  return (
+    <div className="h-full flex flex-col">
+      <div className="mb-2">
+        <div className="flex items-center justify-between mb-2">
+          <h4 className="font-medium">선종별 표준 AVL</h4>
+          <div className="flex gap-1">
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              신규업체 추가
+            </Button>
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              파일 업로드
+            </Button>
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              일괄입력
+            </Button>
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              항목삭제
+            </Button>
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              저장
+            </Button>
+            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+              최종 확정
+            </Button>
+          </div>
+        </div>
+      </div>
+
+      {/* 검색 UI */}
+      <div className="mb-4 p-4 border rounded-lg bg-muted/50">
+        <div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-4">
+          {/* 공사부문 */}
+          <div className="space-y-2">
+            <label className="text-sm font-medium">공사부문</label>
+            <Select value={searchConstructionSector} onValueChange={setSearchConstructionSector}>
+              <SelectTrigger>
+                <SelectValue />
+              </SelectTrigger>
+              <SelectContent>
+                {constructionSectorOptions.map((option) => (
+                  <SelectItem key={option.value} value={option.value}>
+                    {option.label}
+                  </SelectItem>
+                ))}
+              </SelectContent>
+            </Select>
+          </div>
+
+          {/* 선종 */}
+          <div className="space-y-2">
+            <label className="text-sm font-medium">선종</label>
+            <Select value={searchShipType} onValueChange={setSearchShipType}>
+              <SelectTrigger>
+                <SelectValue />
+              </SelectTrigger>
+              <SelectContent>
+                {shipTypeOptions.map((option) => (
+                  <SelectItem key={option.value} value={option.value}>
+                    {option.label}
+                  </SelectItem>
+                ))}
+              </SelectContent>
+            </Select>
+          </div>
+
+          {/* AVL종류 */}
+          <div className="space-y-2">
+            <label className="text-sm font-medium">AVL종류</label>
+            <Select value={searchAvlKind} onValueChange={setSearchAvlKind}>
+              <SelectTrigger>
+                <SelectValue />
+              </SelectTrigger>
+              <SelectContent>
+                {avlKindOptions.map((option) => (
+                  <SelectItem key={option.value} value={option.value}>
+                    {option.label}
+                  </SelectItem>
+                ))}
+              </SelectContent>
+            </Select>
+          </div>
+
+          {/* H/T */}
+          <div className="space-y-2">
+            <label className="text-sm font-medium">H/T 구분</label>
+            <Select value={searchHtDivision} onValueChange={setSearchHtDivision}>
+              <SelectTrigger>
+                <SelectValue />
+              </SelectTrigger>
+              <SelectContent>
+                {htDivisionOptions.map((option) => (
+                  <SelectItem key={option.value} value={option.value}>
+                    {option.label}
+                  </SelectItem>
+                ))}
+              </SelectContent>
+            </Select>
+          </div>
+
+          {/* 검색 버튼들 */}
+          <div className="space-y-2">
+            <label className="text-sm font-medium opacity-0">버튼</label>
+            <div className="flex gap-1">
+              <Button
+                onClick={handleSearch}
+                disabled={loading}
+                size="sm"
+                className="px-3"
+              >
+                <Search className="w-4 h-4 mr-1" />
+                조회
+              </Button>
+              <Button
+                onClick={handleResetSearch}
+                variant="outline"
+                size="sm"
+                className="px-3"
+              >
+                초기화
+              </Button>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div className="flex-1">
+        <DataTable table={table} />
+      </div>
+    </div>
+  )
+}
-- 
cgit v1.2.3


From 2b490956c9752c1b756780a3461bc1c37b6fe0a7 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Mon, 15 Sep 2025 18:58:07 +0900
Subject: (김준회) AVL 관리 및 상세 - 기능 구현 1차 + docker compose 내 오류
 수정
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 _docker/docker-compose.yml                         |    2 +-
 db/schema/avl/avl.ts                               |   17 +-
 lib/avl/components/avl-history-modal.tsx           |  297 +++++
 lib/avl/components/project-field-components.tsx    |  113 ++
 lib/avl/components/project-field-utils.ts          |   45 +
 lib/avl/service.ts                                 | 1244 ++++++++++++++++++--
 lib/avl/snapshot-utils.ts                          |  190 +++
 lib/avl/table/avl-detail-table.tsx                 |  455 +------
 lib/avl/table/avl-registration-area.tsx            |  316 ++++-
 lib/avl/table/avl-table-columns.tsx                |   30 +-
 lib/avl/table/avl-table.tsx                        |  100 +-
 lib/avl/table/avl-vendor-add-and-modify-dialog.tsx |  945 +++++++++++++++
 lib/avl/table/columns-detail.tsx                   |  516 +-------
 lib/avl/table/project-avl-table-columns.tsx        |  167 +++
 lib/avl/table/project-avl-table.tsx                |  720 +++++------
 lib/avl/table/standard-avl-add-dialog.tsx          |  960 +++++++++++++++
 lib/avl/table/standard-avl-table-columns.tsx       |   91 ++
 lib/avl/table/standard-avl-table.tsx               |  603 +++++++---
 lib/avl/table/vendor-pool-table-columns.tsx        |   96 ++
 lib/avl/table/vendor-pool-table.tsx                |  241 ++--
 lib/avl/types.ts                                   |   16 +-
 lib/avl/validations.ts                             |    4 +-
 22 files changed, 5481 insertions(+), 1687 deletions(-)
 create mode 100644 lib/avl/components/avl-history-modal.tsx
 create mode 100644 lib/avl/components/project-field-components.tsx
 create mode 100644 lib/avl/components/project-field-utils.ts
 create mode 100644 lib/avl/snapshot-utils.ts
 create mode 100644 lib/avl/table/avl-vendor-add-and-modify-dialog.tsx
 create mode 100644 lib/avl/table/project-avl-table-columns.tsx
 create mode 100644 lib/avl/table/standard-avl-add-dialog.tsx
 create mode 100644 lib/avl/table/standard-avl-table-columns.tsx
 create mode 100644 lib/avl/table/vendor-pool-table-columns.tsx

(limited to 'lib/avl/table/standard-avl-table.tsx')

diff --git a/_docker/docker-compose.yml b/_docker/docker-compose.yml
index 62b6bae5..bf5027ff 100644
--- a/_docker/docker-compose.yml
+++ b/_docker/docker-compose.yml
@@ -10,7 +10,7 @@ services:
     ports:
       - "5432:5432" # host:container, container는 항상 5432, host 측은 원하는 포트로 설정
     volumes:
-      - postgres_data:/var/lib/postgresql/data
+      - evcp_postgres_data:/var/lib/postgresql/data
     restart: always
 
 volumes:
diff --git a/db/schema/avl/avl.ts b/db/schema/avl/avl.ts
index addbba94..d2aac795 100644
--- a/db/schema/avl/avl.ts
+++ b/db/schema/avl/avl.ts
@@ -1,4 +1,4 @@
-import { pgTable, text, boolean, integer, timestamp, varchar, decimal } from "drizzle-orm/pg-core";
+import { pgTable, boolean, integer, timestamp, varchar, decimal, json } from "drizzle-orm/pg-core";
 import { createInsertSchema, createSelectSchema } from "drizzle-zod";
 
 // AVL 리스트 테이블 (프로젝트 AVL 및 선종별 표준 AVL 리스트)
@@ -17,6 +17,9 @@ export const avlList = pgTable("avl_list", {
   htDivision: varchar("ht_division", { length: 10 }), // H=Hull, T=Top, 공통
   rev: integer("rev").default(1), // 리비전 정보
 
+  // 히스토리 관리
+  vendorInfoSnapshot: json("vendor_info_snapshot"), // AVL 생성 시점의 vendorInfo 현황 스냅샷
+  
   // 타임스탬프
   createdAt: timestamp("created_at").defaultNow(), // 등재일
   createdBy: varchar("created_by", { length: 50 }), // 등재자
@@ -29,10 +32,18 @@ export const avlVendorInfo = pgTable("avl_vendor_info", {
   // 기본 식별자
   id: integer("id").primaryKey().generatedAlwaysAsIdentity(),
 
+  isTemplate: boolean("is_template").default(false), // false: 프로젝트 AVL의 레코드임, true: 표준 AVL의 레코드임
+
+  // 표준 AVL용 필드들 (isTemplate=true일 경우)
+  constructionSector: varchar("construction_sector", { length: 10 }), // 공사부문 (표준 AVL일 경우)
+  shipType: varchar("ship_type", { length: 50 }), // 선종 (표준 AVL일 경우)
+  avlKind: varchar("avl_kind", { length: 50 }), // AVL 종류 (표준 AVL일 경우)
+  htDivision: varchar("ht_division", { length: 10 }), // H/T 구분 (표준 AVL일 경우)
+
   projectCode: varchar("project_code", { length: 50 }), // 프로젝트코드 (프로젝트 AVL일 경우)
 
-  // AVL 리스트와의 관계 (외래키)
-  avlListId: integer("avl_list_id").references(() => avlList.id),
+  // AVL 리스트와의 관계 (자식이 먼저 생기므로.. 제약조건 없는 외래키)
+  avlListId: integer("avl_list_id"),
 
   // 제안방향
   ownerSuggestion: boolean("owner_suggestion").default(false), // 선주 제안사인 경우
diff --git a/lib/avl/components/avl-history-modal.tsx b/lib/avl/components/avl-history-modal.tsx
new file mode 100644
index 00000000..4f0c354b
--- /dev/null
+++ b/lib/avl/components/avl-history-modal.tsx
@@ -0,0 +1,297 @@
+"use client"
+
+import * as React from "react"
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+} from "@/components/ui/dialog"
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
+import {
+  Table,
+  TableBody,
+  TableCell,
+  TableHead,
+  TableHeader,
+  TableRow,
+} from "@/components/ui/table"
+import { Calendar, Users, FileText, ChevronDown, ChevronRight } from "lucide-react"
+import type { AvlListItem } from "@/lib/avl/types"
+
+interface AvlHistoryModalProps {
+  isOpen: boolean
+  onClose: () => void
+  avlItem: AvlListItem | null
+  historyData?: AvlHistoryRecord[]
+  onLoadHistory?: (avlItem: AvlListItem) => Promise<AvlHistoryRecord[]>
+}
+
+export interface VendorSnapshot {
+  id: number
+  vendorName?: string
+  avlVendorName?: string
+  vendorCode?: string
+  disciplineName?: string
+  materialNameCustomerSide?: string
+  materialGroupCode?: string
+  materialGroupName?: string
+  tier?: string
+  hasAvl?: boolean
+  faTarget?: boolean
+  headquarterLocation?: string
+  ownerSuggestion?: boolean
+  shiSuggestion?: boolean
+  [key: string]: unknown // 다른 모든 속성들
+}
+
+export interface AvlHistoryRecord {
+  id: number
+  rev: number
+  createdAt: string
+  createdBy: string
+  vendorInfoSnapshot: VendorSnapshot[] // JSON 데이터
+  changeDescription?: string
+}
+
+// 스냅샷 테이블 컴포넌트
+interface SnapshotTableProps {
+  snapshot: VendorSnapshot[]
+  isOpen: boolean
+  onToggle: () => void
+}
+
+function SnapshotTable({ snapshot, isOpen, onToggle }: SnapshotTableProps) {
+  if (!snapshot || snapshot.length === 0) {
+    return (
+      <div className="text-sm text-muted-foreground">
+        스냅샷 데이터가 없습니다.
+      </div>
+    )
+  }
+
+  return (
+    <Collapsible open={isOpen} onOpenChange={onToggle}>
+      <CollapsibleTrigger asChild>
+        <Button variant="outline" size="sm" className="w-full justify-between">
+          <span>벤더 상세 정보 ({snapshot.length}개)</span>
+          {isOpen ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
+        </Button>
+      </CollapsibleTrigger>
+      <CollapsibleContent className="mt-3">
+        <div className="border rounded-lg">
+          <div className="overflow-auto max-h-[400px]">
+            <Table>
+              <TableHeader className="sticky top-0 bg-background z-10">
+                <TableRow>
+                  <TableHead className="w-[60px]">No.</TableHead>
+                  <TableHead className="w-[100px]">설계공종</TableHead>
+                  <TableHead>고객사 AVL 자재명</TableHead>
+                  <TableHead className="w-[120px]">자재그룹 코드</TableHead>
+                  <TableHead className="w-[130px]">자재그룹 명</TableHead>
+                  <TableHead>AVL 등재업체명</TableHead>
+                  <TableHead className="w-[120px]">협력업체 코드</TableHead>
+                  <TableHead className="w-[130px]">협력업체 명</TableHead>
+                  <TableHead className="w-[80px]">선주제안</TableHead>
+                  <TableHead className="w-[80px]">SHI 제안</TableHead>
+                  <TableHead className="w-[100px]">본사 위치</TableHead>
+                  <TableHead className="w-[80px]">등급</TableHead>
+                  <TableHead className="w-[60px]">AVL</TableHead>
+                  <TableHead className="w-[80px]">FA대상</TableHead>
+                </TableRow>
+              </TableHeader>
+              <TableBody>
+                {snapshot.map((item, index) => (
+                  <TableRow key={item.id || index}>
+                    <TableCell className="font-mono text-xs text-center">{index + 1}</TableCell>
+                    <TableCell className="text-sm">{item.disciplineName || '-'}</TableCell>
+                    <TableCell className="text-sm">{item.materialNameCustomerSide || '-'}</TableCell>
+                    <TableCell className="font-mono text-xs">{item.materialGroupCode || '-'}</TableCell>
+                    <TableCell className="text-sm">{item.materialGroupName || '-'}</TableCell>
+                    <TableCell className="font-medium text-sm">{item.avlVendorName || '-'}</TableCell>
+                    <TableCell className="font-mono text-xs">{item.vendorCode || '-'}</TableCell>
+                    <TableCell className="font-medium text-sm">{item.vendorName || '-'}</TableCell>
+                    <TableCell>
+                      <Badge variant={item.ownerSuggestion ? "default" : "secondary"} className="text-xs">
+                        {item.ownerSuggestion ? "예" : "아니오"}
+                      </Badge>
+                    </TableCell>
+                    <TableCell>
+                      <Badge variant={item.shiSuggestion ? "default" : "secondary"} className="text-xs">
+                        {item.shiSuggestion ? "예" : "아니오"}
+                      </Badge>
+                    </TableCell>
+                    <TableCell className="text-xs">{item.headquarterLocation || '-'}</TableCell>
+                    <TableCell>
+                      {item.tier ? (
+                        <Badge variant="outline" className="text-xs">
+                          {item.tier}
+                        </Badge>
+                      ) : '-'}
+                    </TableCell>
+                    <TableCell>
+                      <Badge variant={item.hasAvl ? "default" : "secondary"} className="text-xs">
+                        {item.hasAvl ? "Y" : "N"}
+                      </Badge>
+                    </TableCell>
+                    <TableCell>
+                      <Badge variant={item.faTarget ? "default" : "secondary"} className="text-xs">
+                        {item.faTarget ? "Y" : "N"}
+                      </Badge>
+                    </TableCell>
+                  </TableRow>
+                ))}
+              </TableBody>
+            </Table>
+          </div>
+        </div>
+      </CollapsibleContent>
+    </Collapsible>
+  )
+}
+
+export function AvlHistoryModal({
+  isOpen,
+  onClose,
+  avlItem,
+  historyData,
+  onLoadHistory
+}: AvlHistoryModalProps) {
+  const [loading, setLoading] = React.useState(false)
+  const [history, setHistory] = React.useState<AvlHistoryRecord[]>([])
+  const [openSnapshots, setOpenSnapshots] = React.useState<Record<number, boolean>>({})
+
+  // 히스토리 데이터 로드
+  React.useEffect(() => {
+    if (isOpen && avlItem && onLoadHistory) {
+      setLoading(true)
+      onLoadHistory(avlItem)
+        .then(setHistory)
+        .catch(console.error)
+        .finally(() => setLoading(false))
+    } else if (historyData) {
+      setHistory(historyData)
+    }
+  }, [isOpen, avlItem, onLoadHistory, historyData])
+
+  // 스냅샷 테이블 토글 함수
+  const toggleSnapshot = (recordId: number) => {
+    setOpenSnapshots(prev => ({
+      ...prev,
+      [recordId]: !prev[recordId]
+    }))
+  }
+
+  if (!avlItem) return null
+
+  return (
+    <Dialog open={isOpen} onOpenChange={onClose}>
+      <DialogContent className="max-w-7xl h-[90vh] flex flex-col">
+        <DialogHeader className="flex-shrink-0">
+          <DialogTitle className="flex items-center gap-2">
+            <FileText className="h-5 w-5" />
+            AVL 리비전 히스토리
+          </DialogTitle>
+          <div className="text-sm text-muted-foreground">
+            {avlItem.isTemplate ? "표준 AVL" : "프로젝트 AVL"} - {avlItem.avlKind}
+            {avlItem.projectCode && ` (${avlItem.projectCode})`}
+          </div>
+        </DialogHeader>
+
+        <div className="flex-1 overflow-auto min-h-0">
+          <div className="pr-4">
+          {loading ? (
+            <div className="flex items-center justify-center h-[300px]">
+              <div className="text-muted-foreground">히스토리를 불러오는 중...</div>
+            </div>
+          ) : history.length === 0 ? (
+            <div className="flex items-center justify-center h-[300px]">
+              <div className="text-muted-foreground">히스토리 데이터가 없습니다.</div>
+            </div>
+          ) : (
+            <div className="space-y-4 py-4">
+              {history.map((record, index) => (
+                <div
+                  key={record.id}
+                  className={`p-4 border rounded-lg ${
+                    index === 0 ? "border-primary bg-primary/5" : "border-border"
+                  }`}
+                >
+                  {/* 리비전 헤더 */}
+                  <div className="flex items-center justify-between mb-3">
+                    <div className="flex items-center gap-2">
+                      <Badge
+                        variant={index === 0 ? "default" : "outline"}
+                        className="font-mono"
+                      >
+                        Rev {record.rev}
+                      </Badge>
+                      {index === 0 && (
+                        <Badge variant="secondary" className="text-xs">
+                          현재
+                        </Badge>
+                      )}
+                    </div>
+                    <div className="flex items-center gap-4 text-sm text-muted-foreground">
+                      <div className="flex items-center gap-1">
+                        <Calendar className="h-4 w-4" />
+                        {new Date(record.createdAt).toLocaleDateString('ko-KR')}
+                      </div>
+                    </div>
+                  </div>
+
+                  {/* 변경 설명 */}
+                  {record.changeDescription && (
+                    <div className="mb-3 p-2 bg-muted/50 rounded text-sm">
+                      {record.changeDescription}
+                    </div>
+                  )}
+
+                  {/* Vendor Info 요약 */}
+                  <div className="grid grid-cols-3 gap-4 text-sm">
+                    <div className="text-center">
+                      <div className="font-medium text-lg">
+                        {record.vendorInfoSnapshot?.length || 0}
+                      </div>
+                      <div className="text-muted-foreground">총 협력업체</div>
+                    </div>
+                    <div className="text-center">
+                      <div className="font-medium text-lg">
+                        {record.vendorInfoSnapshot?.filter(v => v.hasAvl).length || 0}
+                      </div>
+                      <div className="text-muted-foreground">AVL 등재</div>
+                    </div>
+                    <div className="text-center">
+                      <div className="font-medium text-lg">
+                        {record.vendorInfoSnapshot?.filter(v => v.faTarget).length || 0}
+                      </div>
+                      <div className="text-muted-foreground">FA 대상</div>
+                    </div>
+                  </div>
+
+                  {/* 스냅샷 테이블 */}
+                  <div className="mt-3 pt-3 border-t">
+                    <SnapshotTable
+                      snapshot={record.vendorInfoSnapshot || []}
+                      isOpen={openSnapshots[record.id] || false}
+                      onToggle={() => toggleSnapshot(record.id)}
+                    />
+                  </div>
+                </div>
+              ))}
+            </div>
+          )}
+          </div>
+        </div>
+
+        <div className="flex justify-end pt-4 border-t flex-shrink-0 mt-4">
+          <Button variant="outline" onClick={onClose}>
+            닫기
+          </Button>
+        </div>
+      </DialogContent>
+    </Dialog>
+  )
+}
\ No newline at end of file
diff --git a/lib/avl/components/project-field-components.tsx b/lib/avl/components/project-field-components.tsx
new file mode 100644
index 00000000..95505d08
--- /dev/null
+++ b/lib/avl/components/project-field-components.tsx
@@ -0,0 +1,113 @@
+"use client"
+
+import * as React from "react"
+import { Input } from "@/components/ui/input"
+import { Button } from "@/components/ui/button"
+import {
+  ProjectSearchStatus,
+  getLabelStatusClassName,
+  getDisplayElementStatusClassName,
+  getInputStatusClassName
+} from "./project-field-utils"
+
+// 타입 재내보내기
+export type { ProjectSearchStatus } from "./project-field-utils"
+
+// 재사용 가능한 필드 컴포넌트들
+export interface ProjectInputFieldProps {
+  label: string
+  value: string
+  onChange: (value: string) => void
+  placeholder: string
+  status: ProjectSearchStatus
+  statusText?: string
+  minWidth?: string
+}
+
+export const ProjectInputField: React.FC<ProjectInputFieldProps> = ({
+  label,
+  value,
+  onChange,
+  placeholder,
+  status,
+  statusText,
+  minWidth = "250px"
+}) => (
+  <div className="space-y-2 min-w-[250px] flex-shrink-0" style={{ minWidth }}>
+    <label className={`text-sm font-medium ${getLabelStatusClassName(status)}`}>
+      {label}
+      {statusText && <span className="ml-1 text-xs">{statusText}</span>}
+    </label>
+    <Input
+      value={value}
+      onChange={(e) => onChange(e.target.value)}
+      placeholder={placeholder}
+      className={`h-8 text-sm ${getInputStatusClassName(status)}`}
+    />
+  </div>
+)
+
+export interface ProjectDisplayFieldProps {
+  label: string
+  value: string
+  status: ProjectSearchStatus
+  minWidth?: string
+  formatter?: (value: string) => string
+}
+
+export const ProjectDisplayField: React.FC<ProjectDisplayFieldProps> = ({
+  label,
+  value,
+  status,
+  minWidth = "120px",
+  formatter
+}) => {
+  const displayValue = status === 'searching' ? '조회 중...' : (formatter ? formatter(value) : (value || '-'))
+
+  return (
+    <div className="space-y-2 flex-shrink-0" style={{ minWidth }}>
+      <label className={`text-sm font-medium ${getLabelStatusClassName(status)}`}>
+        {label}
+        {status === 'searching' && <span className="ml-1 text-xs">(조회 중...)</span>}
+      </label>
+      <div className={`text-sm font-medium min-h-[32px] flex items-center border rounded-md px-3 bg-background ${getDisplayElementStatusClassName(status)}`}>
+        {displayValue}
+      </div>
+    </div>
+  )
+}
+
+export interface ProjectFileFieldProps {
+  label: string
+  originalFile: string
+  onFileUpload: (event: React.ChangeEvent<HTMLInputElement>) => void
+  minWidth?: string
+}
+
+export const ProjectFileField: React.FC<ProjectFileFieldProps> = ({
+  label,
+  originalFile,
+  onFileUpload,
+  minWidth = "200px"
+}) => (
+  <div className="space-y-2 flex-shrink-0" style={{ minWidth }}>
+    <label className="text-sm font-medium text-muted-foreground">{label}</label>
+    <div className="flex items-center gap-2 min-h-[32px]">
+      {originalFile ? (
+        <span className="text-sm text-blue-600">{originalFile}</span>
+      ) : (
+        <div className="relative">
+          <input
+            type="file"
+            onChange={onFileUpload}
+            className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
+            accept=".xlsx,.xls,.csv"
+          />
+          <Button variant="outline" size="sm" className="text-xs">
+            파일 선택
+          </Button>
+        </div>
+      )}
+    </div>
+  </div>
+)
diff --git a/lib/avl/components/project-field-utils.ts b/lib/avl/components/project-field-utils.ts
new file mode 100644
index 00000000..d3d84295
--- /dev/null
+++ b/lib/avl/components/project-field-utils.ts
@@ -0,0 +1,45 @@
+// 프로젝트 검색 상태 타입
+export type ProjectSearchStatus = 'idle' | 'searching' | 'success-projects' | 'success-bidding' | 'error'
+
+// 프로젝트 상태에 따른 스타일링 유틸리티 함수들
+export const getLabelStatusClassName = (status: ProjectSearchStatus): string => {
+  switch (status) {
+    case 'error':
+      return 'text-red-600'
+    case 'success-projects':
+    case 'success-bidding':
+      return 'text-green-600'
+    case 'searching':
+      return 'text-blue-600'
+    default:
+      return 'text-muted-foreground'
+  }
+}
+
+export const getDisplayElementStatusClassName = (status: ProjectSearchStatus): string => {
+  switch (status) {
+    case 'error':
+      return 'border-red-300'
+    case 'success-projects':
+    case 'success-bidding':
+      return 'border-green-300'
+    case 'searching':
+      return 'border-blue-300'
+    default:
+      return 'border-input'
+  }
+}
+
+export const getInputStatusClassName = (status: ProjectSearchStatus): string => {
+  switch (status) {
+    case 'error':
+      return 'border-red-300 focus:border-red-500 focus:ring-red-500/20'
+    case 'success-projects':
+    case 'success-bidding':
+      return 'border-green-300 focus:border-green-500 focus:ring-green-500/20'
+    case 'searching':
+      return 'border-blue-300 focus:border-blue-500 focus:ring-blue-500/20'
+    default:
+      return ''
+  }
+}
diff --git a/lib/avl/service.ts b/lib/avl/service.ts
index 6a873ac1..535a0169 100644
--- a/lib/avl/service.ts
+++ b/lib/avl/service.ts
@@ -2,18 +2,21 @@
 
 import { GetAvlListSchema, GetAvlDetailSchema, GetProjectAvlSchema, GetStandardAvlSchema } from "./validations";
 import { AvlListItem, AvlDetailItem, CreateAvlListInput, UpdateAvlListInput, ActionResult, AvlVendorInfoInput } from "./types";
-import type { NewAvlVendorInfo, AvlVendorInfo } from "@/db/schema/avl/avl";
+import type { NewAvlVendorInfo } from "@/db/schema/avl/avl";
+import type { NewVendorPool } from "@/db/schema/avl/vendor-pool";
 import db from "@/db/db";
 import { avlList, avlVendorInfo } from "@/db/schema/avl/avl";
-import { eq, and, or, ilike, count, desc, asc, sql } from "drizzle-orm";
+import { vendorPool } from "@/db/schema/avl/vendor-pool";
+import { eq, and, or, ilike, count, desc, asc, sql, inArray } from "drizzle-orm";
 import { debugLog, debugError, debugSuccess, debugWarn } from "@/lib/debug-utils";
-import { revalidateTag, unstable_cache } from "next/cache";
+import { revalidateTag } from "next/cache";
+import { createVendorInfoSnapshot } from "./snapshot-utils";
 
 /**
  * AVL 리스트 조회
  * avl_list 테이블에서 실제 데이터를 조회합니다.
  */
-const _getAvlLists = async (input: GetAvlListSchema) => {
+export const getAvlLists = async (input: GetAvlListSchema) => {
   try {
     const offset = (input.page - 1) * input.perPage;
 
@@ -125,20 +128,11 @@ const _getAvlLists = async (input: GetAvlListSchema) => {
   }
 };
 
-// 캐시된 버전 export - 동일한 입력에 대해 캐시 사용
-export const getAvlLists = unstable_cache(
-  _getAvlLists,
-  ['avl-list'],
-  {
-    tags: ['avl-list'],
-    revalidate: 300, // 5분 캐시
-  }
-);
 
 /**
  * AVL 상세 정보 조회 (특정 AVL ID의 모든 vendor info)
  */
-const _getAvlDetail = async (input: GetAvlDetailSchema & { avlListId: number }) => {
+export const getAvlDetail = async (input: GetAvlDetailSchema & { avlListId: number }) => {
   try {
     const offset = (input.page - 1) * input.perPage;
 
@@ -326,15 +320,6 @@ const _getAvlDetail = async (input: GetAvlDetailSchema & { avlListId: number })
   }
 };
 
-// 캐시된 버전 export
-export const getAvlDetail = unstable_cache(
-  _getAvlDetail,
-  ['avl-detail'],
-  {
-    tags: ['avl-detail'],
-    revalidate: 300, // 5분 캐시
-  }
-);
 
 /**
  * AVL 리스트 상세 정보 조회 (단일)
@@ -522,11 +507,17 @@ export async function createAvlList(data: CreateAvlListInput): Promise<AvlListIt
       avlKind: data.avlKind,
       htDivision: data.htDivision,
       rev: data.rev ?? 1,
+      vendorInfoSnapshot: data.vendorInfoSnapshot, // 스냅샷 데이터 추가
       createdBy: data.createdBy || 'system',
       updatedBy: data.updatedBy || 'system',
     };
 
-    debugLog('DB INSERT 시작', { table: 'avl_list', data: insertData });
+    debugLog('DB INSERT 시작', { 
+      table: 'avl_list', 
+      data: insertData,
+      hasVendorSnapshot: !!insertData.vendorInfoSnapshot,
+      snapshotLength: insertData.vendorInfoSnapshot?.length
+    });
 
     // 데이터베이스에 삽입
     const result = await db
@@ -539,7 +530,11 @@ export async function createAvlList(data: CreateAvlListInput): Promise<AvlListIt
       throw new Error("Failed to create AVL list");
     }
 
-    debugSuccess('DB INSERT 완료', { table: 'avl_list', result: result[0] });
+    debugSuccess('DB INSERT 완료', { 
+      table: 'avl_list', 
+      result: result[0],
+      savedSnapshotLength: result[0].vendorInfoSnapshot?.length
+    });
 
     const createdItem = result[0];
 
@@ -555,6 +550,7 @@ export async function createAvlList(data: CreateAvlListInput): Promise<AvlListIt
       avlType: createdItem.avlKind || '',
       htDivision: createdItem.htDivision || '',
       rev: createdItem.rev || 1,
+      vendorInfoSnapshot: createdItem.vendorInfoSnapshot, // 스냅샷 데이터 포함
     };
 
     debugSuccess('AVL 리스트 생성 완료', { result: transformedData });
@@ -684,11 +680,15 @@ export async function createAvlVendorInfo(data: AvlVendorInfoInput): Promise<Avl
   try {
     debugLog('AVL Vendor Info 생성 시작', { inputData: data });
 
-    const currentTimestamp = new Date();
-
     // UI 필드를 DB 필드로 변환
     const insertData: NewAvlVendorInfo = {
-      avlListId: data.avlListId,
+      isTemplate: data.isTemplate ?? false, // AVL 타입 구분
+      constructionSector: data.constructionSector || null, // 표준 AVL용
+      shipType: data.shipType || null, // 표준 AVL용
+      avlKind: data.avlKind || null, // 표준 AVL용
+      htDivision: data.htDivision || null, // 표준 AVL용
+      projectCode: data.projectCode || null, // 프로젝트 코드 저장
+      avlListId: data.avlListId || null, // nullable - 나중에 프로젝트별로 묶어줄 때 설정
       ownerSuggestion: data.ownerSuggestion ?? false,
       shiSuggestion: data.shiSuggestion ?? false,
       equipBulkDivision: data.equipBulkDivision === "EQUIP" ? "E" : "B",
@@ -906,11 +906,173 @@ export async function deleteAvlVendorInfo(id: number): Promise<boolean> {
   }
 }
 
+/**
+ * 프로젝트 AVL 최종 확정
+ * 1. 주어진 프로젝트 정보로 avlList에 레코드를 생성한다.
+ * 2. 현재 avlVendorInfo 레코드들의 avlListId를 새로 생성된 AVL 리스트 ID로 업데이트한다.
+ */
+export async function finalizeProjectAvl(
+  projectCode: string,
+  projectInfo: {
+    projectName: string;
+    constructionSector: string;
+    shipType: string;
+    htDivision: string;
+  },
+  avlVendorInfoIds: number[],
+  currentUser?: string
+): Promise<{ success: boolean; avlListId?: number; message: string }> {
+  try {
+    debugLog('프로젝트 AVL 최종 확정 시작', { 
+      projectCode, 
+      projectInfo, 
+      avlVendorInfoIds: avlVendorInfoIds.length,
+      currentUser 
+    });
+
+    // 1. 기존 AVL 리스트의 최고 revision 확인
+    const existingAvlLists = await db
+      .select({ rev: avlList.rev })
+      .from(avlList)
+      .where(and(
+        eq(avlList.projectCode, projectCode),
+        eq(avlList.isTemplate, false)
+      ))
+      .orderBy(desc(avlList.rev))
+      .limit(1);
+
+    const nextRevision = existingAvlLists.length > 0 ? (existingAvlLists[0].rev || 0) + 1 : 1;
+
+    debugLog('AVL 리스트 revision 계산', {
+      projectCode,
+      existingRevision: existingAvlLists.length > 0 ? existingAvlLists[0].rev : 0,
+      nextRevision
+    });
+
+    // 2. AVL 리스트 생성을 위한 데이터 준비
+    const createAvlListData: CreateAvlListInput = {
+      isTemplate: false, // 프로젝트 AVL이므로 false
+      constructionSector: projectInfo.constructionSector,
+      projectCode: projectCode,
+      shipType: projectInfo.shipType,
+      avlKind: "프로젝트 AVL", // 기본값으로 설정
+      htDivision: projectInfo.htDivision,
+      rev: nextRevision, // 계산된 다음 리비전
+      createdBy: currentUser || 'system',
+      updatedBy: currentUser || 'system',
+    };
+
+    debugLog('AVL 리스트 생성 데이터', { createAvlListData });
+
+    // 2. AVL Vendor Info 스냅샷 생성 (AVL 리스트 생성 전에 현재 상태 저장)
+    debugLog('AVL Vendor Info 스냅샷 생성 시작', { 
+      vendorInfoIdsCount: avlVendorInfoIds.length,
+      vendorInfoIds: avlVendorInfoIds 
+    });
+    const vendorInfoSnapshot = await createVendorInfoSnapshot(avlVendorInfoIds);
+    debugSuccess('AVL Vendor Info 스냅샷 생성 완료', { 
+      snapshotCount: vendorInfoSnapshot.length,
+      snapshotSize: JSON.stringify(vendorInfoSnapshot).length,
+      sampleSnapshot: vendorInfoSnapshot.slice(0, 1) // 첫 번째 항목만 로깅
+    });
+
+    // 스냅샷을 AVL 리스트 생성 데이터에 추가
+    createAvlListData.vendorInfoSnapshot = vendorInfoSnapshot;
+    debugLog('스냅샷이 createAvlListData에 추가됨', { 
+      hasSnapshot: !!createAvlListData.vendorInfoSnapshot,
+      snapshotLength: createAvlListData.vendorInfoSnapshot?.length 
+    });
+
+    // 3. AVL 리스트 생성
+    const newAvlList = await createAvlList(createAvlListData);
+    
+    if (!newAvlList) {
+      throw new Error("AVL 리스트 생성에 실패했습니다.");
+    }
+
+    debugSuccess('AVL 리스트 생성 완료', { avlListId: newAvlList.id });
+
+    // 3. avlVendorInfo 레코드들의 avlListId 업데이트
+    if (avlVendorInfoIds.length > 0) {
+      debugLog('AVL Vendor Info 업데이트 시작', { 
+        count: avlVendorInfoIds.length, 
+        newAvlListId: newAvlList.id 
+      });
+
+      const updateResults = await Promise.all(
+        avlVendorInfoIds.map(async (vendorInfoId) => {
+          try {
+            const result = await db
+              .update(avlVendorInfo)
+              .set({ 
+                avlListId: newAvlList.id,
+                projectCode: projectCode,
+                updatedAt: new Date()
+              })
+              .where(eq(avlVendorInfo.id, vendorInfoId))
+              .returning({ id: avlVendorInfo.id });
+
+            return { id: vendorInfoId, success: true, result };
+          } catch (error) {
+            debugError('AVL Vendor Info 업데이트 실패', { vendorInfoId, error });
+            return { id: vendorInfoId, success: false, error };
+          }
+        })
+      );
+
+      // 업데이트 결과 검증
+      const successCount = updateResults.filter(r => r.success).length;
+      const failCount = updateResults.filter(r => !r.success).length;
+
+      debugLog('AVL Vendor Info 업데이트 결과', { 
+        total: avlVendorInfoIds.length,
+        success: successCount,
+        failed: failCount
+      });
+
+      if (failCount > 0) {
+        debugWarn('일부 AVL Vendor Info 업데이트 실패', { 
+          failedIds: updateResults.filter(r => !r.success).map(r => r.id)
+        });
+      }
+    }
+
+    // 4. 캐시 무효화
+    revalidateTag('avl-list');
+    revalidateTag('avl-vendor-info');
+
+    debugSuccess('프로젝트 AVL 최종 확정 완료', { 
+      avlListId: newAvlList.id,
+      projectCode,
+      vendorInfoCount: avlVendorInfoIds.length
+    });
+
+    return {
+      success: true,
+      avlListId: newAvlList.id,
+      message: `프로젝트 AVL이 성공적으로 확정되었습니다. (AVL ID: ${newAvlList.id}, 벤더 정보: ${avlVendorInfoIds.length}개)`
+    };
+
+  } catch (err) {
+    debugError('프로젝트 AVL 최종 확정 실패', { 
+      projectCode, 
+      error: err 
+    });
+
+    console.error("Error in finalizeProjectAvl:", err);
+    
+    return {
+      success: false,
+      message: err instanceof Error ? err.message : "프로젝트 AVL 최종 확정 중 오류가 발생했습니다."
+    };
+  }
+}
+
 /**
  * 프로젝트 AVL Vendor Info 조회 (프로젝트별, isTemplate=false)
  * avl_list와 avlVendorInfo를 JOIN하여 프로젝트별 AVL 데이터를 조회합니다.
  */
-const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
+export const getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
   try {
     const offset = (input.page - 1) * input.perPage;
 
@@ -920,11 +1082,11 @@ const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
     // 실제 쿼리는 아래에서 구성됨
 
     // 검색 조건 구성
-    const whereConditions: any[] = [eq(avlList.isTemplate, false)]; // 기본 조건
+    const whereConditions: any[] = []; // 기본 조건 제거
 
-    // 필수 필터: 프로젝트 코드
+    // 필수 필터: 프로젝트 코드 (avlVendorInfo에서 직접 필터링)
     if (input.projectCode) {
-      whereConditions.push(ilike(avlList.projectCode, `%${input.projectCode}%`));
+      whereConditions.push(ilike(avlVendorInfo.projectCode, `%${input.projectCode}%`));
     }
 
     // 검색어 기반 필터링
@@ -1002,7 +1164,7 @@ const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
     const totalCount = await db
       .select({ count: count() })
       .from(avlVendorInfo)
-      .innerJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
+      .leftJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
       .where(and(...whereConditions));
 
     // 데이터 조회 - JOIN 결과에서 필요한 필드들을 명시적으로 선택
@@ -1010,6 +1172,7 @@ const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
       .select({
         // avlVendorInfo의 모든 필드
         id: avlVendorInfo.id,
+        projectCode: avlVendorInfo.projectCode,
         avlListId: avlVendorInfo.avlListId,
         ownerSuggestion: avlVendorInfo.ownerSuggestion,
         shiSuggestion: avlVendorInfo.shiSuggestion,
@@ -1054,7 +1217,7 @@ const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
         updatedAt: avlVendorInfo.updatedAt,
       })
       .from(avlVendorInfo)
-      .innerJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
+      .leftJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
       .where(and(...whereConditions))
       .orderBy(...orderByConditions)
       .limit(input.perPage)
@@ -1103,21 +1266,12 @@ const _getProjectAvlVendorInfo = async (input: GetProjectAvlSchema) => {
   }
 };
 
-// 캐시된 버전 export
-export const getProjectAvlVendorInfo = unstable_cache(
-  _getProjectAvlVendorInfo,
-  ['project-avl-vendor-info'],
-  {
-    tags: ['project-avl-vendor-info'],
-    revalidate: 300, // 5분 캐시
-  }
-);
 
 /**
  * 표준 AVL Vendor Info 조회 (선종별 표준 AVL, isTemplate=true)
  * avl_list와 avlVendorInfo를 JOIN하여 표준 AVL 데이터를 조회합니다.
  */
-const _getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
+export const getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
   try {
     const offset = (input.page - 1) * input.perPage;
 
@@ -1127,20 +1281,20 @@ const _getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
     // 실제 쿼리는 아래에서 구성됨
 
     // 검색 조건 구성
-    const whereConditions: any[] = [eq(avlList.isTemplate, true)]; // 기본 조건
+    const whereConditions: any[] = [eq(avlVendorInfo.isTemplate, true)]; // 기본 조건: 표준 AVL
 
-    // 필수 필터: 표준 AVL용 (공사부문, 선종, AVL종류, H/T)
+    // 필수 필터: 표준 AVL용 (공사부문, 선종, AVL종류, H/T) - avlVendorInfo에서 직접 필터링
     if (input.constructionSector) {
-      whereConditions.push(ilike(avlList.constructionSector, `%${input.constructionSector}%`));
+      whereConditions.push(ilike(avlVendorInfo.constructionSector, `%${input.constructionSector}%`));
     }
     if (input.shipType) {
-      whereConditions.push(ilike(avlList.shipType, `%${input.shipType}%`));
+      whereConditions.push(ilike(avlVendorInfo.shipType, `%${input.shipType}%`));
     }
     if (input.avlKind) {
-      whereConditions.push(ilike(avlList.avlKind, `%${input.avlKind}%`));
+      whereConditions.push(ilike(avlVendorInfo.avlKind, `%${input.avlKind}%`));
     }
     if (input.htDivision) {
-      whereConditions.push(eq(avlList.htDivision, input.htDivision));
+      whereConditions.push(eq(avlVendorInfo.htDivision, input.htDivision));
     }
 
     // 검색어 기반 필터링
@@ -1218,14 +1372,59 @@ const _getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
     const totalCount = await db
       .select({ count: count() })
       .from(avlVendorInfo)
-      .innerJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
       .where(and(...whereConditions));
 
-    // 데이터 조회
+    // 데이터 조회 - avlVendorInfo에서 직접 조회
     const data = await db
-      .select()
+      .select({
+        // avlVendorInfo의 모든 필드
+        id: avlVendorInfo.id,
+        isTemplate: avlVendorInfo.isTemplate,
+        projectCode: avlVendorInfo.projectCode,
+        avlListId: avlVendorInfo.avlListId,
+        ownerSuggestion: avlVendorInfo.ownerSuggestion,
+        shiSuggestion: avlVendorInfo.shiSuggestion,
+        equipBulkDivision: avlVendorInfo.equipBulkDivision,
+        disciplineCode: avlVendorInfo.disciplineCode,
+        disciplineName: avlVendorInfo.disciplineName,
+        materialNameCustomerSide: avlVendorInfo.materialNameCustomerSide,
+        packageCode: avlVendorInfo.packageCode,
+        packageName: avlVendorInfo.packageName,
+        materialGroupCode: avlVendorInfo.materialGroupCode,
+        materialGroupName: avlVendorInfo.materialGroupName,
+        vendorId: avlVendorInfo.vendorId,
+        vendorName: avlVendorInfo.vendorName,
+        vendorCode: avlVendorInfo.vendorCode,
+        avlVendorName: avlVendorInfo.avlVendorName,
+        tier: avlVendorInfo.tier,
+        faTarget: avlVendorInfo.faTarget,
+        faStatus: avlVendorInfo.faStatus,
+        isAgent: avlVendorInfo.isAgent,
+        contractSignerId: avlVendorInfo.contractSignerId,
+        contractSignerName: avlVendorInfo.contractSignerName,
+        contractSignerCode: avlVendorInfo.contractSignerCode,
+        headquarterLocation: avlVendorInfo.headquarterLocation,
+        manufacturingLocation: avlVendorInfo.manufacturingLocation,
+        hasAvl: avlVendorInfo.hasAvl,
+        isBlacklist: avlVendorInfo.isBlacklist,
+        isBcc: avlVendorInfo.isBcc,
+        techQuoteNumber: avlVendorInfo.techQuoteNumber,
+        quoteCode: avlVendorInfo.quoteCode,
+        quoteVendorId: avlVendorInfo.quoteVendorId,
+        quoteVendorName: avlVendorInfo.quoteVendorName,
+        quoteVendorCode: avlVendorInfo.quoteVendorCode,
+        quoteCountry: avlVendorInfo.quoteCountry,
+        quoteTotalAmount: avlVendorInfo.quoteTotalAmount,
+        quoteReceivedDate: avlVendorInfo.quoteReceivedDate,
+        recentQuoteDate: avlVendorInfo.recentQuoteDate,
+        recentQuoteNumber: avlVendorInfo.recentQuoteNumber,
+        recentOrderDate: avlVendorInfo.recentOrderDate,
+        recentOrderNumber: avlVendorInfo.recentOrderNumber,
+        remark: avlVendorInfo.remark,
+        createdAt: avlVendorInfo.createdAt,
+        updatedAt: avlVendorInfo.updatedAt,
+      })
       .from(avlVendorInfo)
-      .innerJoin(avlList, eq(avlVendorInfo.avlListId, avlList.id))
       .where(and(...whereConditions))
       .orderBy(...orderByConditions)
       .limit(input.perPage)
@@ -1233,30 +1432,30 @@ const _getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
 
     // 데이터 변환
     const transformedData: AvlDetailItem[] = data.map((item: any, index) => ({
-      ...(item.avl_vendor_info || item),
+      ...item,
       no: offset + index + 1,
       selected: false,
-      createdAt: ((item.avl_vendor_info || item).createdAt as Date)?.toISOString().split('T')[0] || '',
-      updatedAt: ((item.avl_vendor_info || item).updatedAt as Date)?.toISOString().split('T')[0] || '',
+      createdAt: (item.createdAt as Date)?.toISOString().split('T')[0] || '',
+      updatedAt: (item.updatedAt as Date)?.toISOString().split('T')[0] || '',
       // UI 표시용 필드 변환
-      equipBulkDivision: (item.avl_vendor_info || item).equipBulkDivision === "E" ? "EQUIP" : "BULK",
-      faTarget: (item.avl_vendor_info || item).faTarget ?? false,
-      faStatus: (item.avl_vendor_info || item).faStatus || '',
-      agentStatus: (item.avl_vendor_info || item).isAgent ? "예" : "아니오",
-      shiAvl: (item.avl_vendor_info || item).hasAvl ?? false,
-      shiBlacklist: (item.avl_vendor_info || item).isBlacklist ?? false,
-      shiBcc: (item.avl_vendor_info || item).isBcc ?? false,
-      salesQuoteNumber: (item.avl_vendor_info || item).techQuoteNumber || '',
-      quoteCode: (item.avl_vendor_info || item).quoteCode || '',
-      salesVendorInfo: (item.avl_vendor_info || item).quoteVendorName || '',
-      salesCountry: (item.avl_vendor_info || item).quoteCountry || '',
-      totalAmount: (item.avl_vendor_info || item).quoteTotalAmount ? (item.avl_vendor_info || item).quoteTotalAmount.toString() : '',
-      quoteReceivedDate: (item.avl_vendor_info || item).quoteReceivedDate || '',
-      recentQuoteDate: (item.avl_vendor_info || item).recentQuoteDate || '',
-      recentQuoteNumber: (item.avl_vendor_info || item).recentQuoteNumber || '',
-      recentOrderDate: (item.avl_vendor_info || item).recentOrderDate || '',
-      recentOrderNumber: (item.avl_vendor_info || item).recentOrderNumber || '',
-      remarks: (item.avl_vendor_info || item).remark || '',
+      equipBulkDivision: item.equipBulkDivision === "E" ? "EQUIP" : "BULK",
+      faTarget: item.faTarget ?? false,
+      faStatus: item.faStatus || '',
+      agentStatus: item.isAgent ? "예" : "아니오",
+      shiAvl: item.hasAvl ?? false,
+      shiBlacklist: item.isBlacklist ?? false,
+      shiBcc: item.isBcc ?? false,
+      salesQuoteNumber: item.techQuoteNumber || '',
+      quoteCode: item.quoteCode || '',
+      salesVendorInfo: item.quoteVendorName || '',
+      salesCountry: item.quoteCountry || '',
+      totalAmount: item.quoteTotalAmount ? item.quoteTotalAmount.toString() : '',
+      quoteReceivedDate: item.quoteReceivedDate || '',
+      recentQuoteDate: item.recentQuoteDate || '',
+      recentQuoteNumber: item.recentQuoteNumber || '',
+      recentOrderDate: item.recentOrderDate || '',
+      recentOrderNumber: item.recentOrderNumber || '',
+      remarks: item.remark || '',
     }));
 
     const pageCount = Math.ceil(totalCount[0].count / input.perPage);
@@ -1274,12 +1473,891 @@ const _getStandardAvlVendorInfo = async (input: GetStandardAvlSchema) => {
   }
 };
 
-// 캐시된 버전 export
-export const getStandardAvlVendorInfo = unstable_cache(
-  _getStandardAvlVendorInfo,
-  ['standard-avl-vendor-info'],
-  {
-    tags: ['standard-avl-vendor-info'],
-    revalidate: 300, // 5분 캐시
+/**
+ * 선종별표준AVL → 프로젝트AVL로 복사
+ */
+export const copyToProjectAvl = async (
+  selectedIds: number[],
+  targetProjectCode: string,
+  targetAvlListId: number,
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('선종별표준AVL → 프로젝트AVL 복사 시작', { selectedIds, targetProjectCode, targetAvlListId });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (선종별표준AVL에서)
+    const selectedRecords = await db
+      .select()
+      .from(avlVendorInfo)
+      .where(
+        and(
+          eq(avlVendorInfo.isTemplate, true),
+          inArray(avlVendorInfo.id, selectedIds)
+        )
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // 복사할 데이터 준비
+    const recordsToInsert: NewAvlVendorInfo[] = selectedRecords.map(record => ({
+      ...record,
+      id: undefined, // 새 ID 생성
+      isTemplate: false, // 프로젝트 AVL로 변경
+      projectCode: targetProjectCode, // 대상 프로젝트 코드
+      avlListId: targetAvlListId, // 대상 AVL 리스트 ID
+      // 표준 AVL 필드들은 null로 설정 (프로젝트 AVL에서는 사용하지 않음)
+      constructionSector: null,
+      shipType: null,
+      avlKind: null,
+      htDivision: null,
+      createdAt: undefined,
+      updatedAt: undefined,
+    }));
+
+    // 벌크 인서트
+    await db.insert(avlVendorInfo).values(recordsToInsert);
+
+    debugSuccess('선종별표준AVL → 프로젝트AVL 복사 완료', {
+      copiedCount: recordsToInsert.length,
+      targetProjectCode,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('avl-lists');
+    revalidateTag('avl-vendor-info');
+
+    return {
+      success: true,
+      message: `${recordsToInsert.length}개의 항목이 프로젝트 AVL로 복사되었습니다.`
+    };
+
+  } catch (error) {
+    debugError('선종별표준AVL → 프로젝트AVL 복사 실패', { error, selectedIds, targetProjectCode });
+    return {
+      success: false,
+      message: "프로젝트 AVL로 복사 중 오류가 발생했습니다."
+    };
   }
-);
+};
+
+/**
+ * 프로젝트AVL → 선종별표준AVL로 복사
+ */
+export const copyToStandardAvl = async (
+  selectedIds: number[],
+  targetStandardInfo: {
+    constructionSector: string;
+    shipType: string;
+    avlKind: string;
+    htDivision: string;
+  },
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('프로젝트AVL → 선종별표준AVL 복사 시작', { selectedIds, targetStandardInfo });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선종별 표준 AVL 검색 조건 검증
+    if (!targetStandardInfo.constructionSector?.trim() ||
+        !targetStandardInfo.shipType?.trim() ||
+        !targetStandardInfo.avlKind?.trim() ||
+        !targetStandardInfo.htDivision?.trim()) {
+      return { success: false, message: "선종별 표준 AVL 검색 조건을 모두 입력해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (프로젝트AVL에서)
+    const selectedRecords = await db
+      .select()
+      .from(avlVendorInfo)
+      .where(
+        and(
+          eq(avlVendorInfo.isTemplate, false),
+          inArray(avlVendorInfo.id, selectedIds)
+        )
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // 복사할 데이터 준비
+    const recordsToInsert: NewAvlVendorInfo[] = selectedRecords.map(record => ({
+      ...record,
+      id: undefined, // 새 ID 생성
+      isTemplate: true, // 표준 AVL로 변경
+      // 프로젝트 AVL 필드들은 null로 설정
+      projectCode: null,
+      avlListId: null,
+      // 표준 AVL 필드들 설정
+      constructionSector: targetStandardInfo.constructionSector,
+      shipType: targetStandardInfo.shipType,
+      avlKind: targetStandardInfo.avlKind,
+      htDivision: targetStandardInfo.htDivision,
+      createdAt: undefined,
+      updatedAt: undefined,
+    }));
+
+    // 벌크 인서트
+    await db.insert(avlVendorInfo).values(recordsToInsert);
+
+    debugSuccess('프로젝트AVL → 선종별표준AVL 복사 완료', {
+      copiedCount: recordsToInsert.length,
+      targetStandardInfo,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('avl-lists');
+    revalidateTag('avl-vendor-info');
+
+    return {
+      success: true,
+      message: `${recordsToInsert.length}개의 항목이 선종별표준AVL로 복사되었습니다.`
+    };
+
+  } catch (error) {
+    debugError('프로젝트AVL → 선종별표준AVL 복사 실패', { error, selectedIds, targetStandardInfo });
+    return {
+      success: false,
+      message: "선종별표준AVL로 복사 중 오류가 발생했습니다."
+    };
+  }
+};
+
+/**
+ * 프로젝트AVL → 벤더풀로 복사
+ */
+export const copyToVendorPool = async (
+  selectedIds: number[],
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('프로젝트AVL → 벤더풀 복사 시작', { selectedIds });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (프로젝트AVL에서)
+    const selectedRecords = await db
+      .select()
+      .from(avlVendorInfo)
+      .where(
+        and(
+          eq(avlVendorInfo.isTemplate, false),
+          inArray(avlVendorInfo.id, selectedIds)
+        )
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // 벤더풀 테이블로 복사할 데이터 준비 (필드 매핑)
+    const recordsToInsert: NewVendorPool[] = selectedRecords.map(record => ({
+      // 기본 정보 (프로젝트 AVL에서 추출 또는 기본값 설정)
+      constructionSector: record.constructionSector || "조선", // 기본값 설정
+      htDivision: record.htDivision || "H", // 기본값 설정
+
+      // 설계 정보
+      designCategoryCode: "XX", // 기본값 (실제로는 적절한 값으로 매핑 필요)
+      designCategory: record.disciplineName || "기타",
+      equipBulkDivision: record.equipBulkDivision || "E",
+
+      // 패키지 정보
+      packageCode: record.packageCode,
+      packageName: record.packageName,
+
+      // 자재그룹 정보
+      materialGroupCode: record.materialGroupCode,
+      materialGroupName: record.materialGroupName,
+
+      // 자재 관련 정보 (빈 값으로 설정)
+      smCode: null,
+      similarMaterialNamePurchase: null,
+      similarMaterialNameOther: null,
+
+      // 협력업체 정보
+      vendorCode: record.vendorCode,
+      vendorName: record.vendorName,
+
+      // 사업 및 인증 정보
+      taxId: null, // 벤더풀에서 별도 관리
+      faTarget: record.faTarget,
+      faStatus: record.faStatus,
+      faRemark: null,
+      tier: record.tier,
+      isAgent: record.isAgent,
+
+      // 계약 정보
+      contractSignerCode: record.contractSignerCode,
+      contractSignerName: record.contractSignerName,
+
+      // 위치 정보
+      headquarterLocation: null, // 별도 관리 필요
+      manufacturingLocation: null, // 별도 관리 필요
+
+      // AVL 관련 정보
+      avlVendorName: record.avlVendorName,
+      similarVendorName: null,
+      hasAvl: record.hasAvl,
+
+      // 상태 정보
+      isBlacklist: record.isBlacklist,
+      isBcc: record.isBcc,
+      purchaseOpinion: null,
+
+      // AVL 적용 선종 (기본값으로 설정 - 실제로는 로직 필요)
+      shipTypeCommon: true, // 공통으로 설정
+      shipTypeAmax: false,
+      shipTypeSmax: false,
+      shipTypeVlcc: false,
+      shipTypeLngc: false,
+      shipTypeCont: false,
+
+      // AVL 적용 선종(해양) - 기본값
+      offshoreTypeCommon: false,
+      offshoreTypeFpso: false,
+      offshoreTypeFlng: false,
+      offshoreTypeFpu: false,
+      offshoreTypePlatform: false,
+      offshoreTypeWtiv: false,
+      offshoreTypeGom: false,
+
+      // eVCP 미등록 정보 - 빈 값
+      picName: null,
+      picEmail: null,
+      picPhone: null,
+      agentName: null,
+      agentEmail: null,
+      agentPhone: null,
+
+      // 업체 실적 현황
+      recentQuoteDate: record.recentQuoteDate,
+      recentQuoteNumber: record.recentQuoteNumber,
+      recentOrderDate: record.recentOrderDate,
+      recentOrderNumber: record.recentOrderNumber,
+
+      // 업데이트 히스토리
+      registrationDate: undefined, // 현재 시간으로 자동 설정
+      registrant: userName,
+      lastModifiedDate: undefined,
+      lastModifier: userName,
+    }));
+
+    // 입력 데이터에서 중복 제거 (메모리에서 처리)
+    const seen = new Set<string>();
+    const uniqueRecords = recordsToInsert.filter(record => {
+      if (!record.vendorCode || !record.materialGroupCode) return true; // 필수 필드가 없는 경우는 추가
+      const key = `${record.vendorCode}:${record.materialGroupCode}`;
+      if (seen.has(key)) return false;
+      seen.add(key);
+      return true;
+    });
+
+    // 중복 제거된 레코드 수 계산
+    const duplicateCount = recordsToInsert.length - uniqueRecords.length;
+
+    if (uniqueRecords.length === 0) {
+      return { success: false, message: "복사할 유효한 항목이 없습니다." };
+    }
+
+    // 벌크 인서트
+    await db.insert(vendorPool).values(uniqueRecords);
+
+    debugSuccess('프로젝트AVL → 벤더풀 복사 완료', {
+      copiedCount: uniqueRecords.length,
+      duplicateCount,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('vendor-pool');
+    revalidateTag('vendor-pool-list');
+    revalidateTag('vendor-pool-stats');
+
+    return {
+      success: true,
+      message: `${uniqueRecords.length}개의 항목이 벤더풀로 복사되었습니다.${duplicateCount > 0 ? ` (${duplicateCount}개 입력 데이터 중복 제외)` : ''}`
+    };
+
+  } catch (error) {
+    debugError('프로젝트AVL → 벤더풀 복사 실패', { error, selectedIds });
+    return {
+      success: false,
+      message: "벤더풀로 복사 중 오류가 발생했습니다."
+    };
+  }
+};
+
+/**
+ * 벤더풀 → 프로젝트AVL로 복사
+ */
+export const copyFromVendorPoolToProjectAvl = async (
+  selectedIds: number[],
+  targetProjectCode: string,
+  targetAvlListId: number,
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('벤더풀 → 프로젝트AVL 복사 시작', { selectedIds, targetProjectCode, targetAvlListId });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (벤더풀에서)
+    const selectedRecords = await db
+      .select()
+      .from(vendorPool)
+      .where(
+        inArray(vendorPool.id, selectedIds)
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // 벤더풀 데이터를 AVL Vendor Info로 변환하여 복사
+    const recordsToInsert: NewAvlVendorInfo[] = selectedRecords.map(record => ({
+      // 프로젝트 AVL용 필드들
+      projectCode: targetProjectCode,
+      avlListId: targetAvlListId,
+      isTemplate: false,
+
+      // 벤더풀 데이터를 AVL Vendor Info로 매핑
+      vendorId: null, // 벤더풀에서는 vendorId가 없을 수 있음
+      vendorName: record.vendorName,
+      vendorCode: record.vendorCode,
+
+      // 기본 정보 (벤더풀의 데이터 활용)
+      constructionSector: record.constructionSector,
+      htDivision: record.htDivision,
+
+      // 자재그룹 정보
+      materialGroupCode: record.materialGroupCode,
+      materialGroupName: record.materialGroupName,
+
+      // 설계 정보 (벤더풀의 데이터 활용)
+      designCategory: record.designCategory,
+      equipBulkDivision: record.equipBulkDivision,
+
+      // 패키지 정보
+      packageCode: record.packageCode,
+      packageName: record.packageName,
+
+      // 계약 정보
+      contractSignerCode: record.contractSignerCode,
+      contractSignerName: record.contractSignerName,
+
+      // 위치 정보
+      headquarterLocation: record.headquarterLocation,
+      manufacturingLocation: record.manufacturingLocation,
+
+      // AVL 관련 정보
+      avlVendorName: record.avlVendorName,
+      hasAvl: record.hasAvl,
+
+      // 상태 정보
+      isBlacklist: record.isBlacklist,
+      isBcc: record.isBcc,
+
+      // 기본값들
+      ownerSuggestion: false,
+      shiSuggestion: false,
+      faTarget: record.faTarget,
+      faStatus: record.faStatus,
+      isAgent: record.isAgent,
+
+      // 나머지 필드들은 null 또는 기본값
+      disciplineCode: null,
+      disciplineName: null,
+      materialNameCustomerSide: null,
+      tier: record.tier,
+      filters: [],
+      joinOperator: "and",
+      search: "",
+
+      createdAt: undefined,
+      updatedAt: undefined,
+    }));
+
+    // 벌크 인서트
+    await db.insert(avlVendorInfo).values(recordsToInsert);
+
+    debugSuccess('벤더풀 → 프로젝트AVL 복사 완료', {
+      copiedCount: recordsToInsert.length,
+      targetProjectCode,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('avl-lists');
+    revalidateTag('avl-vendor-info');
+
+    return {
+      success: true,
+      message: `${recordsToInsert.length}개의 항목이 프로젝트 AVL로 복사되었습니다.`
+    };
+
+  } catch (error) {
+    debugError('벤더풀 → 프로젝트AVL 복사 실패', { error, selectedIds, targetProjectCode });
+    return {
+      success: false,
+      message: "프로젝트 AVL로 복사 중 오류가 발생했습니다."
+    };
+  }
+};
+
+/**
+ * 벤더풀 → 선종별표준AVL로 복사
+ */
+export const copyFromVendorPoolToStandardAvl = async (
+  selectedIds: number[],
+  targetStandardInfo: {
+    constructionSector: string;
+    shipType: string;
+    avlKind: string;
+    htDivision: string;
+  },
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('벤더풀 → 선종별표준AVL 복사 시작', { selectedIds, targetStandardInfo });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (벤더풀에서)
+    const selectedRecords = await db
+      .select()
+      .from(vendorPool)
+      .where(
+        inArray(vendorPool.id, selectedIds)
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // 벤더풀 데이터를 AVL Vendor Info로 변환하여 복사
+    const recordsToInsert: NewAvlVendorInfo[] = selectedRecords.map(record => ({
+      // 선종별 표준 AVL용 필드들
+      isTemplate: true,
+      constructionSector: targetStandardInfo.constructionSector,
+      shipType: targetStandardInfo.shipType,
+      avlKind: targetStandardInfo.avlKind,
+      htDivision: targetStandardInfo.htDivision,
+
+      // 벤더풀 데이터를 AVL Vendor Info로 매핑
+      vendorId: null,
+      vendorName: record.vendorName,
+      vendorCode: record.vendorCode,
+
+      // 자재그룹 정보
+      materialGroupCode: record.materialGroupCode,
+      materialGroupName: record.materialGroupName,
+
+      // 설계 정보
+      disciplineName: record.designCategory,
+      equipBulkDivision: record.equipBulkDivision,
+
+      // 패키지 정보
+      packageCode: record.packageCode,
+      packageName: record.packageName,
+
+      // 계약 정보
+      contractSignerCode: record.contractSignerCode,
+      contractSignerName: record.contractSignerName,
+
+      // 위치 정보
+      headquarterLocation: record.headquarterLocation,
+      manufacturingLocation: record.manufacturingLocation,
+
+      // AVL 관련 정보
+      avlVendorName: record.avlVendorName,
+      hasAvl: record.hasAvl,
+
+      // 상태 정보
+      isBlacklist: record.isBlacklist,
+      isBcc: record.isBcc,
+
+      // 기본값들
+      ownerSuggestion: false,
+      shiSuggestion: false,
+      faTarget: record.faTarget,
+      faStatus: record.faStatus,
+      isAgent: record.isAgent,
+
+      // 선종별 표준 AVL에서는 사용하지 않는 필드들
+      projectCode: null,
+      avlListId: null,
+
+      // 나머지 필드들은 null 또는 기본값
+      disciplineCode: null,
+      materialNameCustomerSide: null,
+      tier: record.tier,
+      filters: [],
+      joinOperator: "and",
+      search: "",
+
+      createdAt: undefined,
+      updatedAt: undefined,
+    }));
+
+    // 벌크 인서트
+    await db.insert(avlVendorInfo).values(recordsToInsert);
+
+    debugSuccess('벤더풀 → 선종별표준AVL 복사 완료', {
+      copiedCount: recordsToInsert.length,
+      targetStandardInfo,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('avl-lists');
+    revalidateTag('avl-vendor-info');
+
+    return {
+      success: true,
+      message: `${recordsToInsert.length}개의 항목이 선종별표준AVL로 복사되었습니다.`
+    };
+
+  } catch (error) {
+    debugError('벤더풀 → 선종별표준AVL 복사 실패', { error, selectedIds, targetStandardInfo });
+    return {
+      success: false,
+      message: "선종별표준AVL로 복사 중 오류가 발생했습니다."
+    };
+  }
+};
+
+/**
+ * 선종별표준AVL → 벤더풀로 복사
+ */
+export const copyFromStandardAvlToVendorPool = async (
+  selectedIds: number[],
+  userName: string
+): Promise<ActionResult> => {
+  try {
+    debugLog('선종별표준AVL → 벤더풀 복사 시작', { selectedIds });
+
+    if (!selectedIds.length) {
+      return { success: false, message: "복사할 항목을 선택해주세요." };
+    }
+
+    // 선택된 레코드들 조회 (선종별표준AVL에서)
+    const selectedRecords = await db
+      .select()
+      .from(avlVendorInfo)
+      .where(
+        and(
+          eq(avlVendorInfo.isTemplate, true),
+          inArray(avlVendorInfo.id, selectedIds)
+        )
+      );
+
+    if (!selectedRecords.length) {
+      return { success: false, message: "선택된 항목을 찾을 수 없습니다." };
+    }
+
+    // AVL Vendor Info 데이터를 벤더풀로 변환하여 복사
+    const recordsToInsert: NewVendorPool[] = selectedRecords.map(record => ({
+      // 기본 정보
+      constructionSector: record.constructionSector || "조선",
+      htDivision: record.htDivision || "H",
+
+      // 설계 정보
+      designCategoryCode: "XX", // 기본값
+      designCategory: record.disciplineName || "기타",
+      equipBulkDivision: record.equipBulkDivision || "E",
+
+      // 패키지 정보
+      packageCode: record.packageCode,
+      packageName: record.packageName,
+
+      // 자재그룹 정보
+      materialGroupCode: record.materialGroupCode,
+      materialGroupName: record.materialGroupName,
+
+      // 협력업체 정보
+      vendorCode: record.vendorCode,
+      vendorName: record.vendorName,
+
+      // 사업 및 인증 정보
+      taxId: null,
+      faTarget: record.faTarget,
+      faStatus: record.faStatus,
+      faRemark: null,
+      tier: record.tier,
+      isAgent: record.isAgent,
+
+      // 계약 정보
+      contractSignerCode: record.contractSignerCode,
+      contractSignerName: record.contractSignerName,
+
+      // 위치 정보
+      headquarterLocation: record.headquarterLocation,
+      manufacturingLocation: record.manufacturingLocation,
+
+      // AVL 관련 정보
+      avlVendorName: record.avlVendorName,
+      similarVendorName: null,
+      hasAvl: record.hasAvl,
+
+      // 상태 정보
+      isBlacklist: record.isBlacklist,
+      isBcc: record.isBcc,
+      purchaseOpinion: null,
+
+      // AVL 적용 선종 (기본값)
+      shipTypeCommon: true,
+      shipTypeAmax: false,
+      shipTypeSmax: false,
+      shipTypeVlcc: false,
+      shipTypeLngc: false,
+      shipTypeCont: false,
+
+      // AVL 적용 선종(해양) - 기본값
+      offshoreTypeCommon: false,
+      offshoreTypeFpso: false,
+      offshoreTypeFlng: false,
+      offshoreTypeFpu: false,
+      offshoreTypePlatform: false,
+      offshoreTypeWtiv: false,
+      offshoreTypeGom: false,
+
+      // eVCP 미등록 정보
+      picName: null,
+      picEmail: null,
+      picPhone: null,
+      agentName: null,
+      agentEmail: null,
+      agentPhone: null,
+
+      // 업체 실적 현황
+      recentQuoteDate: record.recentQuoteDate,
+      recentQuoteNumber: record.recentQuoteNumber,
+      recentOrderDate: record.recentOrderDate,
+      recentOrderNumber: record.recentOrderNumber,
+
+      // 업데이트 히스토리
+      registrationDate: undefined,
+      registrant: userName,
+      lastModifiedDate: undefined,
+      lastModifier: userName,
+    }));
+
+    // 중복 체크를 위한 고유한 vendorCode + materialGroupCode 조합 생성
+    const uniquePairs = new Set<string>();
+    const validRecords = recordsToInsert.filter(record => {
+      if (!record.vendorCode || !record.materialGroupCode) return false;
+      const key = `${record.vendorCode}:${record.materialGroupCode}`;
+      if (uniquePairs.has(key)) return false;
+      uniquePairs.add(key);
+      return true;
+    });
+
+    if (validRecords.length === 0) {
+      return { success: false, message: "복사할 유효한 항목이 없습니다." };
+    }
+
+    // 벌크 인서트
+    await db.insert(vendorPool).values(validRecords);
+
+    const duplicateCount = recordsToInsert.length - validRecords.length;
+
+    debugSuccess('선종별표준AVL → 벤더풀 복사 완료', {
+      copiedCount: validRecords.length,
+      duplicateCount,
+      userName
+    });
+
+    // 캐시 무효화
+    revalidateTag('vendor-pool');
+
+    return {
+      success: true,
+      message: `${validRecords.length}개의 항목이 벤더풀로 복사되었습니다.${duplicateCount > 0 ? ` (${duplicateCount}개 입력 데이터 중복 제외)` : ''}`
+    };
+
+  } catch (error) {
+    debugError('선종별표준AVL → 벤더풀 복사 실패', { error, selectedIds });
+    return {
+      success: false,
+      message: "벤더풀로 복사 중 오류가 발생했습니다."
+    };
+  }
+};
+
+/**
+ * 표준 AVL 최종 확정
+ * 표준 AVL을 최종 확정하여 AVL 리스트에 등록합니다.
+ */
+export async function finalizeStandardAvl(
+  standardAvlInfo: {
+    constructionSector: string;
+    shipType: string;
+    avlKind: string;
+    htDivision: string;
+  },
+  avlVendorInfoIds: number[],
+  currentUser?: string
+): Promise<{ success: boolean; avlListId?: number; message: string }> {
+  try {
+    debugLog('표준 AVL 최종 확정 시작', { 
+      standardAvlInfo, 
+      avlVendorInfoIds: avlVendorInfoIds.length,
+      currentUser 
+    });
+
+    // 1. 기존 표준 AVL 리스트의 최고 revision 확인
+    const existingAvlLists = await db
+      .select({ rev: avlList.rev })
+      .from(avlList)
+      .where(and(
+        eq(avlList.constructionSector, standardAvlInfo.constructionSector),
+        eq(avlList.shipType, standardAvlInfo.shipType),
+        eq(avlList.avlKind, standardAvlInfo.avlKind),
+        eq(avlList.htDivision, standardAvlInfo.htDivision),
+        eq(avlList.isTemplate, true)
+      ))
+      .orderBy(desc(avlList.rev))
+      .limit(1);
+
+    const nextRevision = existingAvlLists.length > 0 ? (existingAvlLists[0].rev || 0) + 1 : 1;
+
+    debugLog('표준 AVL 리스트 revision 계산', {
+      standardAvlInfo,
+      existingRevision: existingAvlLists.length > 0 ? existingAvlLists[0].rev : 0,
+      nextRevision
+    });
+
+    // 2. AVL 리스트 생성을 위한 데이터 준비
+    const createAvlListData: CreateAvlListInput = {
+      isTemplate: true, // 표준 AVL이므로 true
+      constructionSector: standardAvlInfo.constructionSector,
+      projectCode: null, // 표준 AVL은 프로젝트 코드가 없음
+      shipType: standardAvlInfo.shipType,
+      avlKind: standardAvlInfo.avlKind,
+      htDivision: standardAvlInfo.htDivision,
+      rev: nextRevision, // 계산된 다음 리비전
+      createdBy: currentUser || 'system',
+      updatedBy: currentUser || 'system',
+    };
+
+    debugLog('표준 AVL 리스트 생성 데이터', { createAvlListData });
+
+    // 2-1. AVL Vendor Info 스냅샷 생성 (AVL 리스트 생성 전에 현재 상태 저장)
+    debugLog('표준 AVL Vendor Info 스냅샷 생성 시작', { 
+      vendorInfoIdsCount: avlVendorInfoIds.length,
+      vendorInfoIds: avlVendorInfoIds 
+    });
+    const vendorInfoSnapshot = await createVendorInfoSnapshot(avlVendorInfoIds);
+    debugSuccess('표준 AVL Vendor Info 스냅샷 생성 완료', { 
+      snapshotCount: vendorInfoSnapshot.length,
+      snapshotSize: JSON.stringify(vendorInfoSnapshot).length,
+      sampleSnapshot: vendorInfoSnapshot.slice(0, 1) // 첫 번째 항목만 로깅
+    });
+
+    // 스냅샷을 AVL 리스트 생성 데이터에 추가
+    createAvlListData.vendorInfoSnapshot = vendorInfoSnapshot;
+    debugLog('표준 AVL 스냅샷이 createAvlListData에 추가됨', { 
+      hasSnapshot: !!createAvlListData.vendorInfoSnapshot,
+      snapshotLength: createAvlListData.vendorInfoSnapshot?.length 
+    });
+
+    // 3. AVL 리스트 생성
+    const newAvlList = await createAvlList(createAvlListData);
+    
+    if (!newAvlList) {
+      throw new Error("표준 AVL 리스트 생성에 실패했습니다.");
+    }
+
+    debugSuccess('표준 AVL 리스트 생성 완료', { avlListId: newAvlList.id });
+
+    // 4. avlVendorInfo 레코드들의 avlListId 업데이트
+    if (avlVendorInfoIds.length > 0) {
+      debugLog('표준 AVL Vendor Info 업데이트 시작', { 
+        count: avlVendorInfoIds.length, 
+        newAvlListId: newAvlList.id 
+      });
+
+      const updateResults = await Promise.all(
+        avlVendorInfoIds.map(async (vendorInfoId) => {
+          try {
+            const result = await db
+              .update(avlVendorInfo)
+              .set({ 
+                avlListId: newAvlList.id,
+                updatedAt: new Date()
+              })
+              .where(eq(avlVendorInfo.id, vendorInfoId))
+              .returning({ id: avlVendorInfo.id });
+
+            return { id: vendorInfoId, success: true, result };
+          } catch (error) {
+            debugError('표준 AVL Vendor Info 업데이트 실패', { vendorInfoId, error });
+            return { id: vendorInfoId, success: false, error };
+          }
+        })
+      );
+
+      // 업데이트 결과 검증
+      const successCount = updateResults.filter(r => r.success).length;
+      const failCount = updateResults.filter(r => !r.success).length;
+
+      debugLog('표준 AVL Vendor Info 업데이트 결과', { 
+        total: avlVendorInfoIds.length,
+        success: successCount,
+        failed: failCount
+      });
+
+      if (failCount > 0) {
+        debugWarn('일부 표준 AVL Vendor Info 업데이트 실패', { 
+          failedIds: updateResults.filter(r => !r.success).map(r => r.id)
+        });
+      }
+    }
+
+    // 5. 캐시 무효화
+    revalidateTag('avl-list');
+    revalidateTag('avl-vendor-info');
+
+    debugSuccess('표준 AVL 최종 확정 완료', { 
+      avlListId: newAvlList.id,
+      standardAvlInfo,
+      vendorInfoCount: avlVendorInfoIds.length
+    });
+
+    return {
+      success: true,
+      avlListId: newAvlList.id,
+      message: `표준 AVL이 성공적으로 확정되었습니다. (AVL ID: ${newAvlList.id}, 벤더 정보: ${avlVendorInfoIds.length}개)`
+    };
+
+  } catch (err) {
+    debugError('표준 AVL 최종 확정 실패', { 
+      standardAvlInfo, 
+      error: err 
+    });
+
+    console.error("Error in finalizeStandardAvl:", err);
+    
+    return {
+      success: false,
+      message: err instanceof Error ? err.message : "표준 AVL 최종 확정 중 오류가 발생했습니다."
+    };
+  }
+}
diff --git a/lib/avl/snapshot-utils.ts b/lib/avl/snapshot-utils.ts
new file mode 100644
index 00000000..0f5d9240
--- /dev/null
+++ b/lib/avl/snapshot-utils.ts
@@ -0,0 +1,190 @@
+/**
+ * AVL Vendor Info 스냅샷 관련 유틸리티 함수들
+ */
+
+import db from "@/db/db"
+import { avlVendorInfo } from "@/db/schema/avl/avl"
+import { inArray } from "drizzle-orm"
+
+/**
+ * AVL Vendor Info 스냅샷 데이터 타입
+ */
+export interface VendorInfoSnapshot {
+  id: number
+  // 설계 정보
+  equipBulkDivision: string | null
+  disciplineCode: string | null
+  disciplineName: string | null
+  // 자재 정보
+  materialNameCustomerSide: string | null
+  packageCode: string | null
+  packageName: string | null
+  materialGroupCode: string | null
+  materialGroupName: string | null
+  // 협력업체 정보
+  vendorId: number | null
+  vendorName: string | null
+  vendorCode: string | null
+  avlVendorName: string | null
+  tier: string | null
+  // FA 정보
+  faTarget: boolean
+  faStatus: string | null
+  // Agent 정보
+  isAgent: boolean
+  // 계약 서명주체
+  contractSignerId: number | null
+  contractSignerName: string | null
+  contractSignerCode: string | null
+  // 위치 정보
+  headquarterLocation: string | null
+  manufacturingLocation: string | null
+  // SHI Qualification
+  hasAvl: boolean
+  isBlacklist: boolean
+  isBcc: boolean
+  // 기술영업 견적결과
+  techQuoteNumber: string | null
+  quoteCode: string | null
+  quoteVendorId: number | null
+  quoteVendorName: string | null
+  quoteVendorCode: string | null
+  quoteCountry: string | null
+  quoteTotalAmount: string | null // 숫자를 문자열로 변환
+  quoteReceivedDate: string | null
+  // 업체 실적 현황
+  recentQuoteDate: string | null
+  recentQuoteNumber: string | null
+  recentOrderDate: string | null
+  recentOrderNumber: string | null
+  // 기타
+  remark: string | null
+  // 타임스탬프
+  createdAt: string
+  updatedAt: string
+}
+
+/**
+ * AVL Vendor Info ID 목록으로부터 스냅샷 데이터를 생성합니다.
+ * 
+ * @param vendorInfoIds - 스냅샷을 생성할 AVL Vendor Info ID 목록
+ * @returns 스냅샷 데이터 배열
+ */
+export async function createVendorInfoSnapshot(vendorInfoIds: number[]): Promise<VendorInfoSnapshot[]> {
+  if (vendorInfoIds.length === 0) {
+    console.log('[SNAPSHOT] 빈 vendorInfoIds 배열, 빈 스냅샷 반환')
+    return []
+  }
+
+  try {
+    console.log('[SNAPSHOT] 스냅샷 생성 시작', { vendorInfoIds, count: vendorInfoIds.length })
+    
+    // AVL Vendor Info 데이터 조회
+    const vendorInfoList = await db
+      .select()
+      .from(avlVendorInfo)
+      .where(inArray(avlVendorInfo.id, vendorInfoIds))
+
+    console.log('[SNAPSHOT] DB 조회 완료', { 
+      requestedIds: vendorInfoIds,
+      foundCount: vendorInfoList.length,
+      foundIds: vendorInfoList.map(v => v.id)
+    })
+
+    // 스냅샷 데이터로 변환
+    const snapshot: VendorInfoSnapshot[] = vendorInfoList.map(info => ({
+      id: info.id,
+      // 설계 정보
+      equipBulkDivision: info.equipBulkDivision,
+      disciplineCode: info.disciplineCode,
+      disciplineName: info.disciplineName,
+      // 자재 정보
+      materialNameCustomerSide: info.materialNameCustomerSide,
+      packageCode: info.packageCode,
+      packageName: info.packageName,
+      materialGroupCode: info.materialGroupCode,
+      materialGroupName: info.materialGroupName,
+      // 협력업체 정보
+      vendorId: info.vendorId,
+      vendorName: info.vendorName,
+      vendorCode: info.vendorCode,
+      avlVendorName: info.avlVendorName,
+      tier: info.tier,
+      // FA 정보
+      faTarget: info.faTarget ?? false,
+      faStatus: info.faStatus,
+      // Agent 정보
+      isAgent: info.isAgent ?? false,
+      // 계약 서명주체
+      contractSignerId: info.contractSignerId,
+      contractSignerName: info.contractSignerName,
+      contractSignerCode: info.contractSignerCode,
+      // 위치 정보
+      headquarterLocation: info.headquarterLocation,
+      manufacturingLocation: info.manufacturingLocation,
+      // SHI Qualification
+      hasAvl: info.hasAvl ?? false,
+      isBlacklist: info.isBlacklist ?? false,
+      isBcc: info.isBcc ?? false,
+      // 기술영업 견적결과
+      techQuoteNumber: info.techQuoteNumber,
+      quoteCode: info.quoteCode,
+      quoteVendorId: info.quoteVendorId,
+      quoteVendorName: info.quoteVendorName,
+      quoteVendorCode: info.quoteVendorCode,
+      quoteCountry: info.quoteCountry,
+      quoteTotalAmount: info.quoteTotalAmount?.toString() || null,
+      quoteReceivedDate: info.quoteReceivedDate,
+      // 업체 실적 현황
+      recentQuoteDate: info.recentQuoteDate,
+      recentQuoteNumber: info.recentQuoteNumber,
+      recentOrderDate: info.recentOrderDate,
+      recentOrderNumber: info.recentOrderNumber,
+      // 기타
+      remark: info.remark,
+      // 타임스탬프 (ISO 문자열로 변환)
+      createdAt: info.createdAt?.toISOString() || new Date().toISOString(),
+      updatedAt: info.updatedAt?.toISOString() || new Date().toISOString(),
+    }))
+
+    console.log('[SNAPSHOT] 스냅샷 변환 완료', { 
+      snapshotCount: snapshot.length,
+      sampleData: snapshot.slice(0, 2) // 처음 2개 항목만 로깅
+    })
+
+    return snapshot
+
+  } catch (error) {
+    console.error('[SNAPSHOT] Vendor Info 스냅샷 생성 실패:', error)
+    throw new Error('Vendor Info 스냅샷 생성 중 오류가 발생했습니다.')
+  }
+}
+
+/**
+ * 스냅샷 데이터의 통계 정보를 생성합니다.
+ * 
+ * @param snapshot - 스냅샷 데이터 배열
+ * @returns 통계 정보 객체
+ */
+export function getSnapshotStatistics(snapshot: VendorInfoSnapshot[]) {
+  return {
+    totalCount: snapshot.length,
+    avlCount: snapshot.filter(item => item.hasAvl).length,
+    blacklistCount: snapshot.filter(item => item.isBlacklist).length,
+    bccCount: snapshot.filter(item => item.isBcc).length,
+    faTargetCount: snapshot.filter(item => item.faTarget).length,
+    agentCount: snapshot.filter(item => item.isAgent).length,
+    tierDistribution: {
+      'Tier 1': snapshot.filter(item => item.tier === 'Tier 1').length,
+      'Tier 2': snapshot.filter(item => item.tier === 'Tier 2').length,
+      'Tier 3': snapshot.filter(item => item.tier === 'Tier 3').length,
+      'Other': snapshot.filter(item => item.tier && !['Tier 1', 'Tier 2', 'Tier 3'].includes(item.tier)).length,
+      'Unspecified': snapshot.filter(item => !item.tier).length,
+    },
+    byDiscipline: snapshot.reduce((acc, item) => {
+      const discipline = item.disciplineName || 'Unknown'
+      acc[discipline] = (acc[discipline] || 0) + 1
+      return acc
+    }, {} as Record<string, number>),
+  }
+}
diff --git a/lib/avl/table/avl-detail-table.tsx b/lib/avl/table/avl-detail-table.tsx
index ba15c6ef..04384ec8 100644
--- a/lib/avl/table/avl-detail-table.tsx
+++ b/lib/avl/table/avl-detail-table.tsx
@@ -5,31 +5,13 @@ import * as React from "react"
 import { useDataTable } from "@/hooks/use-data-table"
 import { DataTable } from "@/components/data-table/data-table"
 import { Button } from "@/components/ui/button"
-import { Input } from "@/components/ui/input"
 import { toast } from "sonner"
 
 import { columns, type AvlDetailItem } from "./columns-detail"
-import { createAvlVendorInfo, updateAvlVendorInfo, deleteAvlVendorInfo, handleAvlAction } from "../service"
-import type { AvlDetailItem as AvlDetailType } from "../types"
-
-// 테이블 메타 타입 확장
-declare module "@tanstack/react-table" {
-  interface TableMeta<TData> {
-    onCellUpdate?: (id: string, field: keyof TData, newValue: any) => Promise<void>
-    onCellCancel?: (id: string, field: keyof TData) => void
-    onAction?: (action: string, data?: any) => void
-    onSaveEmptyRow?: (tempId: string) => Promise<void>
-    onCancelEmptyRow?: (tempId: string) => void
-    isEmptyRow?: (id: string) => boolean
-    getPendingChanges?: () => Record<string, Partial<AvlDetailItem>>
-  }
-}
 
 interface AvlDetailTableProps {
   data: AvlDetailItem[]
   pageCount?: number
-  avlListId: number // 상위 AVL 리스트 ID
-  onRefresh?: () => void // 데이터 새로고침 콜백
   avlType?: '프로젝트AVL' | '선종별표준AVL' // AVL 타입
   projectCode?: string // 프로젝트 코드
   shipOwnerName?: string // 선주명
@@ -39,386 +21,61 @@ interface AvlDetailTableProps {
 export function AvlDetailTable({
   data,
   pageCount,
-  avlListId,
-  onRefresh,
   avlType = '프로젝트AVL',
   projectCode,
   shipOwnerName,
   businessType = '조선'
 }: AvlDetailTableProps) {
-  // 수정사항 추적 (일괄 저장용)
-  const [pendingChanges, setPendingChanges] = React.useState<Record<string, Partial<AvlDetailItem>>>({})
-  const [isSaving, setIsSaving] = React.useState(false)
-
-  // 빈 행 관리 (신규 등록용)
-  const [emptyRows, setEmptyRows] = React.useState<Record<string, AvlDetailItem>>({})
-  const [isCreating, setIsCreating] = React.useState(false)
-
-  // 검색 상태
-  const [searchValue, setSearchValue] = React.useState("")
-
-
-  // 인라인 편집 핸들러 (일괄 저장용)
-  const handleCellUpdate = React.useCallback(async (id: string, field: keyof AvlDetailItem, newValue: any) => {
-    const isEmptyRow = String(id).startsWith('temp-')
-
-    if (isEmptyRow) {
-      // 빈 행의 경우 emptyRows 상태도 업데이트
-      setEmptyRows(prev => ({
-        ...prev,
-        [id]: {
-          ...prev[id],
-          [field]: newValue
-        }
-      }))
-    }
-
-    // pendingChanges에 변경사항 저장 (실시간 표시용)
-    setPendingChanges(prev => ({
-      ...prev,
-      [id]: {
-        ...prev[id],
-        [field]: newValue
-      }
-    }))
-  }, [])
-
-  // 편집 취소 핸들러
-  const handleCellCancel = React.useCallback((id: string, field: keyof AvlDetailItem) => {
-    const isEmptyRow = String(id).startsWith('temp-')
-
-    if (isEmptyRow) {
-      // 빈 행의 경우 emptyRows와 pendingChanges 모두 취소
-      setEmptyRows(prev => ({
-        ...prev,
-        [id]: {
-          ...prev[id],
-          [field]: prev[id][field] // 원래 값으로 복원 (pendingChanges의 초기값 사용)
-        }
-      }))
-
-      setPendingChanges(prev => {
-        const itemChanges = { ...prev[id] }
-        delete itemChanges[field]
-
-        if (Object.keys(itemChanges).length === 0) {
-          const newChanges = { ...prev }
-          delete newChanges[id]
-          return newChanges
-        }
-
-        return {
-          ...prev,
-          [id]: itemChanges
-        }
-      })
-    }
-  }, [])
-
   // 액션 핸들러
-  const handleAction = React.useCallback(async (action: string, data?: any) => {
-    try {
-      switch (action) {
-        case 'new-vendor':
-          // 신규 협력업체 추가 - 빈 행 추가
-          const tempId = `temp-${Date.now()}`
-          const newEmptyRow: AvlDetailItem = {
-            id: tempId,
-            no: 0,
-            selected: false,
-            avlListId: avlListId,
-            equipBulkDivision: "EQUIP",
-            disciplineCode: "",
-            disciplineName: "",
-            materialNameCustomerSide: "",
-            packageCode: "",
-            packageName: "",
-            materialGroupCode: "",
-            materialGroupName: "",
-            vendorId: undefined,
-            vendorName: "",
-            vendorCode: "",
-            avlVendorName: "",
-            tier: "",
-            faTarget: false,
-            faStatus: "",
-            isAgent: false,
-            agentStatus: "아니오",
-            contractSignerId: undefined,
-            contractSignerName: "",
-            contractSignerCode: "",
-            headquarterLocation: "",
-            manufacturingLocation: "",
-            shiAvl: false,
-            shiBlacklist: false,
-            shiBcc: false,
-            salesQuoteNumber: "",
-            quoteCode: "",
-            salesVendorInfo: "",
-            salesCountry: "",
-            totalAmount: "",
-            quoteReceivedDate: "",
-            recentQuoteDate: "",
-            recentQuoteNumber: "",
-            recentOrderDate: "",
-            recentOrderNumber: "",
-            remarks: "",
-            createdAt: new Date().toISOString().split('T')[0],
-            updatedAt: new Date().toISOString().split('T')[0],
-          }
-
-          setEmptyRows(prev => ({
-            ...prev,
-            [tempId]: newEmptyRow
-          }))
-          toast.success("신규 협력업체 행이 추가되었습니다.")
-          break
-
-        case 'bulk-import':
-          // 일괄 입력
-          const bulkResult = await handleAvlAction('bulk-import')
-          if (bulkResult.success) {
-            toast.success(bulkResult.message)
-          } else {
-            toast.error(bulkResult.message)
-          }
-          break
-
-        case 'save':
-          // 변경사항 저장
-          if (Object.keys(pendingChanges).length === 0) {
-            toast.info("저장할 변경사항이 없습니다.")
-            return
-          }
-
-          setIsSaving(true)
-          try {
-            // 각 변경사항을 순차적으로 저장
-            for (const [id, changes] of Object.entries(pendingChanges)) {
-              if (String(id).startsWith('temp-')) continue // 빈 행은 제외
-
-              const numericId = Number(id)
-              if (isNaN(numericId)) {
-                throw new Error(`유효하지 않은 ID: ${id}`)
-              }
-
-              const result = await updateAvlVendorInfo(numericId, changes)
-              if (!result) {
-                throw new Error(`항목 ${id} 저장 실패`)
-              }
-            }
-
-            setPendingChanges({})
-            toast.success("변경사항이 저장되었습니다.")
-            onRefresh?.()
-          } catch (error) {
-            console.error('저장 실패:', error)
-            toast.error("저장 중 오류가 발생했습니다.")
-          } finally {
-            setIsSaving(false)
-          }
-          break
-
-        case 'edit':
-          // 수정 모달 열기 (현재는 간단한 토스트로 처리)
-          toast.info(`${data?.id} 항목 수정`)
-          break
-
-        case 'delete':
-          // 삭제 확인 및 실행
-          if (!data?.id || String(data.id).startsWith('temp-')) return
-
-          const numericId = Number(data.id)
-          if (isNaN(numericId)) {
-            toast.error("유효하지 않은 항목 ID입니다.")
-            return
-          }
-
-          const confirmed = window.confirm(`항목 ${data.id}을(를) 삭제하시겠습니까?`)
-          if (!confirmed) return
-
-          try {
-            const result = await deleteAvlVendorInfo(numericId)
-            if (result) {
-              toast.success("항목이 삭제되었습니다.")
-              onRefresh?.()
-            } else {
-              toast.error("삭제에 실패했습니다.")
-            }
-          } catch (error) {
-            console.error('삭제 실패:', error)
-            toast.error("삭제 중 오류가 발생했습니다.")
-          }
-          break
-
-        case 'avl-form':
-          // AVL 양식 다운로드/보기
-          toast.info("AVL 양식을 준비 중입니다.")
-          // TODO: AVL 양식 다운로드 로직 구현
-          break
-
-        case 'quote-request':
-          // 견적 요청
-          toast.info("견적 요청을 처리 중입니다.")
-          // TODO: 견적 요청 로직 구현
-          break
-
-        case 'vendor-pool':
-          // Vendor Pool 관리
-          toast.info("Vendor Pool을 열고 있습니다.")
-          // TODO: Vendor Pool 페이지 이동 또는 모달 열기 로직 구현
-          break
-
-        case 'download':
-          // 데이터 다운로드
-          toast.info("데이터를 다운로드 중입니다.")
-          // TODO: 데이터 다운로드 로직 구현
-          break
-
-        default:
-          toast.error(`알 수 없는 액션: ${action}`)
-      }
-    } catch (error) {
-      console.error('액션 처리 실패:', error)
-      toast.error("액션 처리 중 오류가 발생했습니다.")
+  const handleAction = React.useCallback(async (action: string) => {
+    switch (action) {
+      case 'avl-form':
+        toast.info("AVL 양식을 준비 중입니다.")
+        // TODO: AVL 양식 다운로드 로직 구현
+        break
+
+      case 'quote-request':
+        toast.info("견적 요청을 처리 중입니다.")
+        // TODO: 견적 요청 로직 구현
+        break
+
+      case 'vendor-pool':
+        toast.info("Vendor Pool을 열고 있습니다.")
+        // TODO: Vendor Pool 페이지 이동 또는 모달 열기 로직 구현
+        break
+
+      case 'download':
+        toast.info("데이터를 다운로드 중입니다.")
+        // TODO: 데이터 다운로드 로직 구현
+        break
+
+      default:
+        toast.error(`알 수 없는 액션: ${action}`)
     }
-  }, [pendingChanges, onRefresh, avlListId])
-
-  // 빈 행 저장 핸들러
-  const handleSaveEmptyRow = React.useCallback(async (tempId: string) => {
-    const emptyRow = emptyRows[tempId]
-    if (!emptyRow) return
-
-    try {
-      setIsCreating(true)
-
-      // 필수 필드 검증
-      if (!emptyRow.disciplineName || !emptyRow.vendorName) {
-        toast.error("설계공종과 협력업체명은 필수 입력 항목입니다.")
-        return
-      }
-
-      // 빈 행 데이터를 생성 데이터로 변환
-      const createData = {
-        avlListId: emptyRow.avlListId,
-        equipBulkDivision: emptyRow.equipBulkDivision,
-        disciplineCode: emptyRow.disciplineCode || undefined,
-        disciplineName: emptyRow.disciplineName,
-        materialNameCustomerSide: emptyRow.materialNameCustomerSide || undefined,
-        packageCode: emptyRow.packageCode || undefined,
-        packageName: emptyRow.packageName || undefined,
-        materialGroupCode: emptyRow.materialGroupCode || undefined,
-        materialGroupName: emptyRow.materialGroupName || undefined,
-        vendorId: emptyRow.vendorId,
-        vendorName: emptyRow.vendorName,
-        vendorCode: emptyRow.vendorCode || undefined,
-        avlVendorName: emptyRow.avlVendorName || undefined,
-        tier: emptyRow.tier || undefined,
-        faTarget: emptyRow.faTarget ?? false,
-        faStatus: emptyRow.faStatus || undefined,
-        isAgent: emptyRow.isAgent ?? false,
-        contractSignerId: emptyRow.contractSignerId,
-        contractSignerName: emptyRow.contractSignerName || undefined,
-        contractSignerCode: emptyRow.contractSignerCode || undefined,
-        headquarterLocation: emptyRow.headquarterLocation || undefined,
-        manufacturingLocation: emptyRow.manufacturingLocation || undefined,
-        hasAvl: emptyRow.shiAvl ?? false,
-        isBlacklist: emptyRow.shiBlacklist ?? false,
-        isBcc: emptyRow.shiBcc ?? false,
-        techQuoteNumber: emptyRow.salesQuoteNumber || undefined,
-        quoteCode: emptyRow.quoteCode || undefined,
-        quoteVendorId: emptyRow.vendorId,
-        quoteVendorName: emptyRow.salesVendorInfo || undefined,
-        quoteVendorCode: emptyRow.vendorCode,
-        quoteCountry: emptyRow.salesCountry || undefined,
-        quoteTotalAmount: emptyRow.totalAmount ? parseFloat(emptyRow.totalAmount.replace(/,/g, '')) : undefined,
-        quoteReceivedDate: emptyRow.quoteReceivedDate || undefined,
-        recentQuoteDate: emptyRow.recentQuoteDate || undefined,
-        recentQuoteNumber: emptyRow.recentQuoteNumber || undefined,
-        recentOrderDate: emptyRow.recentOrderDate || undefined,
-        recentOrderNumber: emptyRow.recentOrderNumber || undefined,
-        remark: emptyRow.remarks || undefined,
-      }
-
-      const result = await createAvlVendorInfo(createData)
-      if (result) {
-        // 빈 행 제거 및 성공 메시지
-        setEmptyRows(prev => {
-          const newRows = { ...prev }
-          delete newRows[tempId]
-          return newRows
-        })
-
-        // pendingChanges에서도 제거
-        setPendingChanges(prev => {
-          const newChanges = { ...prev }
-          delete newChanges[tempId]
-          return newChanges
-        })
-
-        toast.success("새 협력업체가 등록되었습니다.")
-        onRefresh?.()
-      } else {
-        toast.error("등록에 실패했습니다.")
-      }
-    } catch (error) {
-      console.error('빈 행 저장 실패:', error)
-      toast.error("등록 중 오류가 발생했습니다.")
-    } finally {
-      setIsCreating(false)
-    }
-  }, [emptyRows, onRefresh])
-
-  // 빈 행 취소 핸들러
-  const handleCancelEmptyRow = React.useCallback((tempId: string) => {
-    setEmptyRows(prev => {
-      const newRows = { ...prev }
-      delete newRows[tempId]
-      return newRows
-    })
-
-    setPendingChanges(prev => {
-      const newChanges = { ...prev }
-      delete newChanges[tempId]
-      return newChanges
-    })
-
-    toast.info("등록이 취소되었습니다.")
   }, [])
 
-  // 빈 행 포함한 전체 데이터
-  const allData = React.useMemo(() => {
-    const emptyRowArray = Object.values(emptyRows)
-    return [...data, ...emptyRowArray]
-  }, [data, emptyRows])
 
-  // 테이블 메타 설정
+  // 테이블 메타 설정 (읽기 전용)
   const tableMeta = React.useMemo(() => ({
-    onCellUpdate: handleCellUpdate,
-    onCellCancel: handleCellCancel,
     onAction: handleAction,
-    onSaveEmptyRow: handleSaveEmptyRow,
-    onCancelEmptyRow: handleCancelEmptyRow,
-    isEmptyRow: (id: string) => String(id).startsWith('temp-'),
-    getPendingChanges: () => pendingChanges,
-  }), [handleCellUpdate, handleCellCancel, handleAction, handleSaveEmptyRow, handleCancelEmptyRow, pendingChanges])
+  }), [handleAction])
 
   // 데이터 테이블 설정
   const { table } = useDataTable({
-    data: allData,
+    data,
     columns,
-    pageCount,
+    pageCount: pageCount ?? 1,
     initialState: {
       sorting: [{ id: "no", desc: false }],
-      columnPinning: { right: ["actions"] },
+      pagination: {
+        pageIndex: 0,
+        pageSize: 10,
+      },
     },
     getRowId: (row) => String(row.id),
     meta: tableMeta,
   })
 
-  // 변경사항이 있는지 확인
-  const hasPendingChanges = Object.keys(pendingChanges).length > 0
-  const hasEmptyRows = Object.keys(emptyRows).length > 0
 
   return (
     <div className="space-y-4">
@@ -435,45 +92,25 @@ export function AvlDetailTable({
         </div>
       </div>
 
-      {/* 상단 버튼 및 검색 영역 */}
-      <div className="flex items-center justify-between gap-4">
-        <div className="flex items-center gap-2">
-          <Button variant="outline" size="sm" onClick={() => handleAction('avl-form')}>
-            AVL양식
-          </Button>
-          <Button variant="outline" size="sm" onClick={() => handleAction('quote-request')}>
-            견적요청
-          </Button>
-          <Button variant="outline" size="sm" onClick={() => handleAction('vendor-pool')}>
-            Vendor Pool
-          </Button>
-          <Button variant="outline" size="sm" onClick={() => handleAction('download')}>
-            다운로드
-          </Button>
-        </div>
-
-        <div className="flex items-center gap-2">
-          <div className="relative">
-            <Input
-              placeholder="검색..."
-              className="w-64"
-              value={searchValue}
-              onChange={(e) => setSearchValue(e.target.value)}
-            />
-          </div>
-        </div>
+      {/* 상단 버튼 영역 */}
+      <div className="flex items-center gap-2">
+        <Button variant="outline" size="sm" onClick={() => handleAction('avl-form')}>
+          AVL양식
+        </Button>
+        <Button variant="outline" size="sm" onClick={() => handleAction('quote-request')}>
+          견적요청
+        </Button>
+        <Button variant="outline" size="sm" onClick={() => handleAction('vendor-pool')}>
+          Vendor Pool
+        </Button>
+        <Button variant="outline" size="sm" onClick={() => handleAction('download')}>
+          다운로드
+        </Button>
       </div>
 
       {/* 데이터 테이블 */}
       <DataTable table={table} />
 
-      {/* 디버그 정보 (개발 환경에서만 표시) */}
-      {process.env.NODE_ENV === 'development' && (hasPendingChanges || hasEmptyRows) && (
-        <div className="text-xs text-muted-foreground p-2 bg-muted rounded">
-          <div>Pending Changes: {Object.keys(pendingChanges).length}</div>
-          <div>Empty Rows: {Object.keys(emptyRows).length}</div>
-        </div>
-      )}
     </div>
   )
 }
diff --git a/lib/avl/table/avl-registration-area.tsx b/lib/avl/table/avl-registration-area.tsx
index def3d30a..52912a2c 100644
--- a/lib/avl/table/avl-registration-area.tsx
+++ b/lib/avl/table/avl-registration-area.tsx
@@ -5,15 +5,27 @@ import { Card } from "@/components/ui/card"
 import { Button } from "@/components/ui/button"
 import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react"
 import { useAtom } from "jotai"
-import { ProjectAvlTable } from "./project-avl-table"
-import { StandardAvlTable } from "./standard-avl-table"
-import { VendorPoolTable } from "./vendor-pool-table"
+import { ProjectAvlTable, ProjectAvlTableRef } from "./project-avl-table"
+import { StandardAvlTable, StandardAvlTableRef } from "./standard-avl-table"
+import { VendorPoolTable, VendorPoolTableRef } from "./vendor-pool-table"
 import { selectedAvlRecordAtom } from "../avl-atoms"
-import type { AvlListItem } from "../types"
+import { copyToProjectAvl, copyToStandardAvl, copyToVendorPool, copyFromVendorPoolToProjectAvl, copyFromVendorPoolToStandardAvl, copyFromStandardAvlToVendorPool } from "../service"
+import { useSession } from "next-auth/react"
+import { toast } from "sonner"
 
 // 선택된 테이블 타입
 type SelectedTable = 'project' | 'standard' | 'vendor' | null
 
+// TODO: 나머지 테이블들도 ref 지원 추가 시 인터페이스 추가 필요
+// interface StandardAvlTableRef {
+//   getSelectedIds?: () => number[]
+// }
+//
+// interface VendorPoolTableRef {
+//   getSelectedIds?: () => number[]
+// }
+
+
 // 선택 상태 액션 타입
 type SelectionAction =
   | { type: 'SELECT_PROJECT'; count: number }
@@ -105,9 +117,13 @@ interface AvlRegistrationAreaProps {
 }
 
 export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaProps) {
+
   // 선택된 AVL 레코드 구독
   const [selectedAvlRecord] = useAtom(selectedAvlRecordAtom)
 
+  // 세션 정보
+  const { data: session } = useSession()
+
   // 단일 선택 상태 관리 (useReducer 사용)
   const [selectionState, dispatch] = React.useReducer(selectionReducer, {
     selectedTable: null,
@@ -121,10 +137,12 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
 
   // 선택 핸들러들
   const handleProjectSelection = React.useCallback((count: number) => {
+    console.log('handleProjectSelection called with count:', count)
     dispatch({ type: 'SELECT_PROJECT', count })
   }, [])
 
   const handleStandardSelection = React.useCallback((count: number) => {
+    console.log('handleStandardSelection called with count:', count)
     dispatch({ type: 'SELECT_STANDARD', count })
   }, [])
 
@@ -134,6 +152,8 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
 
   const { selectedTable, selectedRowCount, resetCounters } = selectionState
 
+  console.log('selectedTable', selectedTable);
+
   // 선택된 AVL에 따른 필터 값들
   const [currentProjectCode, setCurrentProjectCode] = React.useState<string>("")
   const constructionSector = selectedAvlRecord?.constructionSector || ""
@@ -142,6 +162,38 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
   const htDivision = selectedAvlRecord?.htDivision || ""
   const avlListId = selectedAvlRecord?.id ? String(selectedAvlRecord.id) : ""
 
+  // 선종별 표준 AVL 검색 조건 상태 (복사 버튼 활성화용)
+  const [standardSearchConditions, setStandardSearchConditions] = React.useState({
+    constructionSector: "",
+    shipType: "",
+    avlKind: "",
+    htDivision: ""
+  })
+
+  // 검색 조건이 모두 입력되었는지 확인
+  const isStandardSearchConditionsComplete = React.useMemo(() => {
+    return (
+      standardSearchConditions.constructionSector.trim() !== "" &&
+      standardSearchConditions.shipType.trim() !== "" &&
+      standardSearchConditions.avlKind.trim() !== "" &&
+      standardSearchConditions.htDivision.trim() !== ""
+    )
+  }, [standardSearchConditions])
+
+  // 벤더 풀 리로드 트리거
+  const [vendorPoolReloadTrigger, setVendorPoolReloadTrigger] = React.useState(0)
+
+  // 선종별 표준 AVL 리로드 트리거
+  const [standardAvlReloadTrigger, setStandardAvlReloadTrigger] = React.useState(0)
+
+  // 프로젝트 AVL 리로드 트리거
+  const [projectAvlReloadTrigger, setProjectAvlReloadTrigger] = React.useState(0)
+
+  // 테이블 ref들 (선택된 행 정보 가져오기용)
+  const projectTableRef = React.useRef<ProjectAvlTableRef>(null)
+  const standardTableRef = React.useRef<StandardAvlTableRef>(null)
+  const vendorTableRef = React.useRef<VendorPoolTableRef>(null)
+
   // 선택된 AVL 레코드가 변경될 때 프로젝트 코드 초기화
   React.useEffect(() => {
     setCurrentProjectCode(selectedAvlRecord?.projectCode || "")
@@ -152,6 +204,231 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
     setCurrentProjectCode(projectCode)
   }, [])
 
+  // 선택된 ID들을 가져오는 헬퍼 함수들
+  const getSelectedIds = React.useCallback((tableType: 'project' | 'standard' | 'vendor') => {
+    // 각 테이블 컴포넌트에서 선택된 행들의 ID를 가져오는 로직
+    switch (tableType) {
+      case 'project':
+        return projectTableRef.current?.getSelectedIds?.() || []
+      case 'standard':
+        return standardTableRef.current?.getSelectedIds?.() || []
+      case 'vendor':
+        return vendorTableRef.current?.getSelectedIds?.() || []
+      default:
+        return []
+    }
+  }, [])
+
+  // 복사 버튼 핸들러들
+  const handleCopyToProject = React.useCallback(async () => {
+    if (selectedTable !== 'standard' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('standard')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    if (!currentProjectCode) {
+      toast.error("프로젝트 코드가 설정되지 않았습니다.")
+      return
+    }
+
+    try {
+      const result = await copyToProjectAvl(
+        selectedIds,
+        currentProjectCode,
+        parseInt(avlListId) || 1,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('프로젝트AVL로 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, currentProjectCode, avlListId, session])
+
+  const handleCopyToStandard = React.useCallback(async () => {
+    if (selectedTable !== 'project' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('project')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    const targetStandardInfo = {
+      constructionSector: standardSearchConditions.constructionSector || "조선",
+      shipType: standardSearchConditions.shipType || "",
+      avlKind: standardSearchConditions.avlKind || "",
+      htDivision: standardSearchConditions.htDivision || "H"
+    }
+
+    try {
+      const result = await copyToStandardAvl(
+        selectedIds,
+        targetStandardInfo,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 선종별 표준 AVL 데이터 리로드
+        setStandardAvlReloadTrigger(prev => prev + 1)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('선종별표준AVL로 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, standardSearchConditions, session])
+
+  const handleCopyToVendorPool = React.useCallback(async () => {
+    if (selectedTable !== 'project' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('project')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    try {
+      const result = await copyToVendorPool(
+        selectedIds,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 벤더 풀 데이터 리로드
+        setVendorPoolReloadTrigger(prev => prev + 1)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('벤더풀로 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, session])
+
+  // 추가 복사 버튼 핸들러들
+  const handleCopyFromVendorToProject = React.useCallback(async () => {
+    if (selectedTable !== 'vendor' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('vendor')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    if (!currentProjectCode) {
+      toast.error("프로젝트 코드가 설정되지 않았습니다.")
+      return
+    }
+
+    try {
+      const result = await copyFromVendorPoolToProjectAvl(
+        selectedIds,
+        currentProjectCode,
+        parseInt(avlListId) || 1,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 프로젝트 AVL 리로드
+        setProjectAvlReloadTrigger(prev => prev + 1)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('벤더풀 → 프로젝트AVL 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, currentProjectCode, avlListId, session])
+
+  const handleCopyFromVendorToStandard = React.useCallback(async () => {
+    if (selectedTable !== 'vendor' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('vendor')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    const targetStandardInfo = {
+      constructionSector: standardSearchConditions.constructionSector || "조선",
+      shipType: standardSearchConditions.shipType || "",
+      avlKind: standardSearchConditions.avlKind || "",
+      htDivision: standardSearchConditions.htDivision || "H"
+    }
+
+    try {
+      const result = await copyFromVendorPoolToStandardAvl(
+        selectedIds,
+        targetStandardInfo,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 선종별 표준 AVL 리로드
+        setStandardAvlReloadTrigger(prev => prev + 1)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('벤더풀 → 선종별표준AVL 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, standardSearchConditions, session])
+
+  const handleCopyFromStandardToVendor = React.useCallback(async () => {
+    if (selectedTable !== 'standard' || selectedRowCount === 0) return
+
+    const selectedIds = getSelectedIds('standard')
+    if (!selectedIds.length) {
+      toast.error("복사할 항목을 선택해주세요.")
+      return
+    }
+
+    try {
+      const result = await copyFromStandardAvlToVendorPool(
+        selectedIds,
+        session?.user?.name || "unknown"
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        // 벤더 풀 리로드
+        setVendorPoolReloadTrigger(prev => prev + 1)
+        // 선택 해제
+        dispatch({ type: 'CLEAR_SELECTION' })
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error('선종별표준AVL → 벤더풀 복사 실패:', error)
+      toast.error("복사 중 오류가 발생했습니다.")
+    }
+  }, [selectedTable, selectedRowCount, getSelectedIds, session])
+
   return (
     <Card className={`h-full min-w-full overflow-visible ${disabled ? 'opacity-50 pointer-events-none' : ''}`}>
       {/* 고정 헤더 영역 */}
@@ -159,9 +436,9 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
         <div className="flex items-center justify-between">
           <h3 className="text-lg font-semibold">AVL 등록 {disabled ? "(비활성화)" : ""}</h3>
           <div className="flex gap-2">
-            <Button variant="outline" size="sm" disabled={disabled}>
+            {/* <Button variant="outline" size="sm" disabled={disabled}>
               AVL 불러오기
-            </Button>
+            </Button> */}
           </div>
         </div>
       </div>
@@ -172,11 +449,13 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
           {/* 프로젝트 AVL 테이블 - 9개 컬럼 */}
           <div className="p-4 border-r relative">
             <ProjectAvlTable
+              ref={projectTableRef}
               onSelectionChange={handleProjectSelection}
               resetCounter={resetCounters.project}
               projectCode={currentProjectCode}
               avlListId={parseInt(avlListId) || 1}
               onProjectCodeChange={handleProjectCodeChange}
+              reloadTrigger={projectAvlReloadTrigger}
             />
 
             {/* 이동 버튼들 - 첫 번째 border 위에 오버레이 */}
@@ -188,7 +467,8 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   size="sm"
                   className="w-8 h-8 p-0"
                   title="프로젝트AVL로 복사"
-                  disabled={disabled || selectedTable !== 'standard' || selectedRowCount === 0}
+                  disabled={disabled || selectedTable === 'project' || selectedRowCount === 0}
+                  onClick={handleCopyToProject}
                 >
                   <ChevronLeft className="w-4 h-4" />
                 </Button>
@@ -198,7 +478,8 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   size="sm"
                   className="w-8 h-8 p-0"
                   title="선종별표준AVL로 복사"
-                  disabled={disabled || selectedTable !== 'project' || selectedRowCount === 0}
+                  disabled={disabled || selectedTable !== 'project' || selectedRowCount === 0 || !isStandardSearchConditionsComplete}
+                  onClick={handleCopyToStandard}
                 >
                   <ChevronRight className="w-4 h-4" />
                 </Button>
@@ -209,6 +490,7 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   className="w-8 h-8 p-0"
                   title="벤더풀로 복사"
                   disabled={disabled || selectedTable !== 'project' || selectedRowCount === 0}
+                  onClick={handleCopyToVendorPool}
                 >
                   <ChevronsRight className="w-4 h-4" />
                 </Button>
@@ -220,12 +502,15 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
           {/* 선종별 표준 AVL 테이블 - 8개 컬럼 */}
           <div className="p-4 border-r relative">
             <StandardAvlTable
+              ref={standardTableRef}
               onSelectionChange={handleStandardSelection}
               resetCounter={resetCounters.standard}
               constructionSector={constructionSector}
               shipType={shipType}
               avlKind={avlKind}
               htDivision={htDivision}
+              onSearchConditionsChange={setStandardSearchConditions}
+              reloadTrigger={standardAvlReloadTrigger}
             />
 
             {/* 이동 버튼들 - 두 번째 border 위에 오버레이 */}
@@ -235,8 +520,9 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   variant="outline"
                   size="sm"
                   className="w-8 h-8 p-0"
-                  title="프로젝트AVL로 복사"
-                  disabled={disabled || selectedTable !== 'vendor' || selectedRowCount === 0}
+                  title="벤더풀의 항목을 프로젝트AVL로 복사"
+                  disabled={disabled || selectedTable !== 'vendor' || selectedRowCount === 0 || !currentProjectCode}
+                  onClick={handleCopyFromVendorToProject}
                 >
                   <ChevronsLeft className="w-4 h-4" />
                 </Button>
@@ -245,8 +531,9 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   variant="outline"
                   size="sm"
                   className="w-8 h-8 p-0"
-                  title="선종별표준AVL로 복사"
-                  disabled={disabled || selectedTable !== 'vendor' || selectedRowCount === 0}
+                  title="벤더풀의 항목을 선종별표준AVL로 복사"
+                  disabled={disabled || selectedTable !== 'vendor' || selectedRowCount === 0 || !isStandardSearchConditionsComplete}
+                  onClick={handleCopyFromVendorToStandard}
                 >
                   <ChevronLeft className="w-4 h-4" />
                 </Button>
@@ -254,8 +541,9 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
                   variant="outline"
                   size="sm"
                   className="w-8 h-8 p-0"
-                  title="벤더풀로 복사"
+                  title="선종별표준AVL의 항목을 벤더풀로 복사"
                   disabled={disabled || selectedTable !== 'standard' || selectedRowCount === 0}
+                  onClick={handleCopyFromStandardToVendor}
                 >
                   <ChevronRight className="w-4 h-4" />
                 </Button>
@@ -267,8 +555,10 @@ export function AvlRegistrationArea({ disabled = false }: AvlRegistrationAreaPro
           {/* Vendor Pool 테이블 - 10개 컬럼 */}
           <div className="p-4 relative">
             <VendorPoolTable
+              ref={vendorTableRef}
               onSelectionChange={handleVendorSelection}
               resetCounter={resetCounters.vendor}
+              reloadTrigger={vendorPoolReloadTrigger}
             />
           </div>
         </div>
diff --git a/lib/avl/table/avl-table-columns.tsx b/lib/avl/table/avl-table-columns.tsx
index 77361f36..8caf012e 100644
--- a/lib/avl/table/avl-table-columns.tsx
+++ b/lib/avl/table/avl-table-columns.tsx
@@ -1,7 +1,7 @@
 import { Checkbox } from "@/components/ui/checkbox"
 import { Button } from "@/components/ui/button"
 import { Badge } from "@/components/ui/badge"
-import { Eye, Edit, Trash2 } from "lucide-react"
+import { Eye, Edit, Trash2, History } from "lucide-react"
 import { type ColumnDef, TableMeta } from "@tanstack/react-table"
 import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
 import { EditableCell } from "@/components/data-table/editable-cell"
@@ -224,22 +224,24 @@ export function getColumns({ selectedRows = [], onRowSelect }: GetColumnsProps):
         ),
         cell: ({ getValue, row, table }) => {
           const value = getValue() as number
-          const isModified = getIsModified(table, row.id, "rev")
           return (
-            <EditableCell
-              value={value?.toString() || ""}
-              isModified={isModified}
-              type="number"
-              onUpdate={(newValue) => {
-                table.options.meta?.onCellUpdate?.(row.id, "rev", parseInt(newValue))
-              }}
-              onCancel={() => {
-                table.options.meta?.onCellCancel?.(row.id, "rev")
-              }}
-            />
+            <div className="flex items-center gap-1">
+              <Badge variant="outline" className="font-mono">
+                {value || 1}
+              </Badge>
+              <Button
+                variant="ghost"
+                size="sm"
+                className="h-6 w-6 p-0"
+                onClick={() => table.options.meta?.onAction?.('view-history', row.original)}
+                title="리비전 히스토리 보기"
+              >
+                <History className="h-3 w-3" />
+              </Button>
+            </div>
           )
         },
-        size: 80,
+        size: 100,
       },
     ],
   },
diff --git a/lib/avl/table/avl-table.tsx b/lib/avl/table/avl-table.tsx
index a6910ef5..eb9b2079 100644
--- a/lib/avl/table/avl-table.tsx
+++ b/lib/avl/table/avl-table.tsx
@@ -2,7 +2,6 @@
 
 import * as React from "react"
 import type {
-  DataTableAdvancedFilterField,
   DataTableFilterField,
 } from "@/types/table"
 
@@ -10,12 +9,12 @@ 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 { Button } from "@/components/ui/button"
-import { Checkbox } from "@/components/ui/checkbox"
 import { toast } from "sonner"
 
 import { getColumns } from "./avl-table-columns"
 import { createAvlListAction, updateAvlListAction, deleteAvlListAction, handleAvlActionAction } from "../service"
 import type { AvlListItem } from "../types"
+import { AvlHistoryModal, type AvlHistoryRecord } from "@/lib/avl/components/avl-history-modal"
 
 // 테이블 메타 타입 확장
 declare module "@tanstack/react-table" {
@@ -52,6 +51,50 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
   const [emptyRows, setEmptyRows] = React.useState<Record<string, AvlListItem>>({})
   const [isCreating, setIsCreating] = React.useState(false)
 
+  // 히스토리 모달 관리
+  const [historyModalOpen, setHistoryModalOpen] = React.useState(false)
+  const [selectedAvlItem, setSelectedAvlItem] = React.useState<AvlListItem | null>(null)
+
+  // 히스토리 데이터 로드 함수
+  const loadHistoryData = React.useCallback(async (avlItem: AvlListItem): Promise<AvlHistoryRecord[]> => {
+    try {
+      // 현재 리비전의 스냅샷 데이터 (실제 저장된 데이터 사용)
+      const currentSnapshot = avlItem.vendorInfoSnapshot || []
+      
+      const historyData: AvlHistoryRecord[] = [
+        {
+          id: avlItem.id,
+          rev: avlItem.rev || 1,
+          createdAt: avlItem.createdAt || new Date().toISOString(),
+          createdBy: avlItem.createdBy || "system",
+          vendorInfoSnapshot: currentSnapshot,
+          changeDescription: "최신 리비전 (확정완료)"
+        }
+      ]
+      
+      // TODO: 실제 구현에서는 DB에서 이전 리비전들의 스냅샷 데이터를 조회해야 함
+      // 현재는 더미 데이터로 이전 리비전들을 시뮬레이션
+      if ((avlItem.rev || 1) > 1) {
+        for (let rev = (avlItem.rev || 1) - 1; rev >= 1; rev--) {
+          historyData.push({
+            id: avlItem.id + rev * 1000, // 임시 ID
+            rev,
+            createdAt: new Date(Date.now() - rev * 24 * 60 * 60 * 1000).toISOString(),
+            createdBy: "system",
+            vendorInfoSnapshot: [], // 이전 리비전의 스냅샷 데이터 (실제로는 DB에서 조회)
+            changeDescription: `리비전 ${rev} 변경사항`
+          })
+        }
+      }
+      
+      return historyData
+    } catch (error) {
+      console.error('히스토리 로드 실패:', error)
+      toast.error("히스토리를 불러오는데 실패했습니다.")
+      return []
+    }
+  }, [])
+
   // 필터 필드 정의
   const filterFields: DataTableFilterField<AvlListItem>[] = [
     {
@@ -83,33 +126,6 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
     },
   ]
 
-  // 고급 필터 필드 정의
-  const advancedFilterFields: DataTableAdvancedFilterField<AvlListItem>[] = [
-    {
-      id: "projectCode",
-      label: "프로젝트 코드",
-      type: "text",
-      placeholder: "프로젝트 코드 입력...",
-    },
-    {
-      id: "shipType",
-      label: "선종",
-      type: "text",
-      placeholder: "선종 입력...",
-    },
-    {
-      id: "avlKind",
-      label: "AVL 종류",
-      type: "text",
-      placeholder: "AVL 종류 입력...",
-    },
-    {
-      id: "createdBy",
-      label: "등재자",
-      type: "text",
-      placeholder: "등재자 입력...",
-    },
-  ]
 
   // 인라인 편집 핸들러 (일괄 저장용)
   const handleCellUpdate = React.useCallback(async (id: string, field: keyof AvlListItem, newValue: any) => {
@@ -186,6 +202,7 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
             avlKind: "",
             htDivision: "",
             rev: 1,
+            vendorInfoSnapshot: null,
             createdAt: new Date().toISOString().split('T')[0],
             updatedAt: new Date().toISOString().split('T')[0],
             createdBy: "system",
@@ -296,6 +313,14 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
           }
           break
 
+        case 'view-history':
+          // 리비전 히스토리 조회
+          if (data?.id && !String(data.id).startsWith('temp-')) {
+            setSelectedAvlItem(data as AvlListItem)
+            setHistoryModalOpen(true)
+          }
+          break
+
         default:
           toast.error(`알 수 없는 액션: ${action}`)
       }
@@ -303,7 +328,7 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
       console.error('액션 처리 실패:', error)
       toast.error("액션 처리 중 오류가 발생했습니다.")
     }
-  }, [pendingChanges, onRefresh])
+  }, [pendingChanges, onRefresh, onRegistrationModeChange])
 
   // 빈 행 저장 핸들러
   const handleSaveEmptyRow = React.useCallback(async (tempId: string) => {
@@ -425,6 +450,10 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
     initialState: {
       sorting: [{ id: "createdAt", desc: true }],
       columnPinning: { right: ["actions"] },
+      pagination: {
+        pageIndex: 0,
+        pageSize: 10,
+      },
     },
     getRowId: (row) => String(row.id),
     meta: tableMeta,
@@ -502,6 +531,17 @@ export function AvlTable({ data, pageCount, onRefresh, isLoading, onRegistration
       {/* 데이터 테이블 */}
       <DataTable table={table} />
 
+      {/* 히스토리 모달 */}
+      <AvlHistoryModal
+        isOpen={historyModalOpen}
+        onClose={() => {
+          setHistoryModalOpen(false)
+          setSelectedAvlItem(null)
+        }}
+        avlItem={selectedAvlItem}
+        onLoadHistory={loadHistoryData}
+      />
+
       {/* 디버그 정보 (개발 환경에서만 표시) */}
       {process.env.NODE_ENV === 'development' && (hasPendingChanges || hasEmptyRows) && (
         <div className="text-xs text-muted-foreground p-2 bg-muted rounded">
diff --git a/lib/avl/table/avl-vendor-add-and-modify-dialog.tsx b/lib/avl/table/avl-vendor-add-and-modify-dialog.tsx
new file mode 100644
index 00000000..174982e4
--- /dev/null
+++ b/lib/avl/table/avl-vendor-add-and-modify-dialog.tsx
@@ -0,0 +1,945 @@
+"use client"
+
+import * as React from "react"
+import {
+  Dialog,
+  DialogContent,
+  DialogDescription,
+  DialogFooter,
+  DialogHeader,
+  DialogTitle,
+  DialogTrigger,
+} from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
+import { Input } from "@/components/ui/input"
+import { Label } from "@/components/ui/label"
+import { Checkbox } from "@/components/ui/checkbox"
+import { Textarea } from "@/components/ui/textarea"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import { toast } from "sonner"
+import type { AvlVendorInfoInput, AvlDetailItem } from "../types"
+
+interface AvlVendorAddAndModifyDialogProps {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+  onAddItem: (item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void>
+  editingItem?: AvlDetailItem // 수정할 항목 (없으면 추가 모드)
+  onUpdateItem?: (id: number, item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void>
+
+  // 모드 설정
+  isTemplate?: boolean // false: 프로젝트 AVL, true: 표준 AVL
+
+  // 표준 AVL용 초기값들 (선택적)
+  initialConstructionSector?: string
+  initialShipType?: string
+  initialAvlKind?: string
+  initialHtDivision?: string
+
+  // 프로젝트 AVL용 초기값들 (선택적)
+  initialProjectCode?: string
+}
+
+export function AvlVendorAddAndModifyDialog({
+  open,
+  onOpenChange,
+  onAddItem,
+  editingItem,
+  onUpdateItem,
+  isTemplate = false, // 기본값: 프로젝트 AVL
+  initialConstructionSector,
+  initialShipType,
+  initialAvlKind,
+  initialHtDivision,
+  initialProjectCode
+}: AvlVendorAddAndModifyDialogProps) {
+  const [formData, setFormData] = React.useState<Omit<AvlVendorInfoInput, 'avlListId'>>({
+    // 공통 기본 설정
+    isTemplate: isTemplate,
+
+    // 프로젝트 AVL용 필드들
+    projectCode: initialProjectCode || "",
+
+    // 표준 AVL용 필드들
+    constructionSector: initialConstructionSector || "",
+    shipType: initialShipType || "",
+    avlKind: initialAvlKind || "",
+    htDivision: initialHtDivision || "",
+
+    // 설계 정보
+    equipBulkDivision: "EQUIP",
+    disciplineCode: "",
+    disciplineName: "",
+
+    // 자재 정보
+    materialNameCustomerSide: "",
+
+    // 패키지 정보
+    packageCode: "",
+    packageName: "",
+
+    // 자재그룹 정보
+    materialGroupCode: "",
+    materialGroupName: "",
+
+    // 협력업체 정보
+    vendorName: "",
+    vendorCode: "",
+
+    // AVL 정보
+    avlVendorName: "",
+    tier: "",
+
+    // 제안방향
+    ownerSuggestion: false,
+    shiSuggestion: false,
+
+    // 위치 정보
+    headquarterLocation: "",
+    manufacturingLocation: "",
+
+    // FA 정보
+    faTarget: false,
+    faStatus: "",
+
+    // Agent 정보
+    isAgent: false,
+
+    // 계약 서명주체
+    contractSignerName: "",
+    contractSignerCode: "",
+
+    // SHI Qualification
+    shiAvl: false,
+    shiBlacklist: false,
+    shiBcc: false,
+
+    // 기술영업 견적결과
+    salesQuoteNumber: "",
+    quoteCode: "",
+    salesVendorInfo: "",
+    salesCountry: "",
+    totalAmount: "",
+    quoteReceivedDate: "",
+
+    // 업체 실적 현황
+    recentQuoteDate: "",
+    recentQuoteNumber: "",
+    recentOrderDate: "",
+    recentOrderNumber: "",
+
+    // 기타
+    remarks: ""
+  })
+
+  // 수정 모드일 때 폼 데이터 초기화
+  React.useEffect(() => {
+    if (editingItem) {
+      setFormData({
+        // 공통 기본 설정
+        isTemplate: editingItem.isTemplate ?? isTemplate,
+
+        // 프로젝트 AVL용 필드들
+        projectCode: editingItem.projectCode || initialProjectCode || "",
+
+        // 표준 AVL용 필드들
+        constructionSector: editingItem.constructionSector || initialConstructionSector || "",
+        shipType: editingItem.shipType || initialShipType || "",
+        avlKind: editingItem.avlKind || initialAvlKind || "",
+        htDivision: editingItem.htDivision || initialHtDivision || "",
+
+        // 설계 정보
+        equipBulkDivision: editingItem.equipBulkDivision === "EQUIP" ? "EQUIP" : "BULK",
+        disciplineCode: editingItem.disciplineCode || "",
+        disciplineName: editingItem.disciplineName || "",
+
+        // 자재 정보
+        materialNameCustomerSide: editingItem.materialNameCustomerSide || "",
+
+        // 패키지 정보
+        packageCode: editingItem.packageCode || "",
+        packageName: editingItem.packageName || "",
+
+        // 자재그룹 정보
+        materialGroupCode: editingItem.materialGroupCode || "",
+        materialGroupName: editingItem.materialGroupName || "",
+
+        // 협력업체 정보
+        vendorName: editingItem.vendorName || "",
+        vendorCode: editingItem.vendorCode || "",
+
+        // AVL 정보
+        avlVendorName: editingItem.avlVendorName || "",
+        tier: editingItem.tier || "",
+
+        // 제안방향
+        ownerSuggestion: editingItem.ownerSuggestion || false,
+        shiSuggestion: editingItem.shiSuggestion || false,
+
+        // 위치 정보
+        headquarterLocation: editingItem.headquarterLocation || "",
+        manufacturingLocation: editingItem.manufacturingLocation || "",
+
+        // FA 정보
+        faTarget: editingItem.faTarget || false,
+        faStatus: editingItem.faStatus || "",
+
+        // Agent 정보
+        isAgent: editingItem.isAgent || false,
+
+        // 계약 서명주체
+        contractSignerName: editingItem.contractSignerName || "",
+        contractSignerCode: editingItem.contractSignerCode || "",
+
+        // SHI Qualification
+        shiAvl: editingItem.shiAvl || false,
+        shiBlacklist: editingItem.shiBlacklist || false,
+        shiBcc: editingItem.shiBcc || false,
+
+        // 기술영업 견적결과
+        salesQuoteNumber: editingItem.salesQuoteNumber || "",
+        quoteCode: editingItem.quoteCode || "",
+        salesVendorInfo: editingItem.salesVendorInfo || "",
+        salesCountry: editingItem.salesCountry || "",
+        totalAmount: editingItem.totalAmount || "",
+        quoteReceivedDate: editingItem.quoteReceivedDate || "",
+
+        // 업체 실적 현황
+        recentQuoteDate: editingItem.recentQuoteDate || "",
+        recentQuoteNumber: editingItem.recentQuoteNumber || "",
+        recentOrderDate: editingItem.recentOrderDate || "",
+        recentOrderNumber: editingItem.recentOrderNumber || "",
+
+        // 기타
+        remarks: editingItem.remarks || ""
+      })
+    }
+  }, [editingItem, isTemplate, initialProjectCode, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision])
+
+  // 다이얼로그가 열릴 때 초기값 재설정 (수정 모드가 아닐 때만)
+  React.useEffect(() => {
+    if (open && !editingItem) {
+      setFormData(prev => ({
+        ...prev,
+        isTemplate: isTemplate,
+        projectCode: initialProjectCode || "",
+        constructionSector: initialConstructionSector || "",
+        shipType: initialShipType || "",
+        avlKind: initialAvlKind || "",
+        htDivision: initialHtDivision || "",
+      }))
+    }
+  }, [open, editingItem, isTemplate, initialProjectCode, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision])
+
+  const handleSubmit = async () => {
+    // 공통 필수 필드 검증
+    if (!formData.disciplineName || !formData.materialNameCustomerSide) {
+      toast.error("설계공종과 고객사 AVL 자재명은 필수 입력 항목입니다.")
+      return
+    }
+
+    // 모드별 필수 필드 검증
+    if (isTemplate) {
+      // 표준 AVL 모드
+      if (!formData.constructionSector || !formData.shipType || !formData.avlKind || !formData.htDivision) {
+        toast.error("공사부문, 선종, AVL종류, H/T 구분은 필수 입력 항목입니다.")
+        return
+      }
+    } else {
+      // 프로젝트 AVL 모드
+      if (!formData.projectCode) {
+        toast.error("프로젝트 코드는 필수 입력 항목입니다.")
+        return
+      }
+    }
+
+    try {
+      if (editingItem && onUpdateItem) {
+        // 수정 모드
+        await onUpdateItem(editingItem.id, formData)
+      } else {
+        // 추가 모드
+        await onAddItem(formData)
+      }
+
+      // 폼 초기화
+      setFormData({
+        isTemplate: isTemplate,
+        projectCode: initialProjectCode || "",
+        constructionSector: initialConstructionSector || "",
+        shipType: initialShipType || "",
+        avlKind: initialAvlKind || "",
+        htDivision: initialHtDivision || "",
+        equipBulkDivision: "EQUIP",
+        disciplineCode: "",
+        disciplineName: "",
+        materialNameCustomerSide: "",
+        packageCode: "",
+        packageName: "",
+        materialGroupCode: "",
+        materialGroupName: "",
+        vendorName: "",
+        vendorCode: "",
+        avlVendorName: "",
+        tier: "",
+        ownerSuggestion: false,
+        shiSuggestion: false,
+        headquarterLocation: "",
+        manufacturingLocation: "",
+        faTarget: false,
+        faStatus: "",
+        isAgent: false,
+        contractSignerName: "",
+        contractSignerCode: "",
+        shiAvl: false,
+        shiBlacklist: false,
+        shiBcc: false,
+        salesQuoteNumber: "",
+        quoteCode: "",
+        salesVendorInfo: "",
+        salesCountry: "",
+        totalAmount: "",
+        quoteReceivedDate: "",
+        recentQuoteDate: "",
+        recentQuoteNumber: "",
+        recentOrderDate: "",
+        recentOrderNumber: "",
+        remarks: ""
+      } as Omit<AvlVendorInfoInput, 'avlListId'>)
+
+      onOpenChange(false)
+    } catch (error) {
+      // 에러 처리는 호출하는 쪽에서 담당
+    }
+  }
+
+  const handleCancel = () => {
+    setFormData({
+      isTemplate: isTemplate,
+      projectCode: initialProjectCode || "",
+      constructionSector: initialConstructionSector || "",
+      shipType: initialShipType || "",
+      avlKind: initialAvlKind || "",
+      htDivision: initialHtDivision || "",
+      equipBulkDivision: "EQUIP",
+      disciplineCode: "",
+      disciplineName: "",
+      materialNameCustomerSide: "",
+      packageCode: "",
+      packageName: "",
+      materialGroupCode: "",
+      materialGroupName: "",
+      vendorName: "",
+      vendorCode: "",
+      avlVendorName: "",
+      tier: "",
+      ownerSuggestion: false,
+      shiSuggestion: false,
+      headquarterLocation: "",
+      manufacturingLocation: "",
+      faTarget: false,
+      faStatus: "",
+      isAgent: false,
+      contractSignerName: "",
+      contractSignerCode: "",
+      shiAvl: false,
+      shiBlacklist: false,
+      shiBcc: false,
+      salesQuoteNumber: "",
+      quoteCode: "",
+      salesVendorInfo: "",
+      salesCountry: "",
+      totalAmount: "",
+      quoteReceivedDate: "",
+      recentQuoteDate: "",
+      recentQuoteNumber: "",
+      recentOrderDate: "",
+      recentOrderNumber: "",
+      remarks: ""
+    } as Omit<AvlVendorInfoInput, 'avlListId'>)
+    onOpenChange(false)
+  }
+
+  // 선종 옵션들 (공사부문에 따라 다름)
+  const getShipTypeOptions = (constructionSector: string) => {
+    if (constructionSector === "조선") {
+      return [
+        { value: "A-max", label: "A-max" },
+        { value: "S-max", label: "S-max" },
+        { value: "VLCC", label: "VLCC" },
+        { value: "LNGC", label: "LNGC" },
+        { value: "CONT", label: "CONT" },
+      ]
+    } else if (constructionSector === "해양") {
+      return [
+        { value: "FPSO", label: "FPSO" },
+        { value: "FLNG", label: "FLNG" },
+        { value: "FPU", label: "FPU" },
+        { value: "Platform", label: "Platform" },
+        { value: "WTIV", label: "WTIV" },
+        { value: "GOM", label: "GOM" },
+      ]
+    } else {
+      return []
+    }
+  }
+
+  const shipTypeOptions = getShipTypeOptions(formData.constructionSector)
+
+  return (
+    <Dialog open={open} onOpenChange={onOpenChange}>
+      <DialogContent className="sm:max-w-[800px] max-h-[90vh] overflow-y-auto">
+        <DialogHeader>
+          <DialogTitle>
+            {isTemplate ? "표준 AVL" : "프로젝트 AVL"} {editingItem ? "항목 수정" : "항목 추가"}
+          </DialogTitle>
+          <DialogDescription>
+            {editingItem
+              ? `${isTemplate ? "표준 AVL" : "프로젝트 AVL"} 항목을 수정합니다. 필수 항목을 입력해주세요.`
+              : `새로운 ${isTemplate ? "표준 AVL" : "프로젝트 AVL"} 항목을 추가합니다. 필수 항목을 입력해주세요.`
+            } * 표시된 항목은 필수 입력사항입니다.
+          </DialogDescription>
+        </DialogHeader>
+        <div className="space-y-6 py-4">
+          {/* 모드별 필수 정보 */}
+          {!isTemplate ? (
+            // 프로젝트 AVL 모드
+            <div className="space-y-4">
+              <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">프로젝트 정보 *</h4>
+              <div className="grid grid-cols-1 gap-4">
+                <div className="space-y-2">
+                  <Label htmlFor="projectCode">프로젝트 코드 *</Label>
+                  <Input
+                    id="projectCode"
+                    value={formData.projectCode}
+                    onChange={(e) => setFormData(prev => ({ ...prev, projectCode: e.target.value }))}
+                    placeholder="프로젝트 코드를 입력하세요"
+                  />
+                </div>
+              </div>
+            </div>
+          ) : (
+            // 표준 AVL 모드
+            <div className="space-y-4">
+              <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">표준 AVL 기본 정보 *</h4>
+              <div className="grid grid-cols-2 gap-4">
+                <div className="space-y-2">
+                  <Label htmlFor="constructionSector">공사부문 *</Label>
+                  <Select
+                    value={formData.constructionSector}
+                    onValueChange={(value) => {
+                      setFormData(prev => ({
+                        ...prev,
+                        constructionSector: value,
+                        shipType: "" // 공사부문 변경 시 선종 초기화
+                      }))
+                    }}
+                  >
+                    <SelectTrigger>
+                      <SelectValue placeholder="공사부문을 선택하세요" />
+                    </SelectTrigger>
+                    <SelectContent>
+                      <SelectItem value="조선">조선</SelectItem>
+                      <SelectItem value="해양">해양</SelectItem>
+                    </SelectContent>
+                  </Select>
+                </div>
+                <div className="space-y-2">
+                  <Label htmlFor="shipType">선종 *</Label>
+                  <Select
+                    value={formData.shipType}
+                    onValueChange={(value) =>
+                      setFormData(prev => ({ ...prev, shipType: value }))
+                    }
+                    disabled={!formData.constructionSector}
+                  >
+                    <SelectTrigger>
+                      <SelectValue placeholder="선종을 선택하세요" />
+                    </SelectTrigger>
+                    <SelectContent>
+                      {shipTypeOptions.map((option) => (
+                        <SelectItem key={option.value} value={option.value}>
+                          {option.label}
+                        </SelectItem>
+                      ))}
+                    </SelectContent>
+                  </Select>
+                </div>
+                <div className="space-y-2">
+                  <Label htmlFor="avlKind">AVL종류 *</Label>
+                  <Select
+                    value={formData.avlKind}
+                    onValueChange={(value) =>
+                      setFormData(prev => ({ ...prev, avlKind: value }))
+                    }
+                  >
+                    <SelectTrigger>
+                      <SelectValue placeholder="AVL종류를 선택하세요" />
+                    </SelectTrigger>
+                    <SelectContent>
+                      <SelectItem value="Nearshore">Nearshore</SelectItem>
+                      <SelectItem value="Offshore">Offshore</SelectItem>
+                      <SelectItem value="IOC">IOC</SelectItem>
+                      <SelectItem value="NOC">NOC</SelectItem>
+                    </SelectContent>
+                  </Select>
+                </div>
+                <div className="space-y-2">
+                  <Label htmlFor="htDivision">H/T 구분 *</Label>
+                  <Select
+                    value={formData.htDivision}
+                    onValueChange={(value) =>
+                      setFormData(prev => ({ ...prev, htDivision: value }))
+                    }
+                  >
+                    <SelectTrigger>
+                      <SelectValue placeholder="H/T 구분을 선택하세요" />
+                    </SelectTrigger>
+                    <SelectContent>
+                      <SelectItem value="공통">공통</SelectItem>
+                      <SelectItem value="H">Hull (H)</SelectItem>
+                      <SelectItem value="T">Topside (T)</SelectItem>
+                    </SelectContent>
+                  </Select>
+                </div>
+              </div>
+            </div>
+          )}
+
+          {/* 공통 정보들 (나머지 폼 필드들은 동일하게 유지) */}
+          {/* 기본 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기본 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="equipBulkDivision">EQUIP/BULK 구분</Label>
+                <Select
+                  value={formData.equipBulkDivision}
+                  onValueChange={(value: "EQUIP" | "BULK") =>
+                    setFormData(prev => ({ ...prev, equipBulkDivision: value }))
+                  }
+                >
+                  <SelectTrigger>
+                    <SelectValue />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="EQUIP">EQUIP</SelectItem>
+                    <SelectItem value="BULK">BULK</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="disciplineCode">설계공종코드</Label>
+                <Input
+                  id="disciplineCode"
+                  value={formData.disciplineCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, disciplineCode: e.target.value }))}
+                  placeholder="설계공종코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2 col-span-2">
+                <Label htmlFor="disciplineName">설계공종명 *</Label>
+                <Input
+                  id="disciplineName"
+                  value={formData.disciplineName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, disciplineName: e.target.value }))}
+                  placeholder="설계공종명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2 col-span-2">
+                <Label htmlFor="materialNameCustomerSide">고객사 AVL 자재명 *</Label>
+                <Input
+                  id="materialNameCustomerSide"
+                  value={formData.materialNameCustomerSide}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialNameCustomerSide: e.target.value }))}
+                  placeholder="고객사 AVL 자재명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 패키지 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">패키지 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="packageCode">패키지 코드</Label>
+                <Input
+                  id="packageCode"
+                  value={formData.packageCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, packageCode: e.target.value }))}
+                  placeholder="패키지 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="packageName">패키지 명</Label>
+                <Input
+                  id="packageName"
+                  value={formData.packageName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, packageName: e.target.value }))}
+                  placeholder="패키지 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 자재그룹 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">자재그룹 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="materialGroupCode">자재그룹 코드</Label>
+                <Input
+                  id="materialGroupCode"
+                  value={formData.materialGroupCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialGroupCode: e.target.value }))}
+                  placeholder="자재그룹 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="materialGroupName">자재그룹 명</Label>
+                <Input
+                  id="materialGroupName"
+                  value={formData.materialGroupName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialGroupName: e.target.value }))}
+                  placeholder="자재그룹 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 협력업체 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">협력업체 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="vendorCode">협력업체 코드</Label>
+                <Input
+                  id="vendorCode"
+                  value={formData.vendorCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, vendorCode: e.target.value }))}
+                  placeholder="협력업체 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="vendorName">협력업체 명</Label>
+                <Input
+                  id="vendorName"
+                  value={formData.vendorName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, vendorName: e.target.value }))}
+                  placeholder="협력업체 명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="avlVendorName">AVL 등재업체명</Label>
+                <Input
+                  id="avlVendorName"
+                  value={formData.avlVendorName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, avlVendorName: e.target.value }))}
+                  placeholder="AVL 등재업체명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="tier">등급 (Tier)</Label>
+                <Input
+                  id="tier"
+                  value={formData.tier}
+                  onChange={(e) => setFormData(prev => ({ ...prev, tier: e.target.value }))}
+                  placeholder="등급을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 제안방향 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">제안방향</h4>
+            <div className="flex gap-6">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="ownerSuggestion"
+                  checked={formData.ownerSuggestion}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, ownerSuggestion: !!checked }))
+                  }
+                />
+                <Label htmlFor="ownerSuggestion">선주제안</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiSuggestion"
+                  checked={formData.shiSuggestion}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiSuggestion: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiSuggestion">SHI 제안</Label>
+              </div>
+            </div>
+          </div>
+
+          {/* 위치 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">위치 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="headquarterLocation">본사 위치 (국가)</Label>
+                <Input
+                  id="headquarterLocation"
+                  value={formData.headquarterLocation}
+                  onChange={(e) => setFormData(prev => ({ ...prev, headquarterLocation: e.target.value }))}
+                  placeholder="본사 위치를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="manufacturingLocation">제작/선적지 (국가)</Label>
+                <Input
+                  id="manufacturingLocation"
+                  value={formData.manufacturingLocation}
+                  onChange={(e) => setFormData(prev => ({ ...prev, manufacturingLocation: e.target.value }))}
+                  placeholder="제작/선적지를 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* FA 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">FA 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="faTarget"
+                  checked={formData.faTarget}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, faTarget: !!checked }))
+                  }
+                />
+                <Label htmlFor="faTarget">FA 대상</Label>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="faStatus">FA 현황</Label>
+                <Input
+                  id="faStatus"
+                  value={formData.faStatus}
+                  onChange={(e) => setFormData(prev => ({ ...prev, faStatus: e.target.value }))}
+                  placeholder="FA 현황을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* Agent 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">Agent 정보</h4>
+            <div className="flex items-center space-x-2">
+              <Checkbox
+                id="isAgent"
+                checked={formData.isAgent}
+                onCheckedChange={(checked) =>
+                  setFormData(prev => ({ ...prev, isAgent: !!checked }))
+                }
+              />
+              <Label htmlFor="isAgent">Agent 여부</Label>
+            </div>
+          </div>
+
+          {/* 계약 서명주체 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">계약 서명주체</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="contractSignerCode">계약서명주체 코드</Label>
+                <Input
+                  id="contractSignerCode"
+                  value={formData.contractSignerCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, contractSignerCode: e.target.value }))}
+                  placeholder="계약서명주체 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="contractSignerName">계약서명주체 명</Label>
+                <Input
+                  id="contractSignerName"
+                  value={formData.contractSignerName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, contractSignerName: e.target.value }))}
+                  placeholder="계약서명주체 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* SHI Qualification */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">SHI Qualification</h4>
+            <div className="flex gap-6">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiAvl"
+                  checked={formData.shiAvl}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiAvl: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiAvl">AVL</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiBlacklist"
+                  checked={formData.shiBlacklist}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiBlacklist: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiBlacklist">Blacklist</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiBcc"
+                  checked={formData.shiBcc}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiBcc: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiBcc">BCC</Label>
+              </div>
+            </div>
+          </div>
+
+          {/* 기술영업 견적결과 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기술영업 견적결과</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="salesQuoteNumber">기술영업 견적번호</Label>
+                <Input
+                  id="salesQuoteNumber"
+                  value={formData.salesQuoteNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesQuoteNumber: e.target.value }))}
+                  placeholder="기술영업 견적번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="quoteCode">견적서 Code</Label>
+                <Input
+                  id="quoteCode"
+                  value={formData.quoteCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, quoteCode: e.target.value }))}
+                  placeholder="견적서 Code를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="salesVendorInfo">견적 협력업체 명</Label>
+                <Input
+                  id="salesVendorInfo"
+                  value={formData.salesVendorInfo}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesVendorInfo: e.target.value }))}
+                  placeholder="견적 협력업체 명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="salesCountry">국가</Label>
+                <Input
+                  id="salesCountry"
+                  value={formData.salesCountry}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesCountry: e.target.value }))}
+                  placeholder="국가를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="totalAmount">총 금액</Label>
+                <Input
+                  id="totalAmount"
+                  type="number"
+                  value={formData.totalAmount}
+                  onChange={(e) => setFormData(prev => ({ ...prev, totalAmount: e.target.value }))}
+                  placeholder="총 금액을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="quoteReceivedDate">견적접수일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="quoteReceivedDate"
+                  value={formData.quoteReceivedDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, quoteReceivedDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 업체 실적 현황 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">업체 실적 현황</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="recentQuoteNumber">최근견적번호</Label>
+                <Input
+                  id="recentQuoteNumber"
+                  value={formData.recentQuoteNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteNumber: e.target.value }))}
+                  placeholder="최근견적번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentQuoteDate">최근견적일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="recentQuoteDate"
+                  value={formData.recentQuoteDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentOrderNumber">최근발주번호</Label>
+                <Input
+                  id="recentOrderNumber"
+                  value={formData.recentOrderNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentOrderNumber: e.target.value }))}
+                  placeholder="최근발주번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentOrderDate">최근발주일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="recentOrderDate"
+                  value={formData.recentOrderDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentOrderDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 기타 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기타</h4>
+            <div className="space-y-2">
+              <Label htmlFor="remarks">비고</Label>
+              <Textarea
+                id="remarks"
+                value={formData.remarks}
+                onChange={(e) => setFormData(prev => ({ ...prev, remarks: e.target.value }))}
+                placeholder="비고를 입력하세요"
+                rows={3}
+              />
+            </div>
+          </div>
+        </div>
+        <DialogFooter>
+          <Button type="button" variant="outline" onClick={handleCancel}>
+            취소
+          </Button>
+          <Button type="button" onClick={handleSubmit}>
+            {editingItem ? "수정" : "추가"}
+          </Button>
+        </DialogFooter>
+      </DialogContent>
+    </Dialog>
+  )
+}
diff --git a/lib/avl/table/columns-detail.tsx b/lib/avl/table/columns-detail.tsx
index 204d34f5..84ad9d9a 100644
--- a/lib/avl/table/columns-detail.tsx
+++ b/lib/avl/table/columns-detail.tsx
@@ -1,28 +1,8 @@
 import { Checkbox } from "@/components/ui/checkbox"
 import { Badge } from "@/components/ui/badge"
-import { Button } from "@/components/ui/button"
-import { Edit, Trash2 } from "lucide-react"
-import { type ColumnDef, TableMeta } from "@tanstack/react-table"
+import { type ColumnDef } from "@tanstack/react-table"
 import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
-import { EditableCell } from "@/components/data-table/editable-cell"
 
-// 수정 여부 확인 헬퍼 함수
-const getIsModified = (table: any, rowId: string, fieldName: string) => {
-  const pendingChanges = table.options.meta?.getPendingChanges?.() || {}
-  return String(rowId) in pendingChanges && fieldName in pendingChanges[String(rowId)]
-}
-
-// 테이블 메타 타입 확장
-declare module "@tanstack/react-table" {
-  interface TableMeta<TData> {
-    onCellUpdate?: (id: string, field: keyof TData, newValue: any) => Promise<void>
-    onCellCancel?: (id: string, field: keyof TData) => void
-    onAction?: (action: string, data?: any) => void
-    onSaveEmptyRow?: (tempId: string) => Promise<void>
-    onCancelEmptyRow?: (tempId: string) => void
-    isEmptyRow?: (id: string) => boolean
-  }
-}
 
 // AVL 상세 아이템 타입
 export type AvlDetailItem = {
@@ -89,29 +69,6 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
   {
     header: "기본 정보",
     columns: [
-      {
-        id: "select",
-        header: ({ table }) => (
-          <Checkbox
-            checked={
-              table.getIsAllPageRowsSelected() ||
-              (table.getIsSomePageRowsSelected() && "indeterminate")
-            }
-            onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
-            aria-label="Select all"
-          />
-        ),
-        cell: ({ row }) => (
-          <Checkbox
-            checked={row.getIsSelected()}
-            onCheckedChange={(value) => row.toggleSelected(!!value)}
-            aria-label="Select row"
-          />
-        ),
-        enableSorting: false,
-        enableHiding: false,
-        size: 50,
-      },
       {
         accessorKey: "no",
         header: ({ column }) => (
@@ -124,33 +81,12 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="Equip/Bulk 구분" />
         ),
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("equipBulkDivision") as string
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "equipBulkDivision", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "equipBulkDivision")
-
           return (
-            <EditableCell
-              value={value}
-              type="select"
-              onSave={onSave}
-              options={[
-                { label: "EQUIP", value: "EQUIP" },
-                { label: "BULK", value: "BULK" }
-              ]}
-              placeholder="구분 선택"
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
+            <Badge variant="outline">
+              {value || "-"}
+            </Badge>
           )
         },
         size: 120,
@@ -160,31 +96,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="설계공종" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("disciplineName")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "disciplineName", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "disciplineName")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="설계공종 입력"
-              maxLength={50}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("disciplineName") as string
+          return <span>{value || "-"}</span>
         },
         size: 120,
       },
@@ -193,31 +107,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="고객사 AVL 자재명" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("materialNameCustomerSide")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "materialNameCustomerSide", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "materialNameCustomerSide")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="자재명 입력"
-              maxLength={100}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("materialNameCustomerSide") as string
+          return <span>{value || "-"}</span>
         },
         size: 150,
       },
@@ -226,31 +118,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="패키지 정보" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("packageName")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "packageName", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "packageName")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="패키지명 입력"
-              maxLength={100}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("packageName") as string
+          return <span>{value || "-"}</span>
         },
         size: 130,
       },
@@ -259,31 +129,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="자재그룹코드" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("materialGroupCode")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "materialGroupCode", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "materialGroupCode")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="자재그룹코드 입력"
-              maxLength={50}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("materialGroupCode") as string
+          return <span>{value || "-"}</span>
         },
         size: 120,
       },
@@ -292,31 +140,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="자재그룹명" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("materialGroupName")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "materialGroupName", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "materialGroupName")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="자재그룹명 입력"
-              maxLength={100}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("materialGroupName") as string
+          return <span>{value || "-"}</span>
         },
         size: 130,
       },
@@ -325,31 +151,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="협력업체코드" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("vendorCode")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "vendorCode", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "vendorCode")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="협력업체코드 입력"
-              maxLength={50}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("vendorCode") as string
+          return <span>{value || "-"}</span>
         },
         size: 120,
       },
@@ -358,31 +162,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="협력업체명" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("vendorName")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "vendorName", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "vendorName")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="협력업체명 입력"
-              maxLength={100}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("vendorName") as string
+          return <span className="font-medium">{value || "-"}</span>
         },
         size: 140,
       },
@@ -391,31 +173,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="AVL 등재업체명" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("avlVendorName")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "avlVendorName", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "avlVendorName")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="AVL 등재업체명 입력"
-              maxLength={100}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("avlVendorName") as string
+          return <span>{value || "-"}</span>
         },
         size: 140,
       },
@@ -424,34 +184,20 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="등급 (Tier)" />
         ),
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("tier") as string
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "tier", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "tier")
-
+          if (!value) return <span>-</span>
+          
+          const tierColor = {
+            "Tier 1": "bg-green-100 text-green-800",
+            "Tier 2": "bg-yellow-100 text-yellow-800", 
+            "Tier 3": "bg-red-100 text-red-800"
+          }[value] || "bg-gray-100 text-gray-800"
+          
           return (
-            <EditableCell
-              value={value}
-              type="select"
-              onSave={onSave}
-              options={[
-                { label: "Tier 1", value: "Tier 1" },
-                { label: "Tier 2", value: "Tier 2" },
-                { label: "Tier 3", value: "Tier 3" }
-              ]}
-              placeholder="등급 선택"
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
+            <Badge className={tierColor}>
+              {value}
+            </Badge>
           )
         },
         size: 100,
@@ -467,28 +213,12 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="FA 대상" />
         ),
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("faTarget") as boolean
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "faTarget", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "faTarget")
-
           return (
-            <EditableCell
-              value={value}
-              type="checkbox"
-              onSave={onSave}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
+            <Badge variant={value ? "default" : "secondary"}>
+              {value ? "대상" : "비대상"}
+            </Badge>
           )
         },
         size: 80,
@@ -498,31 +228,9 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
         header: ({ column }) => (
           <DataTableColumnHeaderSimple column={column} title="FA 현황" />
         ),
-        cell: ({ row, table }) => {
-          const value = row.getValue("faStatus")
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "faStatus", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "faStatus")
-
-          return (
-            <EditableCell
-              value={value}
-              type="text"
-              onSave={onSave}
-              placeholder="FA 현황 입력"
-              maxLength={50}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
-            />
-          )
+        cell: ({ row }) => {
+          const value = row.getValue("faStatus") as string
+          return <span>{value || "-"}</span>
         },
         size: 100,
       },
@@ -535,27 +243,13 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
       {
         accessorKey: "shiAvl",
         header: "AVL",
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("shiAvl") as boolean
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "shiAvl", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "shiAvl")
-
           return (
-            <EditableCell
-              value={value}
-              type="checkbox"
-              onSave={onSave}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
+            <Checkbox
+              checked={value}
+              disabled
+              aria-label="SHI AVL 등재 여부"
             />
           )
         },
@@ -564,27 +258,13 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
       {
         accessorKey: "shiBlacklist",
         header: "Blacklist",
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("shiBlacklist") as boolean
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "shiBlacklist", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "shiBlacklist")
-
           return (
-            <EditableCell
-              value={value}
-              type="checkbox"
-              onSave={onSave}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
+            <Checkbox
+              checked={value}
+              disabled
+              aria-label="SHI Blacklist 등재 여부"
             />
           )
         },
@@ -593,27 +273,13 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
       {
         accessorKey: "shiBcc",
         header: "BCC",
-        cell: ({ row, table }) => {
+        cell: ({ row }) => {
           const value = row.getValue("shiBcc") as boolean
-          const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-          const onSave = async (newValue: any) => {
-            if (table.options.meta?.onCellUpdate) {
-              await table.options.meta.onCellUpdate(row.original.id, "shiBcc", newValue)
-            }
-          }
-
-          const isModified = getIsModified(table, row.original.id, "shiBcc")
-
           return (
-            <EditableCell
-              value={value}
-              type="checkbox"
-              onSave={onSave}
-              autoSave={true}
-              disabled={false}
-              initialEditMode={isEmptyRow}
-              isModified={isModified}
+            <Checkbox
+              checked={value}
+              disabled
+              aria-label="SHI BCC 등재 여부"
             />
           )
         },
@@ -621,60 +287,4 @@ export const columns: ColumnDef<AvlDetailItem>[] = [
       },
     ],
   },
-  // 액션 컬럼
-  {
-    id: "actions",
-    header: "액션",
-    cell: ({ row, table }) => {
-      const isEmptyRow = String(row.original.id).startsWith('temp-')
-
-      return (
-        <div className="flex items-center gap-2">
-          {!isEmptyRow && (
-            <>
-              <Button
-                variant="ghost"
-                size="sm"
-                onClick={() => table.options.meta?.onAction?.('edit', row.original)}
-                className="h-8 w-8 p-0"
-              >
-                <Edit className="h-4 w-4" />
-              </Button>
-              <Button
-                variant="ghost"
-                size="sm"
-                onClick={() => table.options.meta?.onAction?.('delete', row.original)}
-                className="h-8 w-8 p-0 text-destructive hover:text-destructive"
-              >
-                <Trash2 className="h-4 w-4" />
-              </Button>
-            </>
-          )}
-          {isEmptyRow && (
-            <>
-              <Button
-                variant="ghost"
-                size="sm"
-                onClick={() => table.options.meta?.onSaveEmptyRow?.(row.original.id)}
-                className="h-8 w-8 p-0"
-              >
-                저장
-              </Button>
-              <Button
-                variant="ghost"
-                size="sm"
-                onClick={() => table.options.meta?.onCancelEmptyRow?.(row.original.id)}
-                className="h-8 w-8 p-0"
-              >
-                취소
-              </Button>
-            </>
-          )}
-        </div>
-      )
-    },
-    size: 100,
-    enableSorting: false,
-    enableHiding: false,
-  },
 ]
diff --git a/lib/avl/table/project-avl-table-columns.tsx b/lib/avl/table/project-avl-table-columns.tsx
new file mode 100644
index 00000000..c052e6f7
--- /dev/null
+++ b/lib/avl/table/project-avl-table-columns.tsx
@@ -0,0 +1,167 @@
+import { ColumnDef } from "@tanstack/react-table"
+import { ProjectAvlItem } from "./project-avl-table"
+import { Checkbox } from "@/components/ui/checkbox"
+
+
+// 프로젝트 AVL 테이블 컬럼
+export const getProjectAvlColumns = (): ColumnDef<ProjectAvlItem>[] => [
+    {
+        id: "select",
+        header: ({ table }) => (
+            <Checkbox
+                checked={
+                    table.getIsAllPageRowsSelected() ||
+                    (table.getIsSomePageRowsSelected() && "indeterminate")
+                }
+                onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+                aria-label="Select all"
+            />
+        ),
+        cell: ({ row, table }) => {
+            // 프로젝트 AVL 테이블의 단일 선택 핸들러
+            const handleRowSelection = (checked: boolean) => {
+                if (checked) {
+                    // 다른 모든 행의 선택 해제
+                    table.getRowModel().rows.forEach(r => {
+                        if (r !== row && r.getIsSelected()) {
+                            r.toggleSelected(false)
+                        }
+                    })
+                }
+                // 현재 행 선택/해제
+                row.toggleSelected(checked)
+            }
+
+            return (
+                <Checkbox
+                    checked={row.getIsSelected()}
+                    onCheckedChange={handleRowSelection}
+                    aria-label="Select row"
+                />
+            )
+        },
+        enableSorting: false,
+        enableHiding: false,
+        size: 50,
+    },
+    {
+        accessorKey: "no",
+        header: "No.",
+        size: 60,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.no}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "disciplineName",
+        header: "설계공종",
+        size: 120,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.disciplineName}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "materialNameCustomerSide",
+        header: "고객사 AVL 자재명",
+        size: 150,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.materialNameCustomerSide}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "materialGroupCode",
+        header: "자재그룹 코드",
+        size: 120,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.materialGroupCode}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "materialGroupName",
+        header: "자재그룹 명",
+        size: 130,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.materialGroupName}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "avlVendorName",
+        header: "AVL 등재업체명",
+        size: 140,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.avlVendorName}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "vendorCode",
+        header: "협력업체 코드",
+        size: 120,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.vendorCode}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "vendorName",
+        header: "협력업체 명",
+        size: 130,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.vendorName}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "ownerSuggestion",
+        header: "선주제안",
+        size: 100,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.ownerSuggestion ? "예" : "아니오"}
+                </span>
+            )
+        },
+    },
+    {
+        accessorKey: "shiSuggestion",
+        header: "SHI 제안",
+        size: 100,
+        cell: ({ row }) => {
+            return (
+                <span>
+                    {row.original.shiSuggestion ? "예" : "아니오"}
+                </span>
+            )
+        },
+    },
+]
\ No newline at end of file
diff --git a/lib/avl/table/project-avl-table.tsx b/lib/avl/table/project-avl-table.tsx
index c6dd8064..8664e32b 100644
--- a/lib/avl/table/project-avl-table.tsx
+++ b/lib/avl/table/project-avl-table.tsx
@@ -1,204 +1,57 @@
 "use client"
 
 import * as React from "react"
-import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, type ColumnDef } from "@tanstack/react-table"
+import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel } from "@tanstack/react-table"
+import { forwardRef, useImperativeHandle, useLayoutEffect, useMemo } from "react"
 import { DataTable } from "@/components/data-table/data-table"
 import { Button } from "@/components/ui/button"
-import { Checkbox } from "@/components/ui/checkbox"
-import { Input } from "@/components/ui/input"
-import { ProjectAvlAddDialog } from "./project-avl-add-dialog"
-import { getProjectAvlVendorInfo, getAvlListById, createAvlVendorInfo, updateAvlVendorInfo, deleteAvlVendorInfo } from "../service"
+import { AvlVendorAddAndModifyDialog } from "./avl-vendor-add-and-modify-dialog"
+import { getProjectAvlVendorInfo, createAvlVendorInfo, updateAvlVendorInfo, deleteAvlVendorInfo, finalizeProjectAvl } from "../service"
 import { getProjectInfoByProjectCode as getProjectInfoFromProjects } from "../../projects/service"
 import { getProjectInfoByProjectCode as getProjectInfoFromBiddingProjects } from "../../bidding-projects/service"
 import { GetProjectAvlSchema } from "../validations"
-import { AvlDetailItem, AvlListItem, AvlVendorInfoInput } from "../types"
+import { AvlDetailItem, AvlVendorInfoInput } from "../types"
 import { toast } from "sonner"
+import { getProjectAvlColumns } from "./project-avl-table-columns"
+import {
+  ProjectDisplayField,
+  ProjectFileField
+} from "../components/project-field-components"
+import { ProjectSearchStatus } from "../components/project-field-utils"
+import { useSession } from "next-auth/react"
+
 
 // 프로젝트 AVL 테이블에서는 AvlDetailItem을 사용
 export type ProjectAvlItem = AvlDetailItem
 
+// ref를 통해 외부에서 접근할 수 있는 메소드들
+export interface ProjectAvlTableRef {
+  getSelectedIds: () => number[]
+}
+
 interface ProjectAvlTableProps {
   onSelectionChange?: (count: number) => void
   resetCounter?: number
   projectCode?: string // 프로젝트 코드 필터
   avlListId?: number // AVL 리스트 ID (관리 영역 표시용)
   onProjectCodeChange?: (projectCode: string) => void // 프로젝트 코드 변경 콜백
+  reloadTrigger?: number
 }
 
-// 프로젝트 AVL 테이블 컬럼
-const getProjectAvlColumns = (): ColumnDef<ProjectAvlItem>[] => [
-  {
-    id: "select",
-    header: ({ table }) => (
-      <Checkbox
-        checked={
-          table.getIsAllPageRowsSelected() ||
-          (table.getIsSomePageRowsSelected() && "indeterminate")
-        }
-        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
-        aria-label="Select all"
-      />
-    ),
-    cell: ({ row, table }) => {
-      // 프로젝트 AVL 테이블의 단일 선택 핸들러
-      const handleRowSelection = (checked: boolean) => {
-        if (checked) {
-          // 다른 모든 행의 선택 해제
-          table.getRowModel().rows.forEach(r => {
-            if (r !== row && r.getIsSelected()) {
-              r.toggleSelected(false)
-            }
-          })
-        }
-        // 현재 행 선택/해제
-        row.toggleSelected(checked)
-      }
-
-      return (
-        <Checkbox
-          checked={row.getIsSelected()}
-          onCheckedChange={handleRowSelection}
-          aria-label="Select row"
-        />
-      )
-    },
-    enableSorting: false,
-    enableHiding: false,
-    size: 50,
-  },
-  {
-    accessorKey: "no",
-    header: "No.",
-    size: 60,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.no}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "disciplineName",
-    header: "설계공종",
-    size: 120,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.disciplineName}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "materialNameCustomerSide",
-    header: "고객사 AVL 자재명",
-    size: 150,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.materialNameCustomerSide}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "materialGroupCode",
-    header: "자재그룹 코드",
-    size: 120,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.materialGroupCode}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "materialGroupName",
-    header: "자재그룹 명",
-    size: 130,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.materialGroupName}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "avlVendorName",
-    header: "AVL 등재업체명",
-    size: 140,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.avlVendorName}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "vendorCode",
-    header: "협력업체 코드",
-    size: 120,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.vendorCode}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "vendorName",
-    header: "협력업체 명",
-    size: 130,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.vendorName}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "ownerSuggestion",
-    header: "선주제안",
-    size: 100,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.ownerSuggestion ? "예" : "아니오"}
-        </span>
-      )
-    },
-  },
-  {
-    accessorKey: "shiSuggestion",
-    header: "SHI 제안",
-    size: 100,
-    cell: ({ row }) => {
-      return (
-        <span>
-          {row.original.shiSuggestion ? "예" : "아니오"}
-        </span>
-      )
-    },
-  },
-]
 
-export function ProjectAvlTable({
+export const ProjectAvlTable = forwardRef<ProjectAvlTableRef, ProjectAvlTableProps>(({
   onSelectionChange,
   resetCounter,
   projectCode,
   avlListId,
-  onProjectCodeChange
-}: ProjectAvlTableProps) {
+  onProjectCodeChange,
+  reloadTrigger
+}, ref) => {
+
+  const { data: sessionData } = useSession()
+
   const [data, setData] = React.useState<ProjectAvlItem[]>([])
-  const [loading, setLoading] = React.useState(false)
   const [pageCount, setPageCount] = React.useState(0)
-  const [avlListInfo, setAvlListInfo] = React.useState<AvlListItem | null>(null)
   const [originalFile, setOriginalFile] = React.useState<string>("")
   const [localProjectCode, setLocalProjectCode] = React.useState<string>(projectCode || "")
 
@@ -215,20 +68,28 @@ export function ProjectAvlTable({
   } | null>(null)
 
   // 프로젝트 검색 상태
-  const [projectSearchStatus, setProjectSearchStatus] = React.useState<'idle' | 'searching' | 'success-projects' | 'success-bidding' | 'error'>('idle')
+  const [projectSearchStatus, setProjectSearchStatus] = React.useState<ProjectSearchStatus>('idle')
+
+  // 검색 버튼 클릭 여부 상태
+  const [isSearchClicked, setIsSearchClicked] = React.useState(false)
+
+  // 페이지네이션 상태
+  const [pagination, setPagination] = React.useState({
+    pageIndex: 0,
+    pageSize: 10,
+  })
 
 
   // 데이터 로드 함수
-  const loadData = React.useCallback(async (searchParams: Partial<GetProjectAvlSchema>) => {
+  const loadData = React.useCallback(async (searchParams: Partial<GetProjectAvlSchema> = {}) => {
     try {
-      setLoading(true)
-      const params: any = {
+      const params = {
         page: searchParams.page ?? 1,
         perPage: searchParams.perPage ?? 10,
         sort: searchParams.sort ?? [{ id: "no", desc: false }],
         flags: searchParams.flags ?? [],
         projectCode: localProjectCode || "",
-        equipBulkDivision: searchParams.equipBulkDivision ?? "",
+        equipBulkDivision: (searchParams.equipBulkDivision as "EQUIP" | "BULK") ?? "EQUIP",
         disciplineCode: searchParams.disciplineCode ?? "",
         disciplineName: searchParams.disciplineName ?? "",
         materialNameCustomerSide: searchParams.materialNameCustomerSide ?? "",
@@ -244,7 +105,13 @@ export function ProjectAvlTable({
         joinOperator: searchParams.joinOperator ?? "and",
         search: searchParams.search ?? "",
       }
+      console.log('ProjectAvlTable - API call params:', params)
       const result = await getProjectAvlVendorInfo(params)
+      console.log('ProjectAvlTable - API result:', {
+        dataCount: result.data.length,
+        pageCount: result.pageCount,
+        requestedPage: params.page
+      })
       setData(result.data)
       setPageCount(result.pageCount)
     } catch (error) {
@@ -252,32 +119,26 @@ export function ProjectAvlTable({
       setData([])
       setPageCount(0)
     } finally {
-      setLoading(false)
+      // 로딩 상태 처리 완료
     }
   }, [localProjectCode])
 
-  // AVL 리스트 정보 로드
+
+
+  // reloadTrigger가 변경될 때마다 데이터 리로드
   React.useEffect(() => {
-    const loadAvlListInfo = async () => {
-      if (avlListId) {
-        try {
-          const info = await getAvlListById(avlListId)
-          setAvlListInfo(info)
-        } catch (error) {
-          console.error("AVL 리스트 정보 로드 실패:", error)
-        }
-      }
+    if (reloadTrigger && reloadTrigger > 0) {
+      console.log('ProjectAvlTable - reloadTrigger changed, reloading data')
+      loadData({})
     }
+  }, [reloadTrigger, loadData])
 
-    loadAvlListInfo()
-  }, [avlListId])
-
-  // 초기 데이터 로드
+  // 초기 데이터 로드 (검색 버튼이 눌렸을 때만)
   React.useEffect(() => {
-    if (localProjectCode) {
+    if (localProjectCode && isSearchClicked) {
       loadData({})
     }
-  }, [loadData, localProjectCode])
+  }, [loadData, localProjectCode, isSearchClicked])
 
   // 파일 업로드 핸들러
   const handleFileUpload = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
@@ -289,42 +150,41 @@ export function ProjectAvlTable({
     }
   }, [])
 
-  // 프로젝트 코드 변경 핸들러
-  const handleProjectCodeChange = React.useCallback(async (value: string) => {
-    setLocalProjectCode(value)
-    onProjectCodeChange?.(value)
+  // 프로젝트 검색 함수 (공통 로직)
+  const searchProject = React.useCallback(async (projectCode: string) => {
+    if (!projectCode.trim()) {
+      setProjectInfo(null)
+      setProjectSearchStatus('idle')
+      setData([])
+      setPageCount(0)
+      return
+    }
 
-    // 프로젝트 코드가 입력된 경우 프로젝트 정보 조회
-    if (value.trim()) {
-      setProjectSearchStatus('searching') // 검색 시작 상태로 변경
+    setProjectSearchStatus('searching') // 검색 시작 상태로 변경
 
-      try {
-        // 1. projects 테이블에서 먼저 검색
-        let projectData = null
-        let searchSource = 'projects'
+    try {
+      // 1. projects 테이블에서 먼저 검색
+      let projectData: {
+        projectName?: string | null;
+        shipType?: string;
+        projectMsrm?: string | null;
+        projectHtDivision?: string | null;
+      } | null = null
+      let searchSource = 'projects'
 
+      try {
+        projectData = await getProjectInfoFromProjects(projectCode.trim())
+        // projects에서 찾았을 때만 즉시 성공 상태로 변경
+        setProjectSearchStatus('success-projects')
+      } catch {
+        // projects 테이블에 없는 경우 biddingProjects 테이블에서 검색
         try {
-          projectData = await getProjectInfoFromProjects(value.trim())
-          // projects에서 찾았을 때만 즉시 성공 상태로 변경
-          setProjectSearchStatus('success-projects')
-        } catch (projectsError) {
-          // projects 테이블에 없는 경우 biddingProjects 테이블에서 검색
-          try {
-            projectData = await getProjectInfoFromBiddingProjects(value.trim())
-            if (projectData) {
-              searchSource = 'bidding-projects'
-              setProjectSearchStatus('success-bidding') // bidding에서 찾았을 때 성공 상태로 변경
-            } else {
-              // 둘 다 실패한 경우에만 에러 상태로 변경
-              setProjectInfo(null)
-              setProjectSearchStatus('error')
-              setData([])
-              setPageCount(0)
-              toast.error("입력하신 프로젝트 코드를 찾을 수 없습니다.")
-              return
-            }
-          } catch (biddingError) {
-            // biddingProjects에서도 에러가 발생한 경우
+          projectData = await getProjectInfoFromBiddingProjects(projectCode.trim())
+          if (projectData) {
+            searchSource = 'bidding-projects'
+            setProjectSearchStatus('success-bidding') // bidding에서 찾았을 때 성공 상태로 변경
+          } else {
+            // 둘 다 실패한 경우에만 에러 상태로 변경
             setProjectInfo(null)
             setProjectSearchStatus('error')
             setData([])
@@ -332,39 +192,67 @@ export function ProjectAvlTable({
             toast.error("입력하신 프로젝트 코드를 찾을 수 없습니다.")
             return
           }
+        } catch {
+          // biddingProjects에서도 에러가 발생한 경우
+          setProjectInfo(null)
+          setProjectSearchStatus('error')
+          setData([])
+          setPageCount(0)
+          toast.error("입력하신 프로젝트 코드를 찾을 수 없습니다.")
+          return
         }
+      }
 
-        if (projectData) {
-          setProjectInfo({
-            projectName: projectData.projectName || "",
-            constructionSector: "조선", // 기본값으로 조선 설정 (필요시 로직 변경)
-            shipType: projectData.shipType || projectData.projectMsrm || "",
-            htDivision: projectData.projectHtDivision || ""
-          })
+      if (projectData) {
+        setProjectInfo({
+          projectName: projectData.projectName || "",
+          constructionSector: "조선", // 기본값으로 조선 설정 (필요시 로직 변경)
+          shipType: projectData.shipType || projectData.projectMsrm || "",
+          htDivision: projectData.projectHtDivision || ""
+        })
 
-          const sourceMessage = searchSource === 'projects' ? '프로젝트' : '견적프로젝트'
-          toast.success(`${sourceMessage}에서 프로젝트 정보를 성공적으로 불러왔습니다.`)
+        const sourceMessage = searchSource === 'projects' ? '프로젝트' : '견적프로젝트'
+        toast.success(`${sourceMessage}에서 프로젝트 정보를 성공적으로 불러왔습니다.`)
 
-          // 프로젝트 검증 성공 시 해당 프로젝트의 AVL 데이터 로드
-          loadData({})
-        }
-      } catch (error) {
-        console.error("프로젝트 정보 조회 실패:", error)
-        setProjectInfo(null)
-        setProjectSearchStatus('error')
-        setData([])
-        setPageCount(0)
-        toast.error("프로젝트 정보를 불러오는데 실패했습니다.")
+        // 검색 성공 시 AVL 데이터 로드 트리거
+        setIsSearchClicked(true)
       }
-    } else {
-      // 프로젝트 코드가 비어있는 경우 프로젝트 정보 초기화 및 데이터 클리어
+    } catch (error) {
+      console.error("프로젝트 정보 조회 실패:", error)
+      setProjectInfo(null)
+      setProjectSearchStatus('error')
+      setData([])
+      setPageCount(0)
+      toast.error("프로젝트 정보를 불러오는데 실패했습니다.")
+    }
+  }, [setIsSearchClicked])
+
+  // 프로젝트 코드 변경 핸들러 (입력만 처리)
+  const handleProjectCodeChange = React.useCallback((value: string) => {
+    setLocalProjectCode(value)
+    onProjectCodeChange?.(value)
+
+    // 입력이 변경되면 검색 상태를 idle로 초기화하고 검색 클릭 상태를 리셋
+    if (!value.trim()) {
       setProjectInfo(null)
       setProjectSearchStatus('idle')
+      setIsSearchClicked(false)
       setData([])
       setPageCount(0)
+    } else {
+      // 새로운 프로젝트 코드가 입력되면 검색 클릭 상태를 리셋 (다시 검색 버튼을 눌러야 함)
+      setIsSearchClicked(false)
     }
   }, [onProjectCodeChange])
 
+  // 프로젝트 검색 버튼 핸들러
+  const handleProjectSearch = React.useCallback(async () => {
+    // 검색 시 페이지를 1페이지로 리셋
+    setPagination(prev => ({ ...prev, pageIndex: 0 }))
+    // 프로젝트 정보 검색 (성공 시 내부에서 AVL 데이터 로드 트리거)
+    await searchProject(localProjectCode)
+  }, [localProjectCode, searchProject])
+
   // 행 추가 핸들러
   const handleAddRow = React.useCallback(() => {
     if (!localProjectCode.trim()) {
@@ -382,16 +270,11 @@ export function ProjectAvlTable({
   // 다이얼로그에서 항목 추가 핸들러
   const handleAddItem = React.useCallback(async (itemData: Omit<AvlVendorInfoInput, 'avlListId'>) => {
     try {
-      // AVL 리스트 ID 확인
-      if (!avlListId) {
-        toast.error("AVL 리스트가 선택되지 않았습니다.")
-        return
-      }
-
-      // DB에 실제 저장할 데이터 준비
+      // DB에 실제 저장할 데이터 준비 (avlListId는 나중에 최종 확정 시 설정)
       const saveData: AvlVendorInfoInput = {
         ...itemData,
-        avlListId: avlListId // 현재 AVL 리스트 ID 설정
+        projectCode: localProjectCode, // 현재 프로젝트 코드 저장
+        avlListId: avlListId || undefined // 있으면 설정, 없으면 undefined (null로 저장됨)
       }
 
       // DB에 저장
@@ -409,7 +292,7 @@ export function ProjectAvlTable({
       console.error("항목 추가 실패:", error)
       toast.error("항목 추가 중 오류가 발생했습니다.")
     }
-  }, [avlListId, loadData])
+  }, [avlListId, loadData, localProjectCode])
 
   // 다이얼로그에서 항목 수정 핸들러
   const handleUpdateItem = React.useCallback(async (id: number, itemData: Omit<AvlVendorInfoInput, 'avlListId'>) => {
@@ -447,21 +330,43 @@ export function ProjectAvlTable({
     getFilteredRowModel: getFilteredRowModel(),
     manualPagination: true,
     pageCount,
-    initialState: {
-      pagination: {
-        pageSize: 10,
-      },
+    state: {
+      pagination,
     },
     onPaginationChange: (updater) => {
-      const newState = typeof updater === 'function' ? updater(table.getState().pagination) : updater
-      loadData({
-        page: newState.pageIndex + 1,
-        perPage: newState.pageSize,
+      // 페이지네이션 상태 업데이트
+      const newPaginationState = typeof updater === 'function' ? updater(pagination) : updater
+
+      console.log('ProjectAvlTable - Pagination changed:', {
+        currentState: pagination,
+        newPaginationState,
+        localProjectCode,
+        isSearchClicked,
+        willLoadData: localProjectCode && isSearchClicked
       })
+
+      setPagination(newPaginationState)
+
+      if (localProjectCode && isSearchClicked) {
+        const apiParams = {
+          page: newPaginationState.pageIndex + 1,
+          perPage: newPaginationState.pageSize,
+        }
+        console.log('ProjectAvlTable - Loading data with params:', apiParams)
+        loadData(apiParams)
+      }
     },
     meta: tableMeta,
   })
 
+  // 외부에서 선택된 ID들을 가져올 수 있도록 ref에 메소드 노출
+  useImperativeHandle(ref, () => ({
+    getSelectedIds: () => {
+      const selectedRows = table.getFilteredSelectedRowModel().rows
+      return selectedRows.map(row => row.original.id)
+    }
+  }))
+
     // 항목 수정 핸들러 (버튼 클릭)
   const handleEditItem = React.useCallback(() => {
     const selectedRows = table.getFilteredSelectedRowModel().rows
@@ -510,11 +415,79 @@ export function ProjectAvlTable({
     }
   }, [table, loadData])
 
+  // 최종 확정 핸들러
+  const handleFinalizeAvl = React.useCallback(async () => {
+    // 1. 필수 조건 검증
+    if (!localProjectCode.trim()) {
+      toast.error("프로젝트 코드를 먼저 입력해주세요.")
+      return
+    }
+
+    if (!projectInfo) {
+      toast.error("프로젝트 정보를 불러올 수 없습니다. 프로젝트 코드를 다시 확인해주세요.")
+      return
+    }
+
+    if (data.length === 0) {
+      toast.error("확정할 AVL 벤더 정보가 없습니다.")
+      return
+    }
+
+    // 2. 사용자 확인
+    const confirmed = window.confirm(
+      `현재 프로젝트(${localProjectCode})의 AVL을 최종 확정하시겠습니까?\n\n` +
+      `- 프로젝트명: ${projectInfo.projectName}\n` +
+      `- 벤더 정보: ${data.length}개\n` +
+      `- 공사부문: ${projectInfo.constructionSector}\n` +
+      `- 선종: ${projectInfo.shipType}\n` +
+      `- H/T 구분: ${projectInfo.htDivision}\n\n` +
+      `확정 후에는 수정이 어려울 수 있습니다.`
+    )
+
+    if (!confirmed) return
+
+    try {
+      // 3. 현재 데이터의 모든 ID 수집
+      const avlVendorInfoIds = data.map(item => item.id)
+
+      // 4. 최종 확정 실행
+      const result = await finalizeProjectAvl(
+        localProjectCode,
+        projectInfo,
+        avlVendorInfoIds,
+        sessionData?.user?.name || ""
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        
+        // 5. 데이터 새로고침
+        loadData({})
+        
+        // 6. 선택 해제
+        table.toggleAllPageRowsSelected(false)
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error("AVL 최종 확정 실패:", error)
+      toast.error("AVL 최종 확정 중 오류가 발생했습니다.")
+    }
+  }, [localProjectCode, projectInfo, data, table, loadData, sessionData?.user?.name])
+
+  // 선택된 행 개수 (안정적인 계산을 위해 useMemo 사용)
+  const selectedRows = table.getFilteredSelectedRowModel().rows
+  const selectedRowCount = useMemo(() => {
+    const count = selectedRows.length
+    console.log('ProjectAvlTable - selectedRowCount calculated:', count)
+    return count
+  }, [selectedRows])
+
   // 선택 상태 변경 시 콜백 호출
-  React.useEffect(() => {
-    const selectedRows = table.getFilteredSelectedRowModel().rows
-    onSelectionChange?.(selectedRows.length)
-  }, [table.getFilteredSelectedRowModel().rows.length, onSelectionChange])
+  useLayoutEffect(() => {
+    console.log('ProjectAvlTable - onSelectionChange called with count:', selectedRowCount)
+    onSelectionChange?.(selectedRowCount)
+  }, [selectedRowCount, onSelectionChange])
 
   // 선택 해제 요청이 오면 모든 선택 해제
   React.useEffect(() => {
@@ -540,7 +513,7 @@ export function ProjectAvlTable({
             >
               항목 수정
             </Button>
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            {/* <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
               파일 업로드
             </Button>
             <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
@@ -548,13 +521,18 @@ export function ProjectAvlTable({
             </Button>
             <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
               강제 매핑
-            </Button>
+            </Button> */}
             <Button variant="outline" size="sm" onClick={handleDeleteItems}>
               항목 삭제
             </Button>
 
             {/* 최종 확정 버튼 */}
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            <Button 
+              variant="outline" 
+              size="sm" 
+              onClick={handleFinalizeAvl}
+              disabled={!localProjectCode.trim() || !projectInfo || data.length === 0}
+            >
               최종 확정
             </Button>
           </div>
@@ -565,140 +543,84 @@ export function ProjectAvlTable({
       <div className="mb-4 p-4 border rounded-lg bg-muted/50">
         <div className="flex gap-4 overflow-x-auto pb-2">
             {/* 프로젝트 코드 */}
-            <div className="space-y-2 min-w-[250px] flex-shrink-0">
-              <label className={`text-sm font-medium ${
-                projectSearchStatus === 'error' ? 'text-red-600' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'text-green-600' :
-                projectSearchStatus === 'searching' ? 'text-blue-600' :
-                'text-muted-foreground'
-              }`}>
-                프로젝트 코드
-                {projectSearchStatus === 'success-projects' && <span className="ml-1 text-xs">(프로젝트)</span>}
-                {projectSearchStatus === 'success-bidding' && <span className="ml-1 text-xs">(견적프로젝트)</span>}
-                {projectSearchStatus === 'searching' && <span className="ml-1 text-xs">(검색 중...)</span>}
-                {projectSearchStatus === 'error' && <span className="ml-1 text-xs">(찾을 수 없음)</span>}
-              </label>
-              <Input
-                value={localProjectCode}
-                onChange={(e) => handleProjectCodeChange(e.target.value)}
-                placeholder="프로젝트 코드를 입력하세요"
-                // disabled={projectSearchStatus === 'searching'}
-                className={`h-8 text-sm ${
-                  projectSearchStatus === 'error' ? 'border-red-300 focus:border-red-500 focus:ring-red-500/20' :
-                  projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-300 focus:border-green-500 focus:ring-green-500/20' :
-                  projectSearchStatus === 'searching' ? 'border-blue-300 focus:border-blue-500 focus:ring-blue-500/20' :
-                  ''
-                }`}
-              />
+            <div className="flex flex-col gap-1 min-w-[200px]">
+              <label className="text-sm font-medium">프로젝트 코드</label>
+              <div className="flex gap-2">
+                <div className="flex-1">
+                  <input
+                    type="text"
+                    value={localProjectCode}
+                    onChange={(e) => handleProjectCodeChange(e.target.value)}
+                    placeholder="프로젝트 코드를 입력하세요"
+                    className={`flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 ${
+                      projectSearchStatus === 'error' ? 'border-red-500' :
+                      projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-500' :
+                      projectSearchStatus === 'searching' ? 'border-blue-500' : ''
+                    }`}
+                    disabled={projectSearchStatus === 'searching'}
+                  />
+                  {projectSearchStatus !== 'idle' && (
+                    <div className="text-xs mt-1 text-muted-foreground">
+                      {projectSearchStatus === 'success-projects' ? '(프로젝트)' :
+                       projectSearchStatus === 'success-bidding' ? '(견적프로젝트)' :
+                       projectSearchStatus === 'searching' ? '(검색 중...)' :
+                       projectSearchStatus === 'error' ? '(찾을 수 없음)' :
+                       undefined}
+                    </div>
+                  )}
+                </div>
+                <Button
+                  variant="outline"
+                  size="sm"
+                  onClick={handleProjectSearch}
+                  disabled={!localProjectCode.trim() || projectSearchStatus === 'searching'}
+                  className="px-3 h-9"
+                >
+                  {projectSearchStatus === 'searching' ? '검색 중...' : '검색'}
+                </Button>
+              </div>
             </div>
 
             {/* 프로젝트명 */}
-            <div className="space-y-2 min-w-[250px] flex-shrink-0">
-              <label className={`text-sm font-medium ${
-                projectSearchStatus === 'error' ? 'text-red-600' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'text-green-600' :
-                projectSearchStatus === 'searching' ? 'text-blue-600' :
-                'text-muted-foreground'
-              }`}>
-                프로젝트명
-                {projectSearchStatus === 'searching' && <span className="ml-1 text-xs">(조회 중...)</span>}
-              </label>
-              <div className={`text-sm font-medium min-h-[32px] flex items-center border rounded-md px-3 bg-background ${
-                projectSearchStatus === 'error' ? 'border-red-300' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-300' :
-                projectSearchStatus === 'searching' ? 'border-blue-300' :
-                'border-input'
-              }`}>
-                {projectSearchStatus === 'searching' ? '조회 중...' : (projectInfo?.projectName || '-')}
-              </div>
-            </div>
+            <ProjectDisplayField
+              label="프로젝트명"
+              value={projectInfo?.projectName || ''}
+              status={projectSearchStatus}
+              minWidth="250px"
+            />
 
             {/* 원본파일 */}
-            <div className="space-y-2 min-w-[200px] flex-shrink-0">
-              <label className="text-sm font-medium text-muted-foreground">원본파일</label>
-              <div className="flex items-center gap-2 min-h-[32px]">
-                {originalFile ? (
-                  <span className="text-sm text-blue-600">{originalFile}</span>
-                ) : (
-                  <div className="relative">
-                    <input
-                      type="file"
-                      onChange={handleFileUpload}
-                      className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
-                      accept=".xlsx,.xls,.csv"
-                    />
-                    <Button variant="outline" size="sm" className="text-xs">
-                      파일 선택
-                    </Button>
-                  </div>
-                )}
-              </div>
-            </div>
+            <ProjectFileField
+              label="원본파일"
+              originalFile={originalFile}
+              onFileUpload={handleFileUpload}
+            />
 
             {/* 공사부문 */}
-            <div className="space-y-2 min-w-[120px] flex-shrink-0">
-              <label className={`text-sm font-medium ${
-                projectSearchStatus === 'error' ? 'text-red-600' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'text-green-600' :
-                projectSearchStatus === 'searching' ? 'text-blue-600' :
-                'text-muted-foreground'
-              }`}>
-                공사부문
-                {projectSearchStatus === 'searching' && <span className="ml-1 text-xs">(조회 중...)</span>}
-              </label>
-              <div className={`text-sm font-medium min-h-[32px] flex items-center border rounded-md px-3 bg-background ${
-                projectSearchStatus === 'error' ? 'border-red-300' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-300' :
-                projectSearchStatus === 'searching' ? 'border-blue-300' :
-                'border-input'
-              }`}>
-                {projectSearchStatus === 'searching' ? '조회 중...' : (projectInfo?.constructionSector || '-')}
-              </div>
-            </div>
+            <ProjectDisplayField
+              label="공사부문"
+              value={projectInfo?.constructionSector || ''}
+              status={projectSearchStatus}
+            />
 
             {/* 선종 */}
-            <div className="space-y-2 min-w-[120px] flex-shrink-0">
-              <label className={`text-sm font-medium ${
-                projectSearchStatus === 'error' ? 'text-red-600' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'text-green-600' :
-                projectSearchStatus === 'searching' ? 'text-blue-600' :
-                'text-muted-foreground'
-              }`}>
-                선종
-                {projectSearchStatus === 'searching' && <span className="ml-1 text-xs">(조회 중...)</span>}
-              </label>
-              <div className={`text-sm font-medium min-h-[32px] flex items-center border rounded-md px-3 bg-background ${
-                projectSearchStatus === 'error' ? 'border-red-300' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-300' :
-                projectSearchStatus === 'searching' ? 'border-blue-300' :
-                'border-input'
-              }`}>
-                {projectSearchStatus === 'searching' ? '조회 중...' : (projectInfo?.shipType || '-')}
-              </div>
-            </div>
+            <ProjectDisplayField
+              label="선종"
+              value={projectInfo?.shipType || ''}
+              status={projectSearchStatus}
+            />
 
             {/* H/T 구분 */}
-            <div className="space-y-2 min-w-[140px] flex-shrink-0">
-              <label className={`text-sm font-medium ${
-                projectSearchStatus === 'error' ? 'text-red-600' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'text-green-600' :
-                projectSearchStatus === 'searching' ? 'text-blue-600' :
-                'text-muted-foreground'
-              }`}>
-                H/T 구분
-                {projectSearchStatus === 'searching' && <span className="ml-1 text-xs">(조회 중...)</span>}
-              </label>
-              <div className={`text-sm font-medium min-h-[32px] flex items-center border rounded-md px-3 bg-background ${
-                projectSearchStatus === 'error' ? 'border-red-300' :
-                projectSearchStatus === 'success-projects' || projectSearchStatus === 'success-bidding' ? 'border-green-300' :
-                projectSearchStatus === 'searching' ? 'border-blue-300' :
-                'border-input'
-              }`}>
-                {projectSearchStatus === 'searching' ? '조회 중...' :
-                 (projectInfo?.htDivision === 'H' ? 'Hull (H)' :
-                  projectInfo?.htDivision === 'T' ? 'Topside (T)' : '-')}
-              </div>
-            </div>
+            <ProjectDisplayField
+              label="H/T 구분"
+              value={projectInfo?.htDivision || ''}
+              status={projectSearchStatus}
+              minWidth="140px"
+              formatter={(value) =>
+                value === 'H' ? 'Hull (H)' :
+                value === 'T' ? 'Topside (T)' : '-'
+              }
+            />
         </div>
       </div>
 
@@ -707,7 +629,7 @@ export function ProjectAvlTable({
       </div>
 
       {/* 행 추가/수정 다이얼로그 */}
-      <ProjectAvlAddDialog
+      <AvlVendorAddAndModifyDialog
         open={isAddDialogOpen}
         onOpenChange={(open) => {
           setIsAddDialogOpen(open)
@@ -718,7 +640,11 @@ export function ProjectAvlTable({
         onAddItem={handleAddItem}
         editingItem={editingItem}
         onUpdateItem={handleUpdateItem}
+        isTemplate={false} // 프로젝트 AVL 모드
+        initialProjectCode={localProjectCode}
       />
     </div>
   )
-}
+})
+
+ProjectAvlTable.displayName = "ProjectAvlTable"
diff --git a/lib/avl/table/standard-avl-add-dialog.tsx b/lib/avl/table/standard-avl-add-dialog.tsx
new file mode 100644
index 00000000..9e8b016c
--- /dev/null
+++ b/lib/avl/table/standard-avl-add-dialog.tsx
@@ -0,0 +1,960 @@
+"use client"
+
+import * as React from "react"
+import {
+  Dialog,
+  DialogContent,
+  DialogDescription,
+  DialogFooter,
+  DialogHeader,
+  DialogTitle,
+  DialogTrigger,
+} from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
+import { Input } from "@/components/ui/input"
+import { Label } from "@/components/ui/label"
+import { Checkbox } from "@/components/ui/checkbox"
+import { Textarea } from "@/components/ui/textarea"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import { toast } from "sonner"
+import type { AvlVendorInfoInput, AvlDetailItem } from "../types"
+
+interface StandardAvlAddDialogProps {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+  onAddItem: (item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void>
+  editingItem?: AvlDetailItem // 수정할 항목 (없으면 추가 모드)
+  onUpdateItem?: (id: number, item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void> // 수정 핸들러
+  // 검색 조건에서 선택한 값들을 초기값으로 사용
+  initialConstructionSector?: string
+  initialShipType?: string
+  initialAvlKind?: string
+  initialHtDivision?: string
+}
+
+export function StandardAvlAddDialog({
+  open,
+  onOpenChange,
+  onAddItem,
+  editingItem,
+  onUpdateItem,
+  initialConstructionSector,
+  initialShipType,
+  initialAvlKind,
+  initialHtDivision
+}: StandardAvlAddDialogProps) {
+  const [formData, setFormData] = React.useState<Omit<AvlVendorInfoInput, 'avlListId'>>({
+    // 표준 AVL용 기본 설정
+    isTemplate: true,
+
+    // 표준 AVL 필수 필드들 (검색 조건에서 선택한 값들로 초기화)
+    constructionSector: initialConstructionSector || "",
+    shipType: initialShipType || "",
+    avlKind: initialAvlKind || "",
+    htDivision: initialHtDivision || "",
+
+    // 설계 정보
+    equipBulkDivision: "EQUIP",
+    disciplineCode: "",
+    disciplineName: "",
+
+    // 자재 정보
+    materialNameCustomerSide: "",
+
+    // 패키지 정보
+    packageCode: "",
+    packageName: "",
+
+    // 자재그룹 정보
+    materialGroupCode: "",
+    materialGroupName: "",
+
+    // 협력업체 정보
+    vendorName: "",
+    vendorCode: "",
+
+    // AVL 정보
+    avlVendorName: "",
+    tier: "",
+
+    // 제안방향
+    ownerSuggestion: false,
+    shiSuggestion: false,
+
+    // 위치 정보
+    headquarterLocation: "",
+    manufacturingLocation: "",
+
+    // FA 정보
+    faTarget: false,
+    faStatus: "",
+
+    // Agent 정보
+    isAgent: false,
+
+    // 계약 서명주체
+    contractSignerName: "",
+    contractSignerCode: "",
+
+    // SHI Qualification
+    shiAvl: false,
+    shiBlacklist: false,
+    shiBcc: false,
+
+    // 기술영업 견적결과
+    salesQuoteNumber: "",
+    quoteCode: "",
+    salesVendorInfo: "",
+    salesCountry: "",
+    totalAmount: "",
+    quoteReceivedDate: "",
+
+    // 업체 실적 현황
+    recentQuoteDate: "",
+    recentQuoteNumber: "",
+    recentOrderDate: "",
+    recentOrderNumber: "",
+
+    // 기타
+    remarks: ""
+  })
+
+  // 수정 모드일 때 폼 데이터 초기화
+  React.useEffect(() => {
+    if (editingItem) {
+      setFormData({
+        // 표준 AVL용 기본 설정
+        isTemplate: true,
+
+        // 표준 AVL 필수 필드들 (기존 값 우선, 없으면 검색 조건 값 사용)
+        constructionSector: editingItem.constructionSector || initialConstructionSector || "",
+        shipType: editingItem.shipType || initialShipType || "",
+        avlKind: editingItem.avlKind || initialAvlKind || "",
+        htDivision: editingItem.htDivision || initialHtDivision || "",
+
+        // 설계 정보
+        equipBulkDivision: editingItem.equipBulkDivision === "EQUIP" ? "EQUIP" : "BULK",
+        disciplineCode: editingItem.disciplineCode || "",
+        disciplineName: editingItem.disciplineName || "",
+
+        // 자재 정보
+        materialNameCustomerSide: editingItem.materialNameCustomerSide || "",
+
+        // 패키지 정보
+        packageCode: editingItem.packageCode || "",
+        packageName: editingItem.packageName || "",
+
+        // 자재그룹 정보
+        materialGroupCode: editingItem.materialGroupCode || "",
+        materialGroupName: editingItem.materialGroupName || "",
+
+        // 협력업체 정보
+        vendorName: editingItem.vendorName || "",
+        vendorCode: editingItem.vendorCode || "",
+
+        // AVL 정보
+        avlVendorName: editingItem.avlVendorName || "",
+        tier: editingItem.tier || "",
+
+        // 제안방향
+        ownerSuggestion: editingItem.ownerSuggestion || false,
+        shiSuggestion: editingItem.shiSuggestion || false,
+
+        // 위치 정보
+        headquarterLocation: editingItem.headquarterLocation || "",
+        manufacturingLocation: editingItem.manufacturingLocation || "",
+
+        // FA 정보
+        faTarget: editingItem.faTarget || false,
+        faStatus: editingItem.faStatus || "",
+
+        // Agent 정보
+        isAgent: editingItem.isAgent || false,
+
+        // 계약 서명주체
+        contractSignerName: editingItem.contractSignerName || "",
+        contractSignerCode: editingItem.contractSignerCode || "",
+
+        // SHI Qualification
+        shiAvl: editingItem.shiAvl || false,
+        shiBlacklist: editingItem.shiBlacklist || false,
+        shiBcc: editingItem.shiBcc || false,
+
+        // 기술영업 견적결과
+        salesQuoteNumber: editingItem.salesQuoteNumber || "",
+        quoteCode: editingItem.quoteCode || "",
+        salesVendorInfo: editingItem.salesVendorInfo || "",
+        salesCountry: editingItem.salesCountry || "",
+        totalAmount: editingItem.totalAmount || "",
+        quoteReceivedDate: editingItem.quoteReceivedDate || "",
+
+        // 업체 실적 현황
+        recentQuoteDate: editingItem.recentQuoteDate || "",
+        recentQuoteNumber: editingItem.recentQuoteNumber || "",
+        recentOrderDate: editingItem.recentOrderDate || "",
+        recentOrderNumber: editingItem.recentOrderNumber || "",
+
+        // 기타
+        remarks: editingItem.remarks || ""
+      })
+    }
+  }, [editingItem, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision])
+
+  // 다이얼로그가 열릴 때 초기값 재설정 (수정 모드가 아닐 때만)
+  React.useEffect(() => {
+    if (open && !editingItem) {
+      setFormData(prev => ({
+        ...prev,
+        constructionSector: initialConstructionSector || "",
+        shipType: initialShipType || "",
+        avlKind: initialAvlKind || "",
+        htDivision: initialHtDivision || "",
+      }))
+    }
+  }, [open, editingItem, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision])
+
+  const handleSubmit = async () => {
+    // 필수 필드 검증 (표준 AVL용)
+    if (!formData.constructionSector || !formData.shipType || !formData.avlKind || !formData.htDivision) {
+      toast.error("공사부문, 선종, AVL종류, H/T 구분은 필수 입력 항목입니다.")
+      return
+    }
+
+    if (!formData.disciplineName || !formData.materialNameCustomerSide) {
+      toast.error("설계공종과 고객사 AVL 자재명은 필수 입력 항목입니다.")
+      return
+    }
+
+    try {
+      if (editingItem && onUpdateItem) {
+        // 수정 모드
+        await onUpdateItem(editingItem.id, formData)
+      } else {
+        // 추가 모드
+        await onAddItem(formData)
+      }
+
+      // 폼 초기화 (onAddItem에서 성공적으로 처리된 경우에만)
+      setFormData({
+        // 표준 AVL용 기본 설정
+        isTemplate: true,
+
+        // 표준 AVL 필수 필드들
+        constructionSector: "",
+        shipType: "",
+        avlKind: "",
+        htDivision: "",
+
+        // 설계 정보
+        equipBulkDivision: "EQUIP",
+        disciplineCode: "",
+        disciplineName: "",
+
+        // 자재 정보
+        materialNameCustomerSide: "",
+
+        // 패키지 정보
+        packageCode: "",
+        packageName: "",
+
+        // 자재그룹 정보
+        materialGroupCode: "",
+        materialGroupName: "",
+
+        // 협력업체 정보
+        vendorName: "",
+        vendorCode: "",
+
+        // AVL 정보
+        avlVendorName: "",
+        tier: "",
+
+        // 제안방향
+        ownerSuggestion: false,
+        shiSuggestion: false,
+
+        // 위치 정보
+        headquarterLocation: "",
+        manufacturingLocation: "",
+
+        // FA 정보
+        faTarget: false,
+        faStatus: "",
+
+        // Agent 정보
+        isAgent: false,
+
+        // 계약 서명주체
+        contractSignerName: "",
+        contractSignerCode: "",
+
+        // SHI Qualification
+        shiAvl: false,
+        shiBlacklist: false,
+        shiBcc: false,
+
+        // 기술영업 견적결과
+        salesQuoteNumber: "",
+        quoteCode: "",
+        salesVendorInfo: "",
+        salesCountry: "",
+        totalAmount: "",
+        quoteReceivedDate: "",
+
+        // 업체 실적 현황
+        recentQuoteDate: "",
+        recentQuoteNumber: "",
+        recentOrderDate: "",
+        recentOrderNumber: "",
+
+        // 기타
+        remarks: ""
+      } as Omit<AvlVendorInfoInput, 'avlListId'>)
+
+      onOpenChange(false)
+    } catch (error) {
+      // 에러 처리는 onAddItem에서 담당하므로 여기서는 아무것도 하지 않음
+    }
+  }
+
+  const handleCancel = () => {
+    setFormData({
+      // 표준 AVL용 기본 설정
+      isTemplate: true,
+
+      // 표준 AVL 필수 필드들
+      constructionSector: "",
+      shipType: "",
+      avlKind: "",
+      htDivision: "",
+
+      // 설계 정보
+      equipBulkDivision: "EQUIP",
+      disciplineCode: "",
+      disciplineName: "",
+
+      // 자재 정보
+      materialNameCustomerSide: "",
+
+      // 패키지 정보
+      packageCode: "",
+      packageName: "",
+
+      // 자재그룹 정보
+      materialGroupCode: "",
+      materialGroupName: "",
+
+      // 협력업체 정보
+      vendorName: "",
+      vendorCode: "",
+
+      // AVL 정보
+      avlVendorName: "",
+      tier: "",
+
+      // 제안방향
+      ownerSuggestion: false,
+      shiSuggestion: false,
+
+      // 위치 정보
+      headquarterLocation: "",
+      manufacturingLocation: "",
+
+      // FA 정보
+      faTarget: false,
+      faStatus: "",
+
+      // Agent 정보
+      isAgent: false,
+
+      // 계약 서명주체
+      contractSignerName: "",
+      contractSignerCode: "",
+
+      // SHI Qualification
+      shiAvl: false,
+      shiBlacklist: false,
+      shiBcc: false,
+
+      // 기술영업 견적결과
+      salesQuoteNumber: "",
+      quoteCode: "",
+      salesVendorInfo: "",
+      salesCountry: "",
+      totalAmount: "",
+      quoteReceivedDate: "",
+
+      // 업체 실적 현황
+      recentQuoteDate: "",
+      recentQuoteNumber: "",
+      recentOrderDate: "",
+      recentOrderNumber: "",
+
+      // 기타
+      remarks: ""
+    } as Omit<AvlVendorInfoInput, 'avlListId'>)
+    onOpenChange(false)
+  }
+
+  // 선종 옵션들 (공사부문에 따라 다름)
+  const getShipTypeOptions = (constructionSector: string) => {
+    if (constructionSector === "조선") {
+      return [
+        { value: "A-max", label: "A-max" },
+        { value: "S-max", label: "S-max" },
+        { value: "VLCC", label: "VLCC" },
+        { value: "LNGC", label: "LNGC" },
+        { value: "CONT", label: "CONT" },
+      ]
+    } else if (constructionSector === "해양") {
+      return [
+        { value: "FPSO", label: "FPSO" },
+        { value: "FLNG", label: "FLNG" },
+        { value: "FPU", label: "FPU" },
+        { value: "Platform", label: "Platform" },
+        { value: "WTIV", label: "WTIV" },
+        { value: "GOM", label: "GOM" },
+      ]
+    } else {
+      return []
+    }
+  }
+
+  const shipTypeOptions = getShipTypeOptions(formData.constructionSector)
+
+  return (
+    <Dialog open={open} onOpenChange={onOpenChange}>
+      <DialogContent className="sm:max-w-[800px] max-h-[90vh] overflow-y-auto">
+        <DialogHeader>
+          <DialogTitle>{editingItem ? "표준 AVL 항목 수정" : "표준 AVL 항목 추가"}</DialogTitle>
+          <DialogDescription>
+            {editingItem
+              ? "표준 AVL 항목을 수정합니다. 필수 항목을 입력해주세요."
+              : "새로운 표준 AVL 항목을 추가합니다. 필수 항목을 입력해주세요."
+            } * 표시된 항목은 필수 입력사항입니다.
+          </DialogDescription>
+        </DialogHeader>
+        <div className="space-y-6 py-4">
+          {/* 표준 AVL 기본 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">표준 AVL 기본 정보 *</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="constructionSector">공사부문 *</Label>
+                <Select
+                  value={formData.constructionSector}
+                  onValueChange={(value) => {
+                    setFormData(prev => ({
+                      ...prev,
+                      constructionSector: value,
+                      shipType: "" // 공사부문 변경 시 선종 초기화
+                    }))
+                  }}
+                >
+                  <SelectTrigger>
+                    <SelectValue placeholder="공사부문을 선택하세요" />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="조선">조선</SelectItem>
+                    <SelectItem value="해양">해양</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="shipType">선종 *</Label>
+                <Select
+                  value={formData.shipType}
+                  onValueChange={(value) =>
+                    setFormData(prev => ({ ...prev, shipType: value }))
+                  }
+                  disabled={!formData.constructionSector}
+                >
+                  <SelectTrigger>
+                    <SelectValue placeholder="선종을 선택하세요" />
+                  </SelectTrigger>
+                  <SelectContent>
+                    {shipTypeOptions.map((option) => (
+                      <SelectItem key={option.value} value={option.value}>
+                        {option.label}
+                      </SelectItem>
+                    ))}
+                  </SelectContent>
+                </Select>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="avlKind">AVL종류 *</Label>
+                <Select
+                  value={formData.avlKind}
+                  onValueChange={(value) =>
+                    setFormData(prev => ({ ...prev, avlKind: value }))
+                  }
+                >
+                  <SelectTrigger>
+                    <SelectValue placeholder="AVL종류를 선택하세요" />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="Nearshore">Nearshore</SelectItem>
+                    <SelectItem value="Offshore">Offshore</SelectItem>
+                    <SelectItem value="IOC">IOC</SelectItem>
+                    <SelectItem value="NOC">NOC</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="htDivision">H/T 구분 *</Label>
+                <Select
+                  value={formData.htDivision}
+                  onValueChange={(value) =>
+                    setFormData(prev => ({ ...prev, htDivision: value }))
+                  }
+                >
+                  <SelectTrigger>
+                    <SelectValue placeholder="H/T 구분을 선택하세요" />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="공통">공통</SelectItem>
+                    <SelectItem value="H">Hull (H)</SelectItem>
+                    <SelectItem value="T">Topside (T)</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+            </div>
+          </div>
+
+          {/* 기본 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기본 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="equipBulkDivision">EQUIP/BULK 구분</Label>
+                <Select
+                  value={formData.equipBulkDivision}
+                  onValueChange={(value: "EQUIP" | "BULK") =>
+                    setFormData(prev => ({ ...prev, equipBulkDivision: value }))
+                  }
+                >
+                  <SelectTrigger>
+                    <SelectValue />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="EQUIP">EQUIP</SelectItem>
+                    <SelectItem value="BULK">BULK</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="disciplineCode">설계공종코드</Label>
+                <Input
+                  id="disciplineCode"
+                  value={formData.disciplineCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, disciplineCode: e.target.value }))}
+                  placeholder="설계공종코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2 col-span-2">
+                <Label htmlFor="disciplineName">설계공종명 *</Label>
+                <Input
+                  id="disciplineName"
+                  value={formData.disciplineName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, disciplineName: e.target.value }))}
+                  placeholder="설계공종명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2 col-span-2">
+                <Label htmlFor="materialNameCustomerSide">고객사 AVL 자재명 *</Label>
+                <Input
+                  id="materialNameCustomerSide"
+                  value={formData.materialNameCustomerSide}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialNameCustomerSide: e.target.value }))}
+                  placeholder="고객사 AVL 자재명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 패키지 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">패키지 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="packageCode">패키지 코드</Label>
+                <Input
+                  id="packageCode"
+                  value={formData.packageCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, packageCode: e.target.value }))}
+                  placeholder="패키지 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="packageName">패키지 명</Label>
+                <Input
+                  id="packageName"
+                  value={formData.packageName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, packageName: e.target.value }))}
+                  placeholder="패키지 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 자재그룹 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">자재그룹 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="materialGroupCode">자재그룹 코드</Label>
+                <Input
+                  id="materialGroupCode"
+                  value={formData.materialGroupCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialGroupCode: e.target.value }))}
+                  placeholder="자재그룹 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="materialGroupName">자재그룹 명</Label>
+                <Input
+                  id="materialGroupName"
+                  value={formData.materialGroupName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, materialGroupName: e.target.value }))}
+                  placeholder="자재그룹 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 협력업체 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">협력업체 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="vendorCode">협력업체 코드</Label>
+                <Input
+                  id="vendorCode"
+                  value={formData.vendorCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, vendorCode: e.target.value }))}
+                  placeholder="협력업체 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="vendorName">협력업체 명</Label>
+                <Input
+                  id="vendorName"
+                  value={formData.vendorName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, vendorName: e.target.value }))}
+                  placeholder="협력업체 명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="avlVendorName">AVL 등재업체명</Label>
+                <Input
+                  id="avlVendorName"
+                  value={formData.avlVendorName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, avlVendorName: e.target.value }))}
+                  placeholder="AVL 등재업체명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="tier">등급 (Tier)</Label>
+                <Input
+                  id="tier"
+                  value={formData.tier}
+                  onChange={(e) => setFormData(prev => ({ ...prev, tier: e.target.value }))}
+                  placeholder="등급을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 제안방향 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">제안방향</h4>
+            <div className="flex gap-6">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="ownerSuggestion"
+                  checked={formData.ownerSuggestion}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, ownerSuggestion: !!checked }))
+                  }
+                />
+                <Label htmlFor="ownerSuggestion">선주제안</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiSuggestion"
+                  checked={formData.shiSuggestion}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiSuggestion: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiSuggestion">SHI 제안</Label>
+              </div>
+            </div>
+          </div>
+
+          {/* 위치 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">위치 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="headquarterLocation">본사 위치 (국가)</Label>
+                <Input
+                  id="headquarterLocation"
+                  value={formData.headquarterLocation}
+                  onChange={(e) => setFormData(prev => ({ ...prev, headquarterLocation: e.target.value }))}
+                  placeholder="본사 위치를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="manufacturingLocation">제작/선적지 (국가)</Label>
+                <Input
+                  id="manufacturingLocation"
+                  value={formData.manufacturingLocation}
+                  onChange={(e) => setFormData(prev => ({ ...prev, manufacturingLocation: e.target.value }))}
+                  placeholder="제작/선적지를 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* FA 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">FA 정보</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="faTarget"
+                  checked={formData.faTarget}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, faTarget: !!checked }))
+                  }
+                />
+                <Label htmlFor="faTarget">FA 대상</Label>
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="faStatus">FA 현황</Label>
+                <Input
+                  id="faStatus"
+                  value={formData.faStatus}
+                  onChange={(e) => setFormData(prev => ({ ...prev, faStatus: e.target.value }))}
+                  placeholder="FA 현황을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* Agent 정보 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">Agent 정보</h4>
+            <div className="flex items-center space-x-2">
+              <Checkbox
+                id="isAgent"
+                checked={formData.isAgent}
+                onCheckedChange={(checked) =>
+                  setFormData(prev => ({ ...prev, isAgent: !!checked }))
+                }
+              />
+              <Label htmlFor="isAgent">Agent 여부</Label>
+            </div>
+          </div>
+
+          {/* 계약 서명주체 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">계약 서명주체</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="contractSignerCode">계약서명주체 코드</Label>
+                <Input
+                  id="contractSignerCode"
+                  value={formData.contractSignerCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, contractSignerCode: e.target.value }))}
+                  placeholder="계약서명주체 코드를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="contractSignerName">계약서명주체 명</Label>
+                <Input
+                  id="contractSignerName"
+                  value={formData.contractSignerName}
+                  onChange={(e) => setFormData(prev => ({ ...prev, contractSignerName: e.target.value }))}
+                  placeholder="계약서명주체 명을 입력하세요"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* SHI Qualification */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">SHI Qualification</h4>
+            <div className="flex gap-6">
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiAvl"
+                  checked={formData.shiAvl}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiAvl: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiAvl">AVL</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiBlacklist"
+                  checked={formData.shiBlacklist}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiBlacklist: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiBlacklist">Blacklist</Label>
+              </div>
+              <div className="flex items-center space-x-2">
+                <Checkbox
+                  id="shiBcc"
+                  checked={formData.shiBcc}
+                  onCheckedChange={(checked) =>
+                    setFormData(prev => ({ ...prev, shiBcc: !!checked }))
+                  }
+                />
+                <Label htmlFor="shiBcc">BCC</Label>
+              </div>
+            </div>
+          </div>
+
+          {/* 기술영업 견적결과 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기술영업 견적결과</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="salesQuoteNumber">기술영업 견적번호</Label>
+                <Input
+                  id="salesQuoteNumber"
+                  value={formData.salesQuoteNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesQuoteNumber: e.target.value }))}
+                  placeholder="기술영업 견적번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="quoteCode">견적서 Code</Label>
+                <Input
+                  id="quoteCode"
+                  value={formData.quoteCode}
+                  onChange={(e) => setFormData(prev => ({ ...prev, quoteCode: e.target.value }))}
+                  placeholder="견적서 Code를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="salesVendorInfo">견적 협력업체 명</Label>
+                <Input
+                  id="salesVendorInfo"
+                  value={formData.salesVendorInfo}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesVendorInfo: e.target.value }))}
+                  placeholder="견적 협력업체 명을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="salesCountry">국가</Label>
+                <Input
+                  id="salesCountry"
+                  value={formData.salesCountry}
+                  onChange={(e) => setFormData(prev => ({ ...prev, salesCountry: e.target.value }))}
+                  placeholder="국가를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="totalAmount">총 금액</Label>
+                <Input
+                  id="totalAmount"
+                  type="number"
+                  value={formData.totalAmount}
+                  onChange={(e) => setFormData(prev => ({ ...prev, totalAmount: e.target.value }))}
+                  placeholder="총 금액을 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="quoteReceivedDate">견적접수일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="quoteReceivedDate"
+                  value={formData.quoteReceivedDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, quoteReceivedDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 업체 실적 현황 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">업체 실적 현황</h4>
+            <div className="grid grid-cols-2 gap-4">
+              <div className="space-y-2">
+                <Label htmlFor="recentQuoteNumber">최근견적번호</Label>
+                <Input
+                  id="recentQuoteNumber"
+                  value={formData.recentQuoteNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteNumber: e.target.value }))}
+                  placeholder="최근견적번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentQuoteDate">최근견적일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="recentQuoteDate"
+                  value={formData.recentQuoteDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentOrderNumber">최근발주번호</Label>
+                <Input
+                  id="recentOrderNumber"
+                  value={formData.recentOrderNumber}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentOrderNumber: e.target.value }))}
+                  placeholder="최근발주번호를 입력하세요"
+                />
+              </div>
+              <div className="space-y-2">
+                <Label htmlFor="recentOrderDate">최근발주일 (YYYY-MM-DD)</Label>
+                <Input
+                  id="recentOrderDate"
+                  value={formData.recentOrderDate}
+                  onChange={(e) => setFormData(prev => ({ ...prev, recentOrderDate: e.target.value }))}
+                  placeholder="YYYY-MM-DD"
+                />
+              </div>
+            </div>
+          </div>
+
+          {/* 기타 */}
+          <div className="space-y-4">
+            <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기타</h4>
+            <div className="space-y-2">
+              <Label htmlFor="remarks">비고</Label>
+              <Textarea
+                id="remarks"
+                value={formData.remarks}
+                onChange={(e) => setFormData(prev => ({ ...prev, remarks: e.target.value }))}
+                placeholder="비고를 입력하세요"
+                rows={3}
+              />
+            </div>
+          </div>
+        </div>
+        <DialogFooter>
+          <Button type="button" variant="outline" onClick={handleCancel}>
+            취소
+          </Button>
+          <Button type="button" onClick={handleSubmit}>
+            {editingItem ? "수정" : "추가"}
+          </Button>
+        </DialogFooter>
+      </DialogContent>
+    </Dialog>
+  )
+}
diff --git a/lib/avl/table/standard-avl-table-columns.tsx b/lib/avl/table/standard-avl-table-columns.tsx
new file mode 100644
index 00000000..903d2590
--- /dev/null
+++ b/lib/avl/table/standard-avl-table-columns.tsx
@@ -0,0 +1,91 @@
+import { Checkbox } from "@/components/ui/checkbox"
+import { ColumnDef } from "@tanstack/react-table"
+import { StandardAvlItem } from "./standard-avl-table"
+
+// 선종별 표준 AVL 테이블 컬럼
+export const standardAvlColumns: ColumnDef<StandardAvlItem>[] = [
+    {
+        id: "select",
+        header: ({ table }) => (
+            <Checkbox
+                checked={
+                    table.getIsAllPageRowsSelected() ||
+                    (table.getIsSomePageRowsSelected() && "indeterminate")
+                }
+                onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+                aria-label="Select all"
+            />
+        ),
+        cell: ({ row, table }) => {
+            // 선종별 표준 AVL 테이블의 단일 선택 핸들러
+            const handleRowSelection = (checked: boolean) => {
+                if (checked) {
+                    // 다른 모든 행의 선택 해제
+                    table.getRowModel().rows.forEach(r => {
+                        if (r !== row && r.getIsSelected()) {
+                            r.toggleSelected(false)
+                        }
+                    })
+                }
+                // 현재 행 선택/해제
+                row.toggleSelected(checked)
+            }
+
+            return (
+                <Checkbox
+                    checked={row.getIsSelected()}
+                    onCheckedChange={handleRowSelection}
+                    aria-label="Select row"
+                />
+            )
+        },
+        enableSorting: false,
+        enableHiding: false,
+        size: 50,
+    },
+    {
+        accessorKey: "no",
+        header: "No.",
+        size: 60,
+    },
+    {
+        accessorKey: "disciplineName",
+        header: "설계공종",
+        size: 120,
+    },
+    {
+        accessorKey: "avlVendorName",
+        header: "AVL 등재업체명",
+        size: 140,
+    },
+    {
+        accessorKey: "materialGroupCode",
+        header: "자재그룹 코드",
+        size: 120,
+    },
+    {
+        accessorKey: "materialGroupName",
+        header: "자재그룹 명",
+        size: 130,
+    },
+    {
+        accessorKey: "vendorCode",
+        header: "협력업체 코드",
+        size: 120,
+    },
+    {
+        accessorKey: "vendorName",
+        header: "협력업체 명",
+        size: 130,
+    },
+    {
+        accessorKey: "headquarterLocation",
+        header: "본사 위치 (국가)",
+        size: 140,
+    },
+    {
+        accessorKey: "tier",
+        header: "등급 (Tier)",
+        size: 120,
+    },
+]
\ No newline at end of file
diff --git a/lib/avl/table/standard-avl-table.tsx b/lib/avl/table/standard-avl-table.tsx
index 924b972a..cc39540b 100644
--- a/lib/avl/table/standard-avl-table.tsx
+++ b/lib/avl/table/standard-avl-table.tsx
@@ -1,10 +1,10 @@
 "use client"
 
 import * as React from "react"
-import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, type ColumnDef } from "@tanstack/react-table"
+import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel } from "@tanstack/react-table"
+import { useLayoutEffect, useMemo, forwardRef, useImperativeHandle } from "react"
 import { DataTable } from "@/components/data-table/data-table"
 import { Button } from "@/components/ui/button"
-import { Checkbox } from "@/components/ui/checkbox"
 import { getStandardAvlVendorInfo } from "../service"
 import { GetStandardAvlSchema } from "../validations"
 import { AvlDetailItem } from "../types"
@@ -17,40 +17,74 @@ import {
 } from "@/components/ui/select"
 import { Search } from "lucide-react"
 import { toast } from "sonner"
+import { standardAvlColumns } from "./standard-avl-table-columns"
+import { AvlVendorAddAndModifyDialog } from "./avl-vendor-add-and-modify-dialog"
+import { createAvlVendorInfo, updateAvlVendorInfo, deleteAvlVendorInfo, finalizeStandardAvl } from "../service"
+import { AvlVendorInfoInput } from "../types"
+import { useSession } from "next-auth/react"
+
+/**
+ * 조선인 경우, 선종:
+ * A-max, S-max, VLCC, LNGC, CONT
+ * 해양인 경우, 선종:
+ * FPSO, FLNG, FPU, Platform, WTIV, GOM
+ * 
+ * AVL종류:
+ * Nearshore, Offshore, IOC, NOC
+ */
 
 // 검색 옵션들
 const constructionSectorOptions = [
-  { value: "all", label: "전체" },
   { value: "조선", label: "조선" },
   { value: "해양", label: "해양" },
 ]
 
-const shipTypeOptions = [
-  { value: "all", label: "전체" },
-  { value: "컨테이너선", label: "컨테이너선" },
-  { value: "유조선", label: "유조선" },
-  { value: "LNG선", label: "LNG선" },
-  { value: "LPG선", label: "LPG선" },
-  { value: "벌크선", label: "벌크선" },
-  { value: "여객선", label: "여객선" },
-]
+// 공사부문에 따른 선종 옵션들
+const getShipTypeOptions = (constructionSector: string) => {
+  if (constructionSector === "조선") {
+    return [
+      { value: "A-max", label: "A-max" },
+      { value: "S-max", label: "S-max" },
+      { value: "VLCC", label: "VLCC" },
+      { value: "LNGC", label: "LNGC" },
+      { value: "CONT", label: "CONT" },
+    ]
+  } else if (constructionSector === "해양") {
+    return [
+      { value: "FPSO", label: "FPSO" },
+      { value: "FLNG", label: "FLNG" },
+      { value: "FPU", label: "FPU" },
+      { value: "Platform", label: "Platform" },
+      { value: "WTIV", label: "WTIV" },
+      { value: "GOM", label: "GOM" },
+    ]
+  } else {
+    // 공사부문이 선택되지 않은 경우 빈 배열
+    return []
+  }
+}
 
 const avlKindOptions = [
-  { value: "all", label: "전체" },
-  { value: "표준", label: "표준" },
-  { value: "특별", label: "특별" },
-  { value: "임시", label: "임시" },
+  { value: "Nearshore", label: "Nearshore" },
+  { value: "Offshore", label: "Offshore" },
+  { value: "IOC", label: "IOC" },
+  { value: "NOC", label: "NOC" },
 ]
 
 const htDivisionOptions = [
-  { value: "all", label: "전체" },
+  { value: "공통", label: "공통" },
   { value: "H", label: "Hull (H)" },
-  { value: "T", label: "Topside (T)" },
+  { value: "T", label: "Top (T)" },
 ]
 
 // 선종별 표준 AVL 테이블에서는 AvlDetailItem을 사용
 export type StandardAvlItem = AvlDetailItem
 
+// ref를 통해 외부에서 접근할 수 있는 메소드들
+export interface StandardAvlTableRef {
+  getSelectedIds: () => number[]
+}
+
 interface StandardAvlTableProps {
   onSelectionChange?: (count: number) => void
   resetCounter?: number
@@ -58,130 +92,154 @@ interface StandardAvlTableProps {
   shipType?: string // 선종 필터
   avlKind?: string // AVL 종류 필터
   htDivision?: string // H/T 구분 필터
+  onSearchConditionsChange?: (conditions: {
+    constructionSector: string
+    shipType: string
+    avlKind: string
+    htDivision: string
+  }) => void
+  reloadTrigger?: number
 }
 
-// 선종별 표준 AVL 테이블 컬럼
-const standardAvlColumns: ColumnDef<StandardAvlItem>[] = [
-  {
-    id: "select",
-    header: ({ table }) => (
-      <Checkbox
-        checked={
-          table.getIsAllPageRowsSelected() ||
-          (table.getIsSomePageRowsSelected() && "indeterminate")
-        }
-        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
-        aria-label="Select all"
-      />
-    ),
-    cell: ({ row, table }) => {
-      // 선종별 표준 AVL 테이블의 단일 선택 핸들러
-      const handleRowSelection = (checked: boolean) => {
-        if (checked) {
-          // 다른 모든 행의 선택 해제
-          table.getRowModel().rows.forEach(r => {
-            if (r !== row && r.getIsSelected()) {
-              r.toggleSelected(false)
-            }
-          })
-        }
-        // 현재 행 선택/해제
-        row.toggleSelected(checked)
-      }
-
-      return (
-        <Checkbox
-          checked={row.getIsSelected()}
-          onCheckedChange={handleRowSelection}
-          aria-label="Select row"
-        />
-      )
-    },
-    enableSorting: false,
-    enableHiding: false,
-    size: 50,
-  },
-  {
-    accessorKey: "no",
-    header: "No.",
-    size: 60,
-  },
-  {
-    accessorKey: "disciplineName",
-    header: "설계공종",
-    size: 120,
-  },
-  {
-    accessorKey: "avlVendorName",
-    header: "AVL 등재업체명",
-    size: 140,
-  },
-  {
-    accessorKey: "materialGroupCode",
-    header: "자재그룹 코드",
-    size: 120,
-  },
-  {
-    accessorKey: "materialGroupName",
-    header: "자재그룹 명",
-    size: 130,
-  },
-  {
-    accessorKey: "vendorCode",
-    header: "협력업체 코드",
-    size: 120,
-  },
-  {
-    accessorKey: "vendorName",
-    header: "협력업체 명",
-    size: 130,
-  },
-  {
-    accessorKey: "headquarterLocation",
-    header: "본사 위치 (국가)",
-    size: 140,
-  },
-  {
-    accessorKey: "tier",
-    header: "등급 (Tier)",
-    size: 120,
-  },
-]
-
-export function StandardAvlTable({
+export const StandardAvlTable = forwardRef<StandardAvlTableRef, StandardAvlTableProps>(({
   onSelectionChange,
   resetCounter,
   constructionSector: initialConstructionSector,
   shipType: initialShipType,
   avlKind: initialAvlKind,
-  htDivision: initialHtDivision
-}: StandardAvlTableProps) {
+  htDivision: initialHtDivision,
+  onSearchConditionsChange,
+  reloadTrigger
+}, ref) => {
+  const { data: sessionData } = useSession()
+  
   const [data, setData] = React.useState<StandardAvlItem[]>([])
   const [loading, setLoading] = React.useState(false)
   const [pageCount, setPageCount] = React.useState(0)
 
+  // 다이얼로그 상태
+  const [isAddDialogOpen, setIsAddDialogOpen] = React.useState(false)
+  const [editingItem, setEditingItem] = React.useState<StandardAvlItem | undefined>(undefined)
+
   // 검색 상태
-  const [searchConstructionSector, setSearchConstructionSector] = React.useState(initialConstructionSector || "all")
-  const [searchShipType, setSearchShipType] = React.useState(initialShipType || "all")
-  const [searchAvlKind, setSearchAvlKind] = React.useState(initialAvlKind || "all")
-  const [searchHtDivision, setSearchHtDivision] = React.useState(initialHtDivision || "all")
+  const [searchConstructionSector, setSearchConstructionSector] = React.useState(initialConstructionSector || "")
+  const [searchShipType, setSearchShipType] = React.useState(initialShipType || "")
+  const [searchAvlKind, setSearchAvlKind] = React.useState(initialAvlKind || "")
+  const [searchHtDivision, setSearchHtDivision] = React.useState(initialHtDivision || "")
+
+  // 페이지네이션 상태
+  const [pagination, setPagination] = React.useState({
+    pageIndex: 0,
+    pageSize: 10,
+  })
+
+  const table = useReactTable({
+    data,
+    columns: standardAvlColumns,
+    getCoreRowModel: getCoreRowModel(),
+    getPaginationRowModel: getPaginationRowModel(),
+    getSortedRowModel: getSortedRowModel(),
+    getFilteredRowModel: getFilteredRowModel(),
+    manualPagination: true,
+    pageCount,
+    state: {
+      pagination,
+    },
+    onPaginationChange: (updater) => {
+      // 페이지네이션 상태 업데이트
+      const newPaginationState = typeof updater === 'function' ? updater(pagination) : updater
+
+      console.log('StandardAvlTable - Pagination changed:', {
+        currentState: pagination,
+        newPaginationState,
+        isAllSearchConditionsSelected,
+        willLoadData: isAllSearchConditionsSelected
+      })
+
+      setPagination(newPaginationState)
+
+      if (isAllSearchConditionsSelected) {
+        const apiParams = {
+          page: newPaginationState.pageIndex + 1,
+          perPage: newPaginationState.pageSize,
+        }
+        console.log('StandardAvlTable - Loading data with params:', apiParams)
+        loadData(apiParams)
+      }
+    },
+  })
+
+  // 공사부문 변경 시 선종 초기화
+  const handleConstructionSectorChange = React.useCallback((value: string) => {
+    setSearchConstructionSector(value)
+    // 공사부문이 변경되면 선종을 빈 값으로 초기화
+    setSearchShipType("")
+  }, [])
+
+  // 검색 상태 변경 시 부모 컴포넌트에 전달
+  React.useEffect(() => {
+    onSearchConditionsChange?.({
+      constructionSector: searchConstructionSector,
+      shipType: searchShipType,
+      avlKind: searchAvlKind,
+      htDivision: searchHtDivision
+    })
+  }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision, onSearchConditionsChange])
+
+  // 현재 공사부문에 따른 선종 옵션들
+  const currentShipTypeOptions = React.useMemo(() =>
+    getShipTypeOptions(searchConstructionSector),
+    [searchConstructionSector]
+  )
+
+  // 모든 검색 조건이 선택되었는지 확인
+  const isAllSearchConditionsSelected = React.useMemo(() => {
+    return (
+      searchConstructionSector.trim() !== "" &&
+      searchShipType.trim() !== "" &&
+      searchAvlKind.trim() !== "" &&
+      searchHtDivision.trim() !== ""
+    )
+  }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
 
   // 데이터 로드 함수
-  const loadData = React.useCallback(async (searchParams: Partial<GetStandardAvlSchema>) => {
+  const loadData = React.useCallback(async (searchParams: Partial<GetStandardAvlSchema> = {}) => {
     try {
       setLoading(true)
+      
       const params: GetStandardAvlSchema = {
         page: searchParams.page ?? 1,
         perPage: searchParams.perPage ?? 10,
         sort: searchParams.sort ?? [{ id: "no", desc: false }],
-        constructionSector: searchConstructionSector === "all" ? "" : searchConstructionSector || "",
-        shipType: searchShipType === "all" ? "" : searchShipType || "",
-        avlKind: searchAvlKind === "all" ? "" : searchAvlKind || "",
-        htDivision: searchHtDivision === "all" ? "" : searchHtDivision || "",
+        flags: searchParams.flags ?? [],
+        constructionSector: searchConstructionSector,
+        shipType: searchShipType,
+        avlKind: searchAvlKind,
+        htDivision: searchHtDivision as "공통" | "H" | "T" | "",
+        equipBulkDivision: searchParams.equipBulkDivision || "",
+        disciplineCode: searchParams.disciplineCode ?? "",
+        disciplineName: searchParams.disciplineName ?? "",
+        materialNameCustomerSide: searchParams.materialNameCustomerSide ?? "",
+        packageCode: searchParams.packageCode ?? "",
+        packageName: searchParams.packageName ?? "",
+        materialGroupCode: searchParams.materialGroupCode ?? "",
+        materialGroupName: searchParams.materialGroupName ?? "",
+        vendorName: searchParams.vendorName ?? "",
+        vendorCode: searchParams.vendorCode ?? "",
+        avlVendorName: searchParams.avlVendorName ?? "",
+        tier: searchParams.tier ?? "",
+        filters: searchParams.filters ?? [],
+        joinOperator: searchParams.joinOperator ?? "and",
         search: "",
         ...searchParams,
       }
+      console.log('StandardAvlTable - API call params:', params)
       const result = await getStandardAvlVendorInfo(params)
+      console.log('StandardAvlTable - API result:', {
+        dataCount: result.data.length,
+        pageCount: result.pageCount,
+        requestedPage: params.page
+      })
       setData(result.data)
       setPageCount(result.pageCount)
     } catch (error) {
@@ -193,52 +251,230 @@ export function StandardAvlTable({
     }
   }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
 
-  // 검색 핸들러
-  const handleSearch = React.useCallback(() => {
-    loadData({})
-  }, [loadData])
+  // reloadTrigger가 변경될 때마다 데이터 리로드
+  React.useEffect(() => {
+    if (reloadTrigger && reloadTrigger > 0) {
+      console.log('StandardAvlTable - reloadTrigger changed, reloading data')
+      loadData({})
+    }
+  }, [reloadTrigger, loadData])
 
   // 검색 초기화 핸들러
   const handleResetSearch = React.useCallback(() => {
-    setSearchConstructionSector("all")
-    setSearchShipType("all")
-    setSearchAvlKind("all")
-    setSearchHtDivision("all")
-    loadData({})
+    setSearchConstructionSector("")
+    setSearchShipType("")
+    setSearchAvlKind("")
+    setSearchHtDivision("")
+    // 초기화 시 빈 데이터로 설정
+    setData([])
+    setPageCount(0)
+  }, [])
+
+  // 검색 핸들러
+  const handleSearch = React.useCallback(() => {
+    if (isAllSearchConditionsSelected) {
+      // 검색 시 페이지를 1페이지로 리셋
+      setPagination(prev => ({ ...prev, pageIndex: 0 }))
+      loadData({ page: 1, perPage: pagination.pageSize })
+    }
+  }, [loadData, isAllSearchConditionsSelected, pagination.pageSize])
+
+  // 항목 추가 핸들러
+  const handleAddItem = React.useCallback(async (itemData: Omit<AvlVendorInfoInput, 'avlListId'>) => {
+    try {
+      const result = await createAvlVendorInfo(itemData)
+
+      if (result) {
+        toast.success("표준 AVL 항목이 성공적으로 추가되었습니다.")
+        // 데이터 새로고침
+        loadData({})
+      } else {
+        toast.error("항목 추가에 실패했습니다.")
+      }
+    } catch (error) {
+      console.error("항목 추가 실패:", error)
+      toast.error("항목 추가 중 오류가 발생했습니다.")
+    }
   }, [loadData])
 
-  // 초기 데이터 로드
-  React.useEffect(() => {
-    loadData({})
+  // 항목 수정 핸들러
+  const handleUpdateItem = React.useCallback(async (id: number, itemData: Omit<AvlVendorInfoInput, 'avlListId'>) => {
+    try {
+      const result = await updateAvlVendorInfo(id, itemData)
+
+      if (result) {
+        toast.success("표준 AVL 항목이 성공적으로 수정되었습니다.")
+        // 데이터 새로고침
+        loadData({})
+        // 수정 모드 해제
+        setEditingItem(undefined)
+      } else {
+        toast.error("항목 수정에 실패했습니다.")
+      }
+    } catch (error) {
+      console.error("항목 수정 실패:", error)
+      toast.error("항목 수정 중 오류가 발생했습니다.")
+    }
   }, [loadData])
 
-  const table = useReactTable({
-    data,
-    columns: standardAvlColumns,
-    getCoreRowModel: getCoreRowModel(),
-    getPaginationRowModel: getPaginationRowModel(),
-    getSortedRowModel: getSortedRowModel(),
-    getFilteredRowModel: getFilteredRowModel(),
-    manualPagination: true,
-    pageCount,
-    initialState: {
-      pagination: {
-        pageSize: 10,
-      },
-    },
-    onPaginationChange: (updater) => {
-      const newState = typeof updater === 'function' ? updater(table.getState().pagination) : updater
-      loadData({
-        page: newState.pageIndex + 1,
-        perPage: newState.pageSize,
+  // 항목 수정 핸들러 (버튼 클릭)
+  const handleEditItem = React.useCallback(() => {
+    const selectedRows = table.getFilteredSelectedRowModel().rows
+
+    if (selectedRows.length !== 1) {
+      toast.error("수정할 항목을 하나만 선택해주세요.")
+      return
+    }
+
+    const selectedItem = selectedRows[0].original
+    setEditingItem(selectedItem)
+    setIsAddDialogOpen(true)
+  }, [table])
+
+  // 항목 삭제 핸들러
+  const handleDeleteItems = React.useCallback(async () => {
+    const selectedRows = table.getFilteredSelectedRowModel().rows
+
+    if (selectedRows.length === 0) {
+      toast.error("삭제할 항목을 선택해주세요.")
+      return
+    }
+
+    // 사용자 확인
+    const confirmed = window.confirm(`선택한 ${selectedRows.length}개 항목을 정말 삭제하시겠습니까?`)
+    if (!confirmed) return
+
+    try {
+      // 선택된 항목들을 DB에서 삭제
+      const deletePromises = selectedRows.map(async (row) => {
+        await deleteAvlVendorInfo(row.original.id)
       })
-    },
-  })
 
-  // 선택 상태 변경 시 콜백 호출
+      await Promise.all(deletePromises)
+
+      toast.success(`${selectedRows.length}개 항목이 삭제되었습니다.`)
+
+      // 데이터 새로고침
+      loadData({})
+
+      // 선택 해제
+      table.toggleAllPageRowsSelected(false)
+    } catch (error) {
+      console.error("항목 삭제 실패:", error)
+      toast.error("항목 삭제 중 오류가 발생했습니다.")
+    }
+  }, [table, loadData])
+
+  // 최종 확정 핸들러 (표준 AVL)
+  const handleFinalizeStandardAvl = React.useCallback(async () => {
+    // 1. 필수 조건 검증
+    if (!isAllSearchConditionsSelected) {
+      toast.error("검색 조건을 모두 선택해주세요.")
+      return
+    }
+
+    if (data.length === 0) {
+      toast.error("확정할 표준 AVL 벤더 정보가 없습니다.")
+      return
+    }
+
+    // 2. 사용자 확인
+    const confirmed = window.confirm(
+      `현재 표준 AVL을 최종 확정하시겠습니까?\n\n` +
+      `- 공사부문: ${searchConstructionSector}\n` +
+      `- 선종: ${searchShipType}\n` +
+      `- AVL종류: ${searchAvlKind}\n` +
+      `- H/T 구분: ${searchHtDivision}\n` +
+      `- 벤더 정보: ${data.length}개\n\n` +
+      `확정 후에는 수정이 어려울 수 있습니다.`
+    )
+
+    if (!confirmed) return
+
+    try {
+      // 3. 현재 데이터의 모든 ID 수집
+      const avlVendorInfoIds = data.map(item => item.id)
+
+      // 4. 최종 확정 실행
+      const standardAvlInfo = {
+        constructionSector: searchConstructionSector,
+        shipType: searchShipType,
+        avlKind: searchAvlKind,
+        htDivision: searchHtDivision
+      }
+
+      const result = await finalizeStandardAvl(
+        standardAvlInfo,
+        avlVendorInfoIds,
+        sessionData?.user?.name || ""
+      )
+
+      if (result.success) {
+        toast.success(result.message)
+        
+        // 5. 데이터 새로고침
+        loadData({})
+        
+        // 6. 선택 해제
+        table.toggleAllPageRowsSelected(false)
+      } else {
+        toast.error(result.message)
+      }
+    } catch (error) {
+      console.error("표준 AVL 최종 확정 실패:", error)
+      toast.error("표준 AVL 최종 확정 중 오류가 발생했습니다.")
+    }
+  }, [searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision, isAllSearchConditionsSelected, data, table, loadData, sessionData?.user?.name])
+
+  // 초기 데이터 로드 (검색 조건이 모두 입력되었을 때만)
   React.useEffect(() => {
-    onSelectionChange?.(table.getFilteredSelectedRowModel().rows.length)
-  }, [table.getFilteredSelectedRowModel().rows.length, onSelectionChange])
+    if (isAllSearchConditionsSelected) {
+      // 검색 조건이 모두 입력되면 페이지를 1페이지로 리셋하고 데이터 로드
+      setPagination(prev => ({ ...prev, pageIndex: 0 }))
+      loadData({ page: 1, perPage: pagination.pageSize })
+    } else {
+      // 검색 조건이 모두 입력되지 않은 경우 빈 데이터로 설정
+      setData([])
+      setPageCount(0)
+    }
+  }, [isAllSearchConditionsSelected, pagination.pageSize, searchConstructionSector, searchShipType, searchAvlKind, searchHtDivision])
+
+  
+
+  // 외부에서 선택된 ID들을 가져올 수 있도록 ref에 메소드 노출
+  useImperativeHandle(ref, () => ({
+    getSelectedIds: () => {
+      const selectedRows = table.getFilteredSelectedRowModel().rows
+      return selectedRows.map(row => row.original.id)
+    }
+  }))
+
+  // 선택된 행 개수 (안정적인 계산을 위해 useMemo 사용)
+  const selectedRows = table.getFilteredSelectedRowModel().rows
+  const selectedRowCount = useMemo(() => {
+    const count = selectedRows.length
+    console.log('StandardAvlTable - selectedRowCount calculated:', count)
+    return count
+  }, [selectedRows])
+
+  // 페이지네이션 상태 디버깅
+  React.useEffect(() => {
+    const paginationState = table.getState().pagination
+    console.log('StandardAvlTable - Current pagination state:', {
+      pageIndex: paginationState.pageIndex,
+      pageSize: paginationState.pageSize,
+      canPreviousPage: table.getCanPreviousPage(),
+      canNextPage: table.getCanNextPage(),
+      pageCount: table.getPageCount(),
+      currentDataLength: data.length
+    })
+  }, [table, data])
+
+  // 선택 상태 변경 시 콜백 호출
+  useLayoutEffect(() => {
+    console.log('StandardAvlTable - onSelectionChange called with count:', selectedRowCount)
+    onSelectionChange?.(selectedRowCount)
+  }, [selectedRowCount, onSelectionChange])
 
   // 선택 해제 요청이 오면 모든 선택 해제
   React.useEffect(() => {
@@ -253,22 +489,35 @@ export function StandardAvlTable({
         <div className="flex items-center justify-between mb-2">
           <h4 className="font-medium">선종별 표준 AVL</h4>
           <div className="flex gap-1">
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            <Button variant="outline" size="sm" onClick={() => setIsAddDialogOpen(true)}>
               신규업체 추가
             </Button>
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            <Button
+              variant="outline"
+              size="sm"
+              onClick={handleEditItem}
+              disabled={table.getFilteredSelectedRowModel().rows.length !== 1}
+            >
+              항목 수정
+            </Button>
+            {/* <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
               파일 업로드
             </Button>
             <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
               일괄입력
+            </Button> */}
+            <Button variant="outline" size="sm" onClick={handleDeleteItems}>
+              항목 삭제
             </Button>
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
-              항목삭제
-            </Button>
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            {/* <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
               저장
-            </Button>
-            <Button variant="outline" size="sm" onClick={() => toast.info("개발 중입니다.")}>
+            </Button> */}
+            <Button 
+              variant="outline" 
+              size="sm" 
+              onClick={handleFinalizeStandardAvl}
+              disabled={!isAllSearchConditionsSelected || data.length === 0}
+            >
               최종 확정
             </Button>
           </div>
@@ -281,7 +530,7 @@ export function StandardAvlTable({
           {/* 공사부문 */}
           <div className="space-y-2">
             <label className="text-sm font-medium">공사부문</label>
-            <Select value={searchConstructionSector} onValueChange={setSearchConstructionSector}>
+            <Select value={searchConstructionSector} onValueChange={handleConstructionSectorChange}>
               <SelectTrigger>
                 <SelectValue />
               </SelectTrigger>
@@ -303,7 +552,7 @@ export function StandardAvlTable({
                 <SelectValue />
               </SelectTrigger>
               <SelectContent>
-                {shipTypeOptions.map((option) => (
+                {currentShipTypeOptions.map((option) => (
                   <SelectItem key={option.value} value={option.value}>
                     {option.label}
                   </SelectItem>
@@ -352,7 +601,7 @@ export function StandardAvlTable({
             <div className="flex gap-1">
               <Button
                 onClick={handleSearch}
-                disabled={loading}
+                disabled={loading || !isAllSearchConditionsSelected}
                 size="sm"
                 className="px-3"
               >
@@ -375,6 +624,28 @@ export function StandardAvlTable({
       <div className="flex-1">
         <DataTable table={table} />
       </div>
+
+      {/* 신규업체 추가 다이얼로그 */}
+      <AvlVendorAddAndModifyDialog
+        open={isAddDialogOpen}
+        onOpenChange={(open) => {
+          setIsAddDialogOpen(open)
+          if (!open) {
+            setEditingItem(undefined) // 다이얼로그가 닫힐 때 수정 모드 해제
+          }
+        }}
+        onAddItem={handleAddItem}
+        editingItem={editingItem}
+        onUpdateItem={handleUpdateItem}
+        isTemplate={true} // 표준 AVL 모드
+        // 검색 조건에서 선택한 값들을 초기값으로 전달
+        initialConstructionSector={searchConstructionSector}
+        initialShipType={searchShipType}
+        initialAvlKind={searchAvlKind}
+        initialHtDivision={searchHtDivision}
+      />
     </div>
   )
-}
+})
+
+StandardAvlTable.displayName = "StandardAvlTable"
diff --git a/lib/avl/table/vendor-pool-table-columns.tsx b/lib/avl/table/vendor-pool-table-columns.tsx
new file mode 100644
index 00000000..53db1059
--- /dev/null
+++ b/lib/avl/table/vendor-pool-table-columns.tsx
@@ -0,0 +1,96 @@
+import { Checkbox } from "@/components/ui/checkbox"
+import { ColumnDef } from "@tanstack/react-table"
+import { VendorPoolItem } from "./vendor-pool-table"
+
+// Vendor Pool 테이블 컬럼
+export const vendorPoolColumns: ColumnDef<VendorPoolItem>[] = [
+    {
+        id: "select",
+        header: ({ table }) => (
+            <Checkbox
+                checked={
+                    table.getIsAllPageRowsSelected() ||
+                    (table.getIsSomePageRowsSelected() && "indeterminate")
+                }
+                onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+                aria-label="Select all"
+            />
+        ),
+        cell: ({ row, table }) => {
+            // Vendor Pool 테이블의 단일 선택 핸들러
+            const handleRowSelection = (checked: boolean) => {
+                if (checked) {
+                    // 다른 모든 행의 선택 해제
+                    table.getRowModel().rows.forEach(r => {
+                        if (r !== row && r.getIsSelected()) {
+                            r.toggleSelected(false)
+                        }
+                    })
+                }
+                // 현재 행 선택/해제
+                row.toggleSelected(checked)
+            }
+
+            return (
+                <Checkbox
+                    checked={row.getIsSelected()}
+                    onCheckedChange={handleRowSelection}
+                    aria-label="Select row"
+                />
+            )
+        },
+        enableSorting: false,
+        enableHiding: false,
+        size: 50,
+    },
+    {
+        accessorKey: "no",
+        header: "No.",
+        size: 60,
+    },
+    {
+        accessorKey: "designCategory",
+        header: "설계공종",
+        size: 120,
+    },
+    {
+        accessorKey: "avlVendorName",
+        header: "AVL 등재업체명",
+        size: 140,
+    },
+    {
+        accessorKey: "materialGroupCode",
+        header: "자재그룹코드",
+        size: 130,
+    },
+    {
+        accessorKey: "materialGroupName",
+        header: "자재그룹명",
+        size: 130,
+    },
+    {
+        accessorKey: "vendorName",
+        header: "협력업체 정보",
+        size: 130,
+    },
+    {
+        accessorKey: "tier",
+        header: "업체분류",
+        size: 100,
+    },
+    {
+        accessorKey: "faStatus",
+        header: "FA현황",
+        size: 100,
+    },
+    {
+        accessorKey: "recentQuoteNumber",
+        header: "최근견적번호",
+        size: 130,
+    },
+    {
+        accessorKey: "recentOrderNumber",
+        header: "최근발주번호",
+        size: 130,
+    },
+]
\ No newline at end of file
diff --git a/lib/avl/table/vendor-pool-table.tsx b/lib/avl/table/vendor-pool-table.tsx
index 1a0a5fca..7ad9eb56 100644
--- a/lib/avl/table/vendor-pool-table.tsx
+++ b/lib/avl/table/vendor-pool-table.tsx
@@ -1,7 +1,8 @@
 "use client"
 
 import * as React from "react"
-import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, type ColumnDef } from "@tanstack/react-table"
+import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel } from "@tanstack/react-table"
+import { forwardRef, useImperativeHandle } from "react"
 import { DataTable } from "@/components/data-table/data-table"
 import { Button } from "@/components/ui/button"
 import { Checkbox } from "@/components/ui/checkbox"
@@ -10,114 +11,29 @@ import { Search } from "lucide-react"
 import { getVendorPools } from "../../vendor-pool/service"
 import { GetVendorPoolSchema } from "../../vendor-pool/validations"
 import { VendorPool } from "../../vendor-pool/types"
+import { vendorPoolColumns } from "./vendor-pool-table-columns"
 
 // Vendor Pool 데이터 타입 (실제 VendorPool 타입 사용)
 export type VendorPoolItem = VendorPool
 
+// ref를 통해 외부에서 접근할 수 있는 메소드들
+export interface VendorPoolTableRef {
+  getSelectedIds: () => number[]
+}
+
 interface VendorPoolTableProps {
   onSelectionChange?: (count: number) => void
   resetCounter?: number
+  reloadTrigger?: number
 }
 
-// Vendor Pool 테이블 컬럼
-const vendorPoolColumns: ColumnDef<VendorPoolItem>[] = [
-  {
-    id: "select",
-    header: ({ table }) => (
-      <Checkbox
-        checked={
-          table.getIsAllPageRowsSelected() ||
-          (table.getIsSomePageRowsSelected() && "indeterminate")
-        }
-        onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
-        aria-label="Select all"
-      />
-    ),
-    cell: ({ row, table }) => {
-      // Vendor Pool 테이블의 단일 선택 핸들러
-      const handleRowSelection = (checked: boolean) => {
-        if (checked) {
-          // 다른 모든 행의 선택 해제
-          table.getRowModel().rows.forEach(r => {
-            if (r !== row && r.getIsSelected()) {
-              r.toggleSelected(false)
-            }
-          })
-        }
-        // 현재 행 선택/해제
-        row.toggleSelected(checked)
-      }
-
-      return (
-        <Checkbox
-          checked={row.getIsSelected()}
-          onCheckedChange={handleRowSelection}
-          aria-label="Select row"
-        />
-      )
-    },
-    enableSorting: false,
-    enableHiding: false,
-    size: 50,
-  },
-  {
-    accessorKey: "no",
-    header: "No.",
-    size: 60,
-  },
-  {
-    accessorKey: "designCategory",
-    header: "설계공종",
-    size: 120,
-  },
-  {
-    accessorKey: "avlVendorName",
-    header: "AVL 등재업체명",
-    size: 140,
-  },
-  {
-    accessorKey: "materialGroupCode",
-    header: "자재그룹코드",
-    size: 130,
-  },
-  {
-    accessorKey: "materialGroupName",
-    header: "자재그룹명",
-    size: 130,
-  },
-  {
-    accessorKey: "vendorName",
-    header: "협력업체 정보",
-    size: 130,
-  },
-  {
-    accessorKey: "tier",
-    header: "업체분류",
-    size: 100,
-  },
-  {
-    accessorKey: "faStatus",
-    header: "FA현황",
-    size: 100,
-  },
-  {
-    accessorKey: "recentQuoteNumber",
-    header: "최근견적번호",
-    size: 130,
-  },
-  {
-    accessorKey: "recentOrderNumber",
-    header: "최근발주번호",
-    size: 130,
-  },
-]
-
 // 실제 데이터는 API에서 가져옴
 
-export function VendorPoolTable({
+export const VendorPoolTable = forwardRef<VendorPoolTableRef, VendorPoolTableProps>(({
   onSelectionChange,
-  resetCounter
-}: VendorPoolTableProps) {
+  resetCounter,
+  reloadTrigger
+}, ref) => {
   const [data, setData] = React.useState<VendorPoolItem[]>([])
   const [loading, setLoading] = React.useState(false)
   const [pageCount, setPageCount] = React.useState(0)
@@ -126,18 +42,78 @@ export function VendorPoolTable({
   const [searchText, setSearchText] = React.useState("")
   const [showAll, setShowAll] = React.useState(false)
 
+  // 페이지네이션 상태
+  const [pagination, setPagination] = React.useState({
+    pageIndex: 0,
+    pageSize: 10,
+  })
+
   // 데이터 로드 함수
-  const loadData = React.useCallback(async (searchParams: Partial<GetVendorPoolSchema>) => {
+  const loadData = React.useCallback(async (searchParams: Partial<GetVendorPoolSchema> = {}) => {
     try {
       setLoading(true)
-      const params: GetVendorPoolSchema = {
+      
+      const params = {
         page: searchParams.page ?? 1,
         perPage: searchParams.perPage ?? 10,
         sort: searchParams.sort ?? [{ id: "registrationDate", desc: true }],
+        flags: [],
         search: searchText || "",
+        constructionSector: undefined,
+        shipType: undefined,
+        htDivision: undefined,
+        designCategoryCode: undefined,
+        designCategory: undefined,
+        equipBulkDivision: undefined,
+        packageCode: undefined,
+        packageName: undefined,
+        materialGroupCode: undefined,
+        materialGroupName: undefined,
+        vendorCode: undefined,
+        vendorName: undefined,
+        faTarget: undefined,
+        faStatus: undefined,
+        tier: undefined,
+        isAgent: undefined,
+        isBlacklist: undefined,
+        isBcc: undefined,
+        purchaseOpinion: undefined,
+        shipTypeCommon: undefined,
+        shipTypeAmax: undefined,
+        shipTypeSmax: undefined,
+        shipTypeVlcc: undefined,
+        shipTypeLngc: undefined,
+        shipTypeCont: undefined,
+        offshoreTypeCommon: undefined,
+        offshoreTypeFpso: undefined,
+        offshoreTypeFlng: undefined,
+        offshoreTypeFpu: undefined,
+        offshoreTypePlatform: undefined,
+        offshoreTypeWtiv: undefined,
+        offshoreTypeGom: undefined,
+        picName: undefined,
+        picEmail: undefined,
+        picPhone: undefined,
+        agentName: undefined,
+        agentEmail: undefined,
+        agentPhone: undefined,
+        recentQuoteDate: undefined,
+        recentQuoteNumber: undefined,
+        recentOrderDate: undefined,
+        recentOrderNumber: undefined,
+        registrationDate: undefined,
+        registrant: undefined,
+        lastModifiedDate: undefined,
+        lastModifier: undefined,
         ...searchParams,
       }
-      const result = await getVendorPools(params)
+      console.log('VendorPoolTable - API call params:', params)
+      const result = await getVendorPools(params as GetVendorPoolSchema)
+      console.log('VendorPoolTable - API result:', {
+        dataCount: result.data.length,
+        pageCount: result.pageCount,
+        requestedPage: params.page
+      })
       setData(result.data)
       setPageCount(result.pageCount)
     } catch (error) {
@@ -155,9 +131,11 @@ export function VendorPoolTable({
       // 전체보기 모드에서는 페이징 없이 전체 데이터 로드
       loadData({ perPage: 1000 }) // 충분히 큰 숫자로 전체 데이터 가져오기
     } else {
-      loadData({})
+      // 검색 시 페이지를 1페이지로 리셋
+      setPagination(prev => ({ ...prev, pageIndex: 0 }))
+      loadData({ page: 1, perPage: pagination.pageSize })
     }
-  }, [loadData, showAll])
+  }, [loadData, showAll, pagination.pageSize])
 
   // 전체보기 토글 핸들러
   const handleShowAllToggle = React.useCallback((checked: boolean) => {
@@ -174,8 +152,18 @@ export function VendorPoolTable({
 
   // 초기 데이터 로드
   React.useEffect(() => {
-    loadData({})
-  }, [loadData])
+    // 초기 로드 시 페이지를 1페이지로 설정
+    setPagination(prev => ({ ...prev, pageIndex: 0 }))
+    loadData({ page: 1, perPage: pagination.pageSize })
+  }, [pagination.pageSize])
+
+  // reloadTrigger가 변경될 때마다 데이터 리로드
+  React.useEffect(() => {
+    if (reloadTrigger && reloadTrigger > 0) {
+      console.log('VendorPoolTable - reloadTrigger changed, reloading data')
+      loadData({})
+    }
+  }, [reloadTrigger, loadData])
 
   const table = useReactTable({
     data,
@@ -186,27 +174,48 @@ export function VendorPoolTable({
     getFilteredRowModel: getFilteredRowModel(),
     manualPagination: !showAll, // 전체보기 시에는 수동 페이징 비활성화
     pageCount: showAll ? 1 : pageCount, // 전체보기 시 1페이지, 일반 모드에서는 API에서 받은 pageCount 사용
-    initialState: {
-      pagination: {
-        pageSize: showAll ? data.length : 10, // 전체보기 시 모든 데이터 표시
-      },
+    state: {
+      pagination: showAll ? { pageIndex: 0, pageSize: data.length } : pagination,
     },
     onPaginationChange: (updater) => {
       if (!showAll) {
         // 전체보기가 아닐 때만 페이징 변경 처리
-        const newState = typeof updater === 'function' ? updater(table.getState().pagination) : updater
-        loadData({
-          page: newState.pageIndex + 1,
-          perPage: newState.pageSize,
+        const newPaginationState = typeof updater === 'function' ? updater(pagination) : updater
+
+        console.log('VendorPoolTable - Pagination changed:', {
+          currentState: pagination,
+          newPaginationState,
+          showAll,
+          willLoadData: !showAll
         })
+
+        setPagination(newPaginationState)
+
+        const apiParams = {
+          page: newPaginationState.pageIndex + 1,
+          perPage: newPaginationState.pageSize,
+        }
+        console.log('VendorPoolTable - Loading data with params:', apiParams)
+        loadData(apiParams)
       }
     },
   })
 
+  // 외부에서 선택된 ID들을 가져올 수 있도록 ref에 메소드 노출
+  useImperativeHandle(ref, () => ({
+    getSelectedIds: () => {
+      const selectedRows = table.getFilteredSelectedRowModel().rows
+      return selectedRows.map(row => row.original.id)
+    }
+  }))
+
+  // 선택된 행 개수
+  const selectedRowCount = table.getFilteredSelectedRowModel().rows.length
+
   // 선택 상태 변경 시 콜백 호출
   React.useEffect(() => {
-    onSelectionChange?.(table.getFilteredSelectedRowModel().rows.length)
-  }, [table.getFilteredSelectedRowModel().rows.length, onSelectionChange])
+    onSelectionChange?.(selectedRowCount)
+  }, [selectedRowCount, onSelectionChange])
 
   // 선택 해제 요청이 오면 모든 선택 해제
   React.useEffect(() => {
@@ -287,4 +296,6 @@ export function VendorPoolTable({
       </div>
     </div>
   )
-}
+})
+
+VendorPoolTable.displayName = "VendorPoolTable"
diff --git a/lib/avl/types.ts b/lib/avl/types.ts
index 640299ef..6a7b5143 100644
--- a/lib/avl/types.ts
+++ b/lib/avl/types.ts
@@ -7,6 +7,7 @@ export interface AvlListItem extends Omit<AvlList, 'createdAt' | 'updatedAt'> {
   selected: boolean;
   createdAt: string; // UI에서 사용하기 위해 string으로 변환
   updatedAt: string; // UI에서 사용하기 위해 string으로 변환
+  vendorInfoSnapshot?: any; // JSON 데이터
 
   // 추가 표시용 필드들 (실제로는 AvlVendorInfo에서 가져와야 함)
   projectInfo?: string;
@@ -53,11 +54,12 @@ export interface AvlDetailItem extends Omit<AvlVendorInfo, 'createdAt' | 'update
 }
 
 // AVL 생성을 위한 입력 타입
-export interface CreateAvlListInput extends Omit<AvlList, 'id' | 'createdAt' | 'updatedAt'> {
+export interface CreateAvlListInput extends Omit<AvlList, 'id' | 'createdAt' | 'updatedAt' | 'vendorInfoSnapshot'> {
   // UI에서 입력받을 추가 필드들
   projectInfo?: string;
   shipType?: string;
   avlType?: string;
+  vendorInfoSnapshot?: any; // JSON 데이터, 선택적 속성
 }
 
 // AVL 업데이트를 위한 입력 타입
@@ -68,6 +70,18 @@ export interface UpdateAvlListInput extends Partial<CreateAvlListInput> {
 
 // AVL Vendor Info UI 입력을 위한 인터페이스
 export interface AvlVendorInfoInput {
+  // AVL 타입 구분
+  isTemplate?: boolean; // false: 프로젝트 AVL, true: 표준 AVL
+
+  // 표준 AVL용 필드들 (isTemplate=true일 경우)
+  constructionSector?: string; // 공사부문
+  shipType?: string; // 선종
+  avlKind?: string; // AVL 종류
+  htDivision?: string; // H/T 구분
+
+  // 프로젝트 코드 (나중에 AVL 리스트와 연결할 때 사용)
+  projectCode?: string;
+
   // AVL 리스트 ID (생성 시 필수, UI에서는 선택적으로 사용)
   avlListId?: number;
 
diff --git a/lib/avl/validations.ts b/lib/avl/validations.ts
index 367a5db1..6f09cdfd 100644
--- a/lib/avl/validations.ts
+++ b/lib/avl/validations.ts
@@ -141,10 +141,10 @@ export const standardAvlSearchParamsCache = createSearchParamsCache({
   constructionSector: parseAsString.withDefault(""),
   shipType: parseAsString.withDefault(""),
   avlKind: parseAsString.withDefault(""),
-  htDivision: parseAsStringEnum(["H", "T"]).withDefault(""),
+  htDivision: parseAsStringEnum(["공통", "H", "T", ""]).withDefault(""),
 
   // 추가 필터들
-  equipBulkDivision: parseAsStringEnum(["EQUIP", "BULK"]).withDefault(""),
+  equipBulkDivision: parseAsStringEnum(["EQUIP", "BULK", ""]).withDefault(""),
   disciplineCode: parseAsString.withDefault(""),
   disciplineName: parseAsString.withDefault(""),
   materialNameCustomerSide: parseAsString.withDefault(""),
-- 
cgit v1.2.3

