summaryrefslogtreecommitdiff
path: root/db/seeds/menu-v2-seed.ts
blob: 0c6b310df50aed2a1a01f1ab9fdc9a9296e8d566 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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);
    });
}