206 lines
9.6 KiB
TypeScript
206 lines
9.6 KiB
TypeScript
import { PrismaClient, UserRole, UserStatus } from '@prisma/client';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
// 간단한 비밀번호 해시 함수 (실제 프로덕션에서는 bcrypt 사용 권장)
|
|
function hashPassword(password: string): string {
|
|
// 개발 환경용 간단한 해시 (실제로는 bcrypt 사용)
|
|
// 모든 사용자의 기본 비밀번호는 "password123"으로 설정
|
|
return '$2a$10$placeholder_hash_for_development_only';
|
|
}
|
|
|
|
async function main() {
|
|
console.log('🌱 Seeding database...');
|
|
|
|
// 1. 사용자 데이터 생성
|
|
const mockUsers = [
|
|
{ id: "1", joinDate: "2024-01-15", name: "김민준", email: "user1@example.com", role: "learner", status: "active" },
|
|
{ id: "2", joinDate: "2024-01-20", name: "이서준", email: "user2@example.com", role: "learner", status: "active" },
|
|
{ id: "3", joinDate: "2024-02-05", name: "박도윤", email: "user3@example.com", role: "learner", status: "inactive" },
|
|
{ id: "4", joinDate: "2024-02-10", name: "최예준", email: "user4@example.com", role: "instructor", status: "active" },
|
|
{ id: "5", joinDate: "2024-02-15", name: "정시우", email: "user5@example.com", role: "instructor", status: "active" },
|
|
{ id: "6", joinDate: "2024-02-20", name: "강하준", email: "user6@example.com", role: "learner", status: "active" },
|
|
{ id: "7", joinDate: "2024-03-01", name: "조주원", email: "user7@example.com", role: "admin", status: "active" },
|
|
{ id: "8", joinDate: "2024-03-05", name: "윤지호", email: "user8@example.com", role: "learner", status: "active" },
|
|
{ id: "9", joinDate: "2024-03-10", name: "장준서", email: "user9@example.com", role: "learner", status: "inactive" },
|
|
{ id: "10", joinDate: "2024-03-15", name: "임건우", email: "user10@example.com", role: "instructor", status: "active" },
|
|
{ id: "11", joinDate: "2024-03-20", name: "한서연", email: "user11@example.com", role: "learner", status: "active" },
|
|
{ id: "12", joinDate: "2024-04-01", name: "오서윤", email: "user12@example.com", role: "learner", status: "active" },
|
|
{ id: "13", joinDate: "2024-04-05", name: "서지우", email: "user13@example.com", role: "instructor", status: "inactive" },
|
|
{ id: "14", joinDate: "2024-04-10", name: "신서현", email: "user14@example.com", role: "learner", status: "active" },
|
|
{ id: "15", joinDate: "2024-04-15", name: "권민서", email: "user15@example.com", role: "admin", status: "active" },
|
|
{ id: "16", joinDate: "2024-04-20", name: "황하은", email: "user16@example.com", role: "learner", status: "active" },
|
|
{ id: "17", joinDate: "2024-05-01", name: "안예은", email: "user17@example.com", role: "learner", status: "inactive" },
|
|
{ id: "18", joinDate: "2024-05-05", name: "송윤서", email: "user18@example.com", role: "instructor", status: "active" },
|
|
{ id: "19", joinDate: "2024-05-10", name: "전채원", email: "user19@example.com", role: "learner", status: "active" },
|
|
{ id: "20", joinDate: "2024-05-15", name: "홍지원", email: "user20@example.com", role: "learner", status: "active" },
|
|
{ id: "21", joinDate: "2024-05-20", name: "김민수", email: "user21@example.com", role: "instructor", status: "active" },
|
|
{ id: "22", joinDate: "2024-06-01", name: "이영희", email: "user22@example.com", role: "learner", status: "active" },
|
|
{ id: "23", joinDate: "2024-06-05", name: "박철수", email: "user23@example.com", role: "learner", status: "inactive" },
|
|
{ id: "24", joinDate: "2024-06-10", name: "최수진", email: "user24@example.com", role: "admin", status: "active" },
|
|
{ id: "25", joinDate: "2024-06-15", name: "정대현", email: "user25@example.com", role: "instructor", status: "active" },
|
|
{ id: "26", joinDate: "2024-06-20", name: "강미영", email: "user26@example.com", role: "learner", status: "active" },
|
|
{ id: "27", joinDate: "2024-07-01", name: "조성호", email: "user27@example.com", role: "learner", status: "active" },
|
|
{ id: "28", joinDate: "2024-07-05", name: "윤지은", email: "user28@example.com", role: "instructor", status: "inactive" },
|
|
{ id: "29", joinDate: "2024-07-10", name: "장현우", email: "user29@example.com", role: "learner", status: "active" },
|
|
{ id: "30", joinDate: "2024-07-15", name: "임소영", email: "user30@example.com", role: "learner", status: "active" },
|
|
];
|
|
|
|
// 사용자 생성 및 ID 매핑 저장
|
|
const userMap = new Map<string, string>();
|
|
|
|
for (const userData of mockUsers) {
|
|
const role = userData.role === 'instructor' ? UserRole.ADMIN :
|
|
userData.role === 'admin' ? UserRole.ADMIN :
|
|
UserRole.LEARNER;
|
|
const status = userData.status === 'active' ? UserStatus.ACTIVE : UserStatus.INACTIVE;
|
|
|
|
const user = await prisma.user.upsert({
|
|
where: { email: userData.email },
|
|
update: {},
|
|
create: {
|
|
email: userData.email,
|
|
password: hashPassword('password123'), // 기본 비밀번호
|
|
name: userData.name,
|
|
role,
|
|
status,
|
|
joinDate: new Date(userData.joinDate),
|
|
},
|
|
});
|
|
|
|
userMap.set(userData.id, user.id);
|
|
}
|
|
|
|
console.log(`✅ Created ${userMap.size} users`);
|
|
|
|
// 관리자 계정 찾기 (공지사항 작성자용)
|
|
const adminUsers = await prisma.user.findMany({
|
|
where: { role: UserRole.ADMIN, status: UserStatus.ACTIVE },
|
|
});
|
|
const defaultAdmin = adminUsers[0];
|
|
|
|
// 2. 교육과정 데이터 생성
|
|
const mockCourses = [
|
|
{ id: "1", courseName: "웹 개발 기초", instructorName: "최예준", createdAt: "2024-01-15", createdBy: "관리자" },
|
|
{ id: "2", courseName: "React 실전 프로젝트", instructorName: "정시우", createdAt: "2024-02-20", createdBy: "관리자" },
|
|
{ id: "3", courseName: "데이터베이스 설계", instructorName: "임건우", createdAt: "2024-03-10", createdBy: "관리자" },
|
|
{ id: "4", courseName: "Node.js 백엔드 개발", instructorName: "송윤서", createdAt: "2024-03-25", createdBy: "관리자" },
|
|
{ id: "5", courseName: "TypeScript 마스터", instructorName: "김민수", createdAt: "2024-04-05", createdBy: "관리자" },
|
|
{ id: "6", courseName: "UI/UX 디자인 기초", instructorName: "정대현", createdAt: "2024-04-18", createdBy: "관리자" },
|
|
{ id: "7", courseName: "모바일 앱 개발", instructorName: "최예준", createdAt: "2024-05-02", createdBy: "관리자" },
|
|
{ id: "8", courseName: "클라우드 인프라", instructorName: "정시우", createdAt: "2024-05-15", createdBy: "관리자" },
|
|
{ id: "9", courseName: "머신러닝 입문", instructorName: "임건우", createdAt: "2024-06-01", createdBy: "관리자" },
|
|
{ id: "10", courseName: "DevOps 실무", instructorName: "송윤서", createdAt: "2024-06-20", createdBy: "관리자" },
|
|
];
|
|
|
|
const courseMap = new Map<string, string>();
|
|
|
|
for (const courseData of mockCourses) {
|
|
// 강사 이름으로 사용자 찾기
|
|
const instructor = await prisma.user.findFirst({
|
|
where: { name: courseData.instructorName, role: UserRole.ADMIN },
|
|
});
|
|
|
|
if (!instructor) {
|
|
console.warn(`⚠️ Instructor not found: ${courseData.instructorName}`);
|
|
continue;
|
|
}
|
|
|
|
const course = await prisma.course.create({
|
|
data: {
|
|
courseName: courseData.courseName,
|
|
instructorId: instructor.id,
|
|
createdById: defaultAdmin?.id || instructor.id,
|
|
createdAt: new Date(courseData.createdAt),
|
|
},
|
|
});
|
|
|
|
courseMap.set(courseData.id, course.id);
|
|
}
|
|
|
|
console.log(`✅ Created ${courseMap.size} courses`);
|
|
|
|
// 3. 공지사항 데이터 생성
|
|
const mockNotices = [
|
|
{
|
|
id: 2,
|
|
title: '공지사항 제목이 노출돼요',
|
|
date: '2025-09-10',
|
|
views: 1230,
|
|
writer: '문지호',
|
|
content: [
|
|
'사이트 이용 관련 주요 변경 사항을 안내드립니다.',
|
|
'변경되는 내용은 공지일자로부터 즉시 적용됩니다.',
|
|
],
|
|
},
|
|
{
|
|
id: 1,
|
|
title: '📢 방사선학 온라인 강의 수강 안내 및 필수 공지',
|
|
date: '2025-06-28',
|
|
views: 594,
|
|
writer: '문지호',
|
|
hasAttachment: true,
|
|
content: [
|
|
'온라인 강의 수강 방법과 필수 확인 사항을 안내드립니다.',
|
|
'수강 기간 및 출석, 과제 제출 관련 정책을 반드시 확인해 주세요.',
|
|
],
|
|
},
|
|
];
|
|
|
|
// 공지사항 작성자 찾기 또는 생성
|
|
let noticeWriter = await prisma.user.findFirst({
|
|
where: { name: '문지호' },
|
|
});
|
|
|
|
if (!noticeWriter) {
|
|
noticeWriter = await prisma.user.create({
|
|
data: {
|
|
email: 'munjih@example.com',
|
|
password: hashPassword('password123'),
|
|
name: '문지호',
|
|
role: UserRole.ADMIN,
|
|
status: UserStatus.ACTIVE,
|
|
},
|
|
});
|
|
}
|
|
|
|
for (const noticeData of mockNotices) {
|
|
const notice = await prisma.notice.create({
|
|
data: {
|
|
title: noticeData.title,
|
|
content: noticeData.content?.join('\n') || '',
|
|
writerId: noticeWriter.id,
|
|
views: noticeData.views,
|
|
hasAttachment: noticeData.hasAttachment || false,
|
|
date: new Date(noticeData.date),
|
|
},
|
|
});
|
|
|
|
// 첨부파일이 있는 경우
|
|
if (noticeData.hasAttachment) {
|
|
await prisma.noticeAttachment.create({
|
|
data: {
|
|
noticeId: notice.id,
|
|
fileName: '공지사항_첨부파일.pdf',
|
|
filePath: '/uploads/notices/sample.pdf',
|
|
fileSize: 1024000, // 1MB
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
console.log(`✅ Created ${mockNotices.length} notices`);
|
|
|
|
console.log('🎉 Seeding completed!');
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error('❌ Error seeding database:', e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|