summaryrefslogtreecommitdiff
path: root/lib/project-avl/service.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-04-28 02:13:30 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-04-28 02:13:30 +0000
commitef4c533ebacc2cdc97e518f30e9a9350004fcdfb (patch)
tree345251a3ed0f4429716fa5edaa31024d8f4cb560 /lib/project-avl/service.ts
parent9ceed79cf32c896f8a998399bf1b296506b2cd4a (diff)
~20250428 작업사항
Diffstat (limited to 'lib/project-avl/service.ts')
-rw-r--r--lib/project-avl/service.ts106
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/project-avl/service.ts b/lib/project-avl/service.ts
new file mode 100644
index 00000000..6ba10c5e
--- /dev/null
+++ b/lib/project-avl/service.ts
@@ -0,0 +1,106 @@
+// src/lib/projectApprovedVendors/service.ts
+"use server"; // Next.js 서버 액션에서 직접 import하려면 (선택)
+
+import { revalidateTag, unstable_noStore } from "next/cache";
+import db from "@/db/db";
+import { customAlphabet } from "nanoid";
+
+import { filterColumns } from "@/lib/filter-columns";
+import { unstable_cache } from "@/lib/unstable-cache";
+import { getErrorMessage } from "@/lib/handle-error";
+
+import { asc, desc, ilike, inArray, and, gte, lte, not, or ,eq} from "drizzle-orm";
+import { GetProjectAVLSchema } from "./validations";
+import { projectApprovedVendors } from "@/db/schema";
+import { countProjectAVLs, selectProejctAVLs } from "./repository";
+
+
+/* -----------------------------------------------------
+ 1) 조회 관련
+----------------------------------------------------- */
+
+/**
+ * 복잡한 조건으로 Item 목록을 조회 (+ pagination) 하고,
+ * 총 개수에 따라 pageCount를 계산해서 리턴.
+ * Next.js의 unstable_cache를 사용해 일정 시간 캐시.
+ */
+export async function getProjecTAVL(input: GetProjectAVLSchema) {
+
+ return unstable_cache(
+ async () => {
+ try {
+ const offset = (input.page - 1) * input.perPage;
+
+ // const advancedTable = input.flags.includes("advancedTable");
+ const advancedTable = true;
+
+ // advancedTable 모드면 filterColumns()로 where 절 구성
+ const advancedWhere = filterColumns({
+ table: projectApprovedVendors,
+ filters: input.filters,
+ joinOperator: input.joinOperator,
+ });
+
+
+ let globalWhere
+ if (input.search) {
+ const s = `%${input.search}%`
+ globalWhere =
+ or(
+ ilike(projectApprovedVendors.vendor_name, s),
+ ilike(projectApprovedVendors.tax_id, s)
+ , ilike(projectApprovedVendors.vendor_email, s)
+ , ilike(projectApprovedVendors.vendor_type_name_ko, s)
+ , ilike(projectApprovedVendors.project_name, s)
+ , ilike(projectApprovedVendors.project_code, s)
+ )
+ // 필요시 여러 칼럼 OR조건 (status, priority, etc)
+ }
+
+ const finalWhere = and(
+ // advancedWhere or your existing conditions
+ advancedWhere,
+ globalWhere // and()함수로 결합 or or() 등으로 결합
+ )
+
+
+ // 아니면 ilike, inArray, gte 등으로 where 절 구성
+ const where = finalWhere
+
+
+ const orderBy =
+ input.sort.length > 0
+ ? input.sort.map((item) =>
+ item.desc ? desc(projectApprovedVendors[item.id]) : asc(projectApprovedVendors[item.id])
+ )
+ : [asc(projectApprovedVendors.approved_at)];
+
+ // 트랜잭션 내부에서 Repository 호출
+ const { data, total } = await db.transaction(async (tx) => {
+ const data = await selectProejctAVLs(tx, {
+ where,
+ orderBy,
+ offset,
+ limit: input.perPage,
+ });
+
+ const total = await countProjectAVLs(tx, where);
+ return { data, total };
+ });
+
+ const pageCount = Math.ceil(total / input.perPage);
+
+ return { data, pageCount };
+ } catch (err) {
+ // 에러 발생 시 디폴트
+ return { data: [], pageCount: 0 };
+ }
+ },
+ [JSON.stringify(input)], // 캐싱 키
+ {
+ revalidate: 3600,
+ tags: ["project-approved-vendors"], // revalidateTag("projectApprovedVendors") 호출 시 무효화
+ }
+ )();
+}
+