"use server"; import db from "@/db/db"; import { integrations } from "@/db/schema/integration"; import { eq } from "drizzle-orm"; import { GetIntegrationsSchema } from "./validations"; import { filterColumns } from "@/lib/filter-columns"; import { asc, desc, ilike, and, or, count } from "drizzle-orm"; /* ----------------------------------------------------- 1) 통합 목록 조회 ----------------------------------------------------- */ export async function getIntegrations(input: GetIntegrationsSchema) { try { const offset = (input.page - 1) * input.perPage; // 1. where 절 let advancedWhere; try { advancedWhere = filterColumns({ table: integrations, filters: input.filters, joinOperator: input.joinOperator, }); } catch (whereErr) { console.error("Error building advanced where:", whereErr); advancedWhere = undefined; } let globalWhere; if (input.search) { try { const s = `%${input.search}%`; globalWhere = or( ilike(integrations.code, s), ilike(integrations.name, s), ilike(integrations.sourceSystem, s), ilike(integrations.targetSystem, s), ilike(integrations.description, s) ); } catch (searchErr) { console.error("Error building search where:", searchErr); globalWhere = undefined; } } // 2. where 결합 let finalWhere; const whereArr = [advancedWhere, globalWhere].filter(Boolean); if (whereArr.length === 2) { finalWhere = and(...whereArr); } else if (whereArr.length === 1) { finalWhere = whereArr[0]; } else { finalWhere = undefined; } // 3. order by let orderBy = [asc(integrations.createdAt)]; try { if (input.sort.length > 0) { const sortItems = input.sort .map((item) => { if (!item || !item.id || typeof item.id !== "string") return null; // 기본 정렬 컬럼들만 허용 switch (item.id) { case "id": return item.desc ? desc(integrations.id) : asc(integrations.id); case "code": return item.desc ? desc(integrations.code) : asc(integrations.code); case "name": return item.desc ? desc(integrations.name) : asc(integrations.name); case "type": return item.desc ? desc(integrations.type) : asc(integrations.type); case "status": return item.desc ? desc(integrations.status) : asc(integrations.status); case "sourceSystem": return item.desc ? desc(integrations.sourceSystem) : asc(integrations.sourceSystem); case "targetSystem": return item.desc ? desc(integrations.targetSystem) : asc(integrations.targetSystem); case "createdAt": return item.desc ? desc(integrations.createdAt) : asc(integrations.createdAt); case "updatedAt": return item.desc ? desc(integrations.updatedAt) : asc(integrations.updatedAt); default: return null; } }) .filter((v): v is Exclude => v !== null); if (sortItems.length > 0) { orderBy = sortItems; } } } catch (orderErr) { console.error("Error building order by:", orderErr); } // 4. 쿼리 실행 let data = []; let total = 0; try { const queryBuilder = db.select().from(integrations); if (finalWhere !== undefined) { queryBuilder.where(finalWhere); } if (orderBy && orderBy.length > 0) { queryBuilder.orderBy(...orderBy); } if (typeof offset === "number" && !isNaN(offset)) { queryBuilder.offset(offset); } if (typeof input.perPage === "number" && !isNaN(input.perPage)) { queryBuilder.limit(input.perPage); } data = await queryBuilder; const countBuilder = db .select({ count: count() }) .from(integrations); if (finalWhere !== undefined) { countBuilder.where(finalWhere); } const countResult = await countBuilder; total = countResult[0]?.count || 0; } catch (queryErr) { console.error("Query execution failed:", queryErr); throw queryErr; } const pageCount = Math.ceil(total / input.perPage); return { data, pageCount }; } catch (err) { console.error("Error in getIntegrations:", err); if (err instanceof Error) { console.error("Error message:", err.message); console.error("Error stack:", err.stack); } return { data: [], pageCount: 0 }; } } /* ----------------------------------------------------- 2) 통합 생성 ----------------------------------------------------- */ export async function createIntegration(data: Omit) { try { const [created] = await db.insert(integrations).values({ ...data, createdAt: new Date(), updatedAt: new Date(), }).returning(); return { data: created }; } catch (err) { console.error("Error creating integration:", err); return { error: "생성 중 오류가 발생했습니다." }; } } /* ----------------------------------------------------- 3) 통합 수정 ----------------------------------------------------- */ export async function updateIntegration(id: number, data: Partial) { try { const [updated] = await db .update(integrations) .set({ ...data, updatedAt: new Date(), }) .where(eq(integrations.id, id)) .returning(); return { data: updated }; } catch (err) { console.error("Error updating integration:", err); return { error: "수정 중 오류가 발생했습니다." }; } } /* ----------------------------------------------------- 4) 통합 삭제 ----------------------------------------------------- */ export async function deleteIntegration(id: number) { try { await db.delete(integrations).where(eq(integrations.id, id)); return { success: true }; } catch (err) { console.error("Error deleting integration:", err); return { error: "삭제 중 오류가 발생했습니다." }; } } // 통합 조회 (단일) export async function getIntegration(id: number): Promise> { try { const result = await db.select().from(integrations).where(eq(integrations.id, id)).limit(1); if (result.length === 0) { return { error: "통합을 찾을 수 없습니다." }; } return { data: result[0] }; } catch (error) { console.error("통합 조회 오류:", error); return { error: "통합 조회에 실패했습니다." }; } } // 기존 함수들도 유지 (하위 호환성) export async function getIntegrationList() { try { const data = await db.select().from(integrations); return data; } catch (error) { console.error("통합 목록 조회 실패:", error); return []; } }