summaryrefslogtreecommitdiff
path: root/db/seeds/menu-v2-seed.ts
diff options
context:
space:
mode:
Diffstat (limited to 'db/seeds/menu-v2-seed.ts')
-rw-r--r--db/seeds/menu-v2-seed.ts145
1 files changed, 145 insertions, 0 deletions
diff --git a/db/seeds/menu-v2-seed.ts b/db/seeds/menu-v2-seed.ts
new file mode 100644
index 00000000..0c6b310d
--- /dev/null
+++ b/db/seeds/menu-v2-seed.ts
@@ -0,0 +1,145 @@
+// db/seeds/menu-v2-seed.ts
+import { mainNav, additionalNav, mainNavVendor, additionalNavVendor, MenuSection, MenuItem } from "@/config/menuConfig";
+import koMenu from '@/i18n/locales/ko/menu.json';
+import enMenu from '@/i18n/locales/en/menu.json';
+import db from "@/db/db";
+import { menuTreeNodes } from "@/db/schema/menu-v2";
+import type { MenuDomain } from "@/lib/menu-v2/types";
+
+type TranslationObject = { [key: string]: string | TranslationObject };
+
+// 중첩 키로 번역 값 가져오기
+function getTranslation(key: string, locale: 'ko' | 'en'): string {
+ const translations: TranslationObject = locale === 'ko' ? koMenu : enMenu;
+ const keys = key.split('.');
+ let value: string | TranslationObject | undefined = translations;
+
+ for (const k of keys) {
+ if (typeof value === 'object' && value !== null) {
+ value = value[k];
+ } else {
+ return key;
+ }
+ if (value === undefined) return key;
+ }
+
+ return typeof value === 'string' ? value : key;
+}
+
+export async function seedMenuTree() {
+ console.log('🌱 Starting menu tree seeding...');
+
+ // 기존 데이터 삭제
+ await db.delete(menuTreeNodes);
+ console.log('✅ Cleared existing menu tree data');
+
+ // evcp 도메인 seed
+ await seedDomainMenus('evcp', mainNav, additionalNav);
+ console.log('✅ Seeded evcp menu tree');
+
+ // partners 도메인 seed
+ await seedDomainMenus('partners', mainNavVendor, additionalNavVendor);
+ console.log('✅ Seeded partners menu tree');
+
+ console.log('🎉 Menu tree seeding completed!');
+}
+
+async function seedDomainMenus(
+ domain: MenuDomain,
+ navConfig: MenuSection[],
+ additionalConfig: MenuItem[]
+) {
+ // 최상위 sortOrder (메뉴그룹과 최상위 메뉴 모두 같은 레벨에서 정렬)
+ let topLevelSortOrder = 0;
+
+ // 메인 네비게이션 (메뉴그룹 → 그룹 → 메뉴)
+ for (const section of navConfig) {
+ // 1단계: 메뉴그룹 생성
+ const [menuGroup] = await db.insert(menuTreeNodes).values({
+ domain,
+ parentId: null,
+ nodeType: 'menu_group',
+ titleKo: getTranslation(section.titleKey, 'ko'),
+ titleEn: getTranslation(section.titleKey, 'en'),
+ sortOrder: topLevelSortOrder++,
+ isActive: true,
+ }).returning();
+
+ // groupKey별로 그룹화
+ const groupedItems = new Map<string, MenuItem[]>();
+ section.items.forEach(item => {
+ const groupKey = item.groupKey || '__default__';
+ if (!groupedItems.has(groupKey)) {
+ groupedItems.set(groupKey, []);
+ }
+ groupedItems.get(groupKey)!.push(item);
+ });
+
+ let groupSortOrder = 0;
+ for (const [groupKey, items] of groupedItems) {
+ let parentId = menuGroup.id;
+
+ // groupKey가 있으면 2단계 그룹 생성
+ if (groupKey !== '__default__') {
+ const [group] = await db.insert(menuTreeNodes).values({
+ domain,
+ parentId: menuGroup.id,
+ nodeType: 'group',
+ titleKo: getTranslation(groupKey, 'ko'),
+ titleEn: getTranslation(groupKey, 'en'),
+ sortOrder: groupSortOrder++,
+ isActive: true,
+ }).returning();
+ parentId = group.id;
+ }
+
+ // 3단계: 메뉴 생성
+ let menuSortOrder = 0;
+ for (const item of items) {
+ await db.insert(menuTreeNodes).values({
+ domain,
+ parentId,
+ nodeType: 'menu',
+ titleKo: getTranslation(item.titleKey, 'ko'),
+ titleEn: getTranslation(item.titleKey, 'en'),
+ descriptionKo: item.descriptionKey ? getTranslation(item.descriptionKey, 'ko') : null,
+ descriptionEn: item.descriptionKey ? getTranslation(item.descriptionKey, 'en') : null,
+ menuPath: item.href,
+ icon: item.icon || null,
+ sortOrder: menuSortOrder++,
+ isActive: true,
+ });
+ }
+ }
+ }
+
+ // 최상위 단일 링크 메뉴 (기존 additional)
+ // nodeType을 'menu'로 설정하고 parentId를 null로 유지
+ for (const item of additionalConfig) {
+ await db.insert(menuTreeNodes).values({
+ domain,
+ parentId: null,
+ nodeType: 'menu', // 'additional' 대신 'menu' 사용
+ titleKo: getTranslation(item.titleKey, 'ko'),
+ titleEn: getTranslation(item.titleKey, 'en'),
+ descriptionKo: item.descriptionKey ? getTranslation(item.descriptionKey, 'ko') : null,
+ descriptionEn: item.descriptionKey ? getTranslation(item.descriptionKey, 'en') : null,
+ menuPath: item.href,
+ sortOrder: topLevelSortOrder++, // 메뉴그룹 다음 순서
+ isActive: true,
+ });
+ }
+}
+
+// CLI에서 직접 실행 가능하도록
+if (require.main === module) {
+ seedMenuTree()
+ .then(() => {
+ console.log('Seed completed successfully');
+ process.exit(0);
+ })
+ .catch((error) => {
+ console.error('Seed failed:', error);
+ process.exit(1);
+ });
+}