"use server"; import db from "@/db/db" import { items } from "@/db/schema/items" import { projects } from "@/db/schema/projects" import { eq } from "drizzle-orm" import { contractItems, contracts } from "@/db/schema/contract"; import { getServerSession } from "next-auth"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; export interface ProjectWithContracts { projectId: number projectCode: string projectName: string projectType: string contracts: { contractId: number contractNo: string contractName: string packages: { itemId: number // contract_items.id itemName: string }[] }[] } export async function getVendorProjectsAndContracts( vendorId?: number ): Promise { // 세션에서 도메인 정보 가져오기 const session = await getServerSession(authOptions) // EVCP 도메인일 때만 전체 조회 const isEvcpDomain = session?.user?.domain === "evcp" const query = db .select({ projectId: projects.id, projectCode: projects.code, projectName: projects.name, projectType: projects.type, contractId: contracts.id, contractNo: contracts.contractNo, contractName: contracts.contractName, itemId: contractItems.id, itemName: items.itemName, }) .from(contracts) .innerJoin(projects, eq(contracts.projectId, projects.id)) .innerJoin(contractItems, eq(contractItems.contractId, contracts.id)) .innerJoin(items, eq(contractItems.itemId, items.id)) if (!isEvcpDomain && vendorId) { query.where(eq(contracts.vendorId, vendorId)) } const rows = await query const projectMap = new Map() for (const row of rows) { // 1) 프로젝트 그룹 찾기 let projectEntry = projectMap.get(row.projectId) if (!projectEntry) { // 새 프로젝트 항목 생성 projectEntry = { projectId: row.projectId, projectCode: row.projectCode, projectName: row.projectName, projectType: row.projectType, contracts: [], } projectMap.set(row.projectId, projectEntry) } // 2) 프로젝트 안에서 계약(contractId) 찾기 let contractEntry = projectEntry.contracts.find( (c) => c.contractId === row.contractId ) if (!contractEntry) { // 새 계약 항목 contractEntry = { contractId: row.contractId, contractNo: row.contractNo, contractName: row.contractName, packages: [], } projectEntry.contracts.push(contractEntry) } // 3) 계약의 packages 배열에 아이템 추가 (중복 체크) // itemName이 같은 항목이 이미 존재하는지 확인 const existingItem = contractEntry.packages.find( (pkg) => pkg.itemName === row.itemName ) // 같은 itemName이 없는 경우에만 추가 if (!existingItem) { contractEntry.packages.push({ itemId: row.itemId, itemName: row.itemName, }) } } return Array.from(projectMap.values()) }