143 lines
4.5 KiB
TypeScript
143 lines
4.5 KiB
TypeScript
import 'dotenv/config';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { mapAllHrProjects } from '../prisma/mapHrProjects';
|
|
|
|
const prisma = new PrismaClient();
|
|
const API_BASE = process.env.TARGET_API_URL?.replace(/\/$/, '');
|
|
|
|
async function importViaPrisma(adminId: string, memberId: string) {
|
|
const tasks = mapAllHrProjects();
|
|
|
|
await prisma.file.deleteMany({});
|
|
await prisma.taskDetail.deleteMany({});
|
|
await prisma.milestone.deleteMany({});
|
|
await prisma.kpiMetric.deleteMany({});
|
|
await prisma.task.deleteMany({});
|
|
|
|
for (const t of tasks) {
|
|
const { milestones, detailContent, ...taskData } = t;
|
|
const task = await prisma.task.create({
|
|
data: {
|
|
...taskData,
|
|
creatorId: adminId,
|
|
assigneeId: 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: adminId,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
console.log(`✅ Prisma import complete: ${tasks.length} tasks`);
|
|
}
|
|
|
|
async function importViaApi(adminId: string, memberId: string) {
|
|
const base = API_BASE!;
|
|
const tasks = mapAllHrProjects();
|
|
|
|
const existingRes = await fetch(`${base}/api/tasks`);
|
|
if (!existingRes.ok) throw new Error(`GET /api/tasks failed: ${existingRes.status}`);
|
|
const existing = (await existingRes.json()) as { id: string }[];
|
|
|
|
for (const task of existing) {
|
|
const del = await fetch(`${base}/api/tasks/${task.id}`, { method: 'DELETE' });
|
|
if (!del.ok && del.status !== 204) throw new Error(`DELETE ${task.id} failed: ${del.status}`);
|
|
}
|
|
|
|
for (const t of tasks) {
|
|
const { milestones, detailContent, ...taskData } = t;
|
|
const body = {
|
|
...taskData,
|
|
startDate: taskData.startDate?.toISOString() ?? null,
|
|
dueDate: taskData.dueDate?.toISOString() ?? null,
|
|
creatorId: adminId,
|
|
assigneeId: memberId,
|
|
};
|
|
|
|
const createRes = await fetch(`${base}/api/tasks`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
});
|
|
if (!createRes.ok) {
|
|
const err = await createRes.text();
|
|
throw new Error(`POST task "${t.title}" failed: ${createRes.status} ${err}`);
|
|
}
|
|
const created = (await createRes.json()) as { id: string };
|
|
|
|
for (const [order, ms] of milestones.entries()) {
|
|
const msRes = await fetch(`${base}/api/milestones/${created.id}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ ...ms, order }),
|
|
});
|
|
if (!msRes.ok) console.warn(` ⚠ milestone skip: ${t.title} / ${ms.title}`);
|
|
}
|
|
|
|
if (detailContent) {
|
|
const detailRes = await fetch(`${base}/api/details/${created.id}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ content: detailContent, authorName: '관리자' }),
|
|
});
|
|
if (!detailRes.ok) console.warn(` ⚠ detail skip: ${t.title}`);
|
|
}
|
|
}
|
|
|
|
console.log(`✅ API import complete: ${tasks.length} tasks → ${base}`);
|
|
}
|
|
|
|
async function main() {
|
|
const tasks = mapAllHrProjects();
|
|
console.log(`📦 data/seed/hr-data.json → ${tasks.length} tasks mapped`);
|
|
|
|
let adminId: string;
|
|
let memberId: string;
|
|
|
|
if (API_BASE) {
|
|
const res = await fetch(`${API_BASE}/api/tasks`);
|
|
const existing = res.ok ? ((await res.json()) as { creatorId: string; assigneeId: string | null }[]) : [];
|
|
if (existing.length > 0) {
|
|
adminId = existing[0].creatorId;
|
|
memberId = existing[0].assigneeId ?? existing[0].creatorId;
|
|
} else {
|
|
throw new Error('API에 기존 task가 없어 creatorId를 확인할 수 없습니다.');
|
|
}
|
|
await importViaApi(adminId, memberId);
|
|
} else {
|
|
const admin = await prisma.user.upsert({
|
|
where: { email: 'admin@eene.com' },
|
|
update: {},
|
|
create: { email: 'admin@eene.com', password: '!', name: '관리자', role: 'ADMIN', department: 'EENE' },
|
|
});
|
|
const member = await prisma.user.upsert({
|
|
where: { email: 'member@eene.com' },
|
|
update: { name: '정성호' },
|
|
create: { email: 'member@eene.com', password: '!', name: '정성호', role: 'MEMBER', department: 'EENE' },
|
|
});
|
|
adminId = admin.id;
|
|
memberId = member.id;
|
|
await importViaPrisma(adminId, memberId);
|
|
}
|
|
}
|
|
|
|
main()
|
|
.catch((err) => {
|
|
console.error('❌ Import failed:', err);
|
|
process.exit(1);
|
|
})
|
|
.finally(() => prisma.$disconnect());
|