// db/schema/menu-v2.ts import { pgTable, pgEnum, integer, varchar, text, timestamp, boolean, index, uniqueIndex } from "drizzle-orm/pg-core"; import { relations } from "drizzle-orm"; import { users } from "./users"; export const menuTreeNodeTypeEnum = pgEnum('menu_tree_node_type', [ 'menu_group', // 메뉴그룹 (1단계) - 헤더에 표시되는 드롭다운 트리거 'group', // 그룹 (2단계) - 드롭다운 내 구분 영역 'menu', // 메뉴 (3단계) - 드롭다운 내 링크 'additional' // 추가 메뉴 - 최상위 단일 링크 (Dashboard, QNA, FAQ 등) ]); export const menuDomainEnum = pgEnum('menu_domain', [ 'evcp', // 내부 사용자용 'partners' // 협력업체용 ]); export const menuTreeNodes = pgTable("menu_tree_nodes", { id: integer("id").primaryKey().generatedAlwaysAsIdentity(), // 도메인 구분 domain: menuDomainEnum("domain").notNull(), // 트리 구조 parentId: integer("parent_id").references((): any => menuTreeNodes.id, { onDelete: "cascade" }), nodeType: menuTreeNodeTypeEnum("node_type").notNull(), sortOrder: integer("sort_order").notNull().default(0), // 다국어 텍스트 (DB 직접 관리) titleKo: varchar("title_ko", { length: 255 }).notNull(), titleEn: varchar("title_en", { length: 255 }), descriptionKo: text("description_ko"), descriptionEn: text("description_en"), // 메뉴 전용 필드 (nodeType === 'menu' 또는 'additional'일 때) menuPath: varchar("menu_path", { length: 255 }), // href 값 (예: /evcp/projects) icon: varchar("icon", { length: 100 }), // 권한 연동 // evcp: Oracle DB SCR_ID 참조 // partners: 자체 권한 시스템 (TODO) scrId: varchar("scr_id", { length: 100 }), // 상태 isActive: boolean("is_active").default(true).notNull(), // 담당자 (evcp 전용) manager1Id: integer("manager1_id").references(() => users.id, { onDelete: "set null" }), manager2Id: integer("manager2_id").references(() => users.id, { onDelete: "set null" }), createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(), updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow().notNull(), }, (table) => ({ domainIdx: index("menu_tree_domain_idx").on(table.domain), parentIdx: index("menu_tree_parent_idx").on(table.parentId), sortOrderIdx: index("menu_tree_sort_order_idx").on(table.sortOrder), menuPathUnique: uniqueIndex("menu_tree_path_unique_idx").on(table.menuPath), scrIdIdx: index("menu_tree_scr_id_idx").on(table.scrId), })); // Relations 정의 export const menuTreeNodesRelations = relations(menuTreeNodes, ({ one, many }) => ({ parent: one(menuTreeNodes, { fields: [menuTreeNodes.parentId], references: [menuTreeNodes.id], relationName: "parentChild", }), children: many(menuTreeNodes, { relationName: "parentChild", }), manager1: one(users, { fields: [menuTreeNodes.manager1Id], references: [users.id], relationName: "menuManager1", }), manager2: one(users, { fields: [menuTreeNodes.manager2Id], references: [users.id], relationName: "menuManager2", }), })); // Type exports export type MenuTreeNode = typeof menuTreeNodes.$inferSelect; export type NewMenuTreeNode = typeof menuTreeNodes.$inferInsert; export type NodeType = (typeof menuTreeNodeTypeEnum.enumValues)[number]; export type MenuDomain = (typeof menuDomainEnum.enumValues)[number];