Files
eene_dashboard/backend/prisma/seed.ts
EENE Dashboard b3f2da203b EENE Dashboard upload to Gitea
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 16:59:34 +09:00

274 lines
4.3 KiB
TypeScript

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<string, string>();
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());