import 'dotenv/config'; import bcrypt from 'bcrypt'; import { PrismaClient } from '@prisma/client'; import { loadHrProjects, mapAllHrProjects, mapHrProjectToTask, mapHrTeamMembers, normalizePersonName, } from './mapHrProjects'; const prisma = new PrismaClient(); const HUB_CONFIG = { sloganTitle: '분기 중점 과제', sloganLines: ['인사 · 육성 · 문화 · 총무', '개선과제', '정상 추진'], scheduleTitle: '분기 주요 일정', scheduleItems: [ { id: '1', date: '2026-04-01', text: '상반기 채용·온보딩' }, { id: '2', date: '2026-05-15', text: '조직문화 진단·리더십 교육' }, { id: '3', date: '2026-06-20', text: '분기 성과 점검·평가' }, ], routineLabels: ['채용 운영', '학습 지원', '직원 소통', '자산·시설', '문서·행정'], }; async function main() { console.log('🌱 Seeding database from data/seed/hr-data.json ...'); const adminPw = await bcrypt.hash('admin1234!', 12); const memberPw = await bcrypt.hash('member1234!', 12); const admin = await prisma.user.upsert({ where: { email: 'admin@eene.com' }, update: {}, create: { email: 'admin@eene.com', password: adminPw, name: '관리자', role: 'ADMIN', department: 'EENE' }, }); const member = await prisma.user.upsert({ where: { email: 'member@eene.com' }, update: { name: '정성호' }, create: { email: 'member@eene.com', password: memberPw, name: '정성호', role: 'MEMBER', department: 'EENE' }, }); console.log('✅ Users ready'); await prisma.milestoneAssignee.deleteMany({}); await prisma.taskAssignee.deleteMany({}); await prisma.file.deleteMany({}); await prisma.taskDetail.deleteMany({}); await prisma.milestone.deleteMany({}); await prisma.kpiMetric.deleteMany({}); await prisma.task.deleteMany({}); await prisma.teamMember.deleteMany({}); const teamParsed = mapHrTeamMembers(); const memberIdByName = new Map(); for (const tm of teamParsed) { const created = await prisma.teamMember.create({ data: { name: tm.name, rank: tm.rank, role: tm.role, cell: tm.cell, photoUrl: tm.photoUrl, sortOrder: tm.sortOrder, isActive: true, }, }); memberIdByName.set(normalizePersonName(tm.name), created.id); } console.log(`✅ Team members: ${teamParsed.length}명 (hr-data.json TEAM)`); const hrProjects = loadHrProjects(); let taskCount = 0; for (const hp of hrProjects) { if (hp.priority === '상시') continue; const t = mapHrProjectToTask(hp); const { milestones, detailContent, ...taskData } = t; const pmKey = hp.pm?.trim() ? normalizePersonName(hp.pm) : ''; const pmMemberId = pmKey ? memberIdByName.get(pmKey) ?? null : null; const ownerIds = [...new Set( (hp.owners ?? []) .map((o) => normalizePersonName(o)) .filter(Boolean) .map((key) => memberIdByName.get(key)) .filter((id): id is string => !!id), )]; const task = await prisma.task.create({ data: { ...taskData, creatorId: admin.id, assigneeId: member.id, pmMemberId, ...(ownerIds.length > 0 ? { taskAssignees: { create: ownerIds.map((memberId) => ({ memberId })) } } : {}), }, }); for (const [order, ms] of milestones.entries()) { await prisma.milestone.create({ data: { ...ms, taskId: task.id, order }, }); } if (detailContent) { await prisma.taskDetail.create({ data: { taskId: task.id, content: detailContent, updatedBy: admin.id, }, }); } taskCount += 1; } await prisma.hubConfig.upsert({ where: { id: 'default' }, update: { config: HUB_CONFIG }, create: { id: 'default', config: HUB_CONFIG }, }); console.log(`✅ Tasks: ${taskCount}개 (PROJECTS)`); console.log('✅ Hub config reset (5 대분류 상시업무)'); console.log('🎉 Seeding complete!'); console.log(' → 브라우저에서 Ctrl+F5 후, 필요 시 DevTools에서 localStorage 허브 키 삭제'); } main().catch(console.error).finally(() => prisma.$disconnect());