// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // ============================================ // 사용자 관련 모델 // ============================================ /// 사용자 (User) /// 권한 설정 페이지, 로그인/회원가입에서 사용 model User { id String @id @default(uuid()) email String @unique // 이메일 (아이디로 사용) password String // 비밀번호 (해시화되어 저장) name String // 성명 phone String? // 휴대폰 번호 gender String? // 성별 (M/F) birthdate DateTime? // 생년월일 role UserRole @default(LEARNER) // 권한: 학습자, 관리자 status UserStatus @default(ACTIVE) // 계정 상태: 활성화, 비활성화 joinDate DateTime @default(now()) // 가입일 // 관계 createdCourses Course[] @relation("CourseCreator") instructedCourses Course[] @relation("CourseInstructor") createdLessons Lesson[] @relation("LessonCreator") createdNotices Notice[] @relation("NoticeWriter") enrollments Enrollment[] // 수강 등록 certificates Certificate[] // 수료증 logs Log[] // 로그 기록 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([email]) @@index([role]) @@index([status]) @@map("users") } enum UserRole { LEARNER // 학습자 ADMIN // 관리자 (강사 권한 포함) } enum UserStatus { ACTIVE // 활성화 INACTIVE // 비활성화 } // ============================================ // 교육과정 관련 모델 // ============================================ /// 교육과정 (Course) /// 교육과정 관리 페이지에서 사용 model Course { id String @id @default(uuid()) courseName String // 교육과정명 instructorId String // 강사 ID (User의 ADMIN 역할) instructor User @relation("CourseInstructor", fields: [instructorId], references: [id]) createdById String // 등록자 ID createdBy User @relation("CourseCreator", fields: [createdById], references: [id]) createdAt DateTime @default(now()) // 생성일 // 관계 lessons Lesson[] // 강좌 목록 updatedAt DateTime @updatedAt @@index([instructorId]) @@index([createdById]) @@index([createdAt]) @@map("courses") } /// 강좌 (Lesson) /// 강좌 관리 페이지에서 사용 model Lesson { id String @id @default(uuid()) courseId String // 교육과정 ID course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) lessonName String // 강좌명 learningGoal String? @db.Text // 학습 목표 (최대 1000자) createdById String // 등록자 ID createdBy User @relation("LessonCreator", fields: [createdById], references: [id]) createdAt DateTime @default(now()) // 등록일 // 관계 videos LessonVideo[] // 강좌 영상 vrContents LessonVRContent[] // VR 콘텐츠 questions Question[] // 학습 평가 문제 attachments LessonAttachment[] // 첨부파일 enrollments Enrollment[] // 수강 등록 updatedAt DateTime @updatedAt @@index([courseId]) @@index([createdById]) @@index([createdAt]) @@map("lessons") } /// 강좌 영상 (LessonVideo) /// 강좌 등록 시 첨부되는 영상 파일 (최대 10개, 30MB 미만) model LessonVideo { id String @id @default(uuid()) lessonId String // 강좌 ID lesson Lesson @relation(fields: [lessonId], references: [id], onDelete: Cascade) fileName String // 파일명 filePath String // 파일 저장 경로 fileSize Int // 파일 크기 (bytes) order Int // 순서 createdAt DateTime @default(now()) @@index([lessonId]) @@map("lesson_videos") } /// VR 콘텐츠 (LessonVRContent) /// 강좌 등록 시 첨부되는 VR 콘텐츠 파일 (최대 10개, 30MB 미만) model LessonVRContent { id String @id @default(uuid()) lessonId String // 강좌 ID lesson Lesson @relation(fields: [lessonId], references: [id], onDelete: Cascade) fileName String // 파일명 filePath String // 파일 저장 경로 fileSize Int // 파일 크기 (bytes) order Int // 순서 createdAt DateTime @default(now()) @@index([lessonId]) @@map("lesson_vr_contents") } /// 강좌 첨부파일 (LessonAttachment) /// 강좌 관련 기타 첨부파일 model LessonAttachment { id String @id @default(uuid()) lessonId String // 강좌 ID lesson Lesson @relation(fields: [lessonId], references: [id], onDelete: Cascade) fileName String // 파일명 filePath String // 파일 저장 경로 fileSize Int // 파일 크기 (bytes) createdAt DateTime @default(now()) @@index([lessonId]) @@map("lesson_attachments") } // ============================================ // 학습 평가 관련 모델 // ============================================ /// 문제 (Question) /// 문제 은행 페이지에서 사용, 강좌별 학습 평가 문제 model Question { id String @id @default(uuid()) lessonId String? // 강좌 ID (선택적, 문제 은행에만 있을 수도 있음) lesson Lesson? @relation(fields: [lessonId], references: [id], onDelete: SetNull) question String @db.Text // 문제 내용 type QuestionType @default(MULTIPLE_CHOICE) // 문제 유형 options Json? // 선택지 (객관식인 경우) correctAnswer String @db.Text // 정답 explanation String? @db.Text // 해설 points Int @default(1) // 배점 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([lessonId]) @@map("questions") } enum QuestionType { MULTIPLE_CHOICE // 객관식 SHORT_ANSWER // 단답형 ESSAY // 서술형 } // ============================================ // 공지사항 관련 모델 // ============================================ /// 공지사항 (Notice) /// 공지사항 관리 페이지에서 사용 model Notice { id String @id @default(uuid()) title String // 제목 content String @db.Text // 내용 (최대 1000자) writerId String // 작성자 ID writer User @relation("NoticeWriter", fields: [writerId], references: [id]) views Int @default(0) // 조회수 hasAttachment Boolean @default(false) // 첨부파일 여부 date DateTime @default(now()) // 게시일 // 관계 attachment NoticeAttachment? // 첨부파일 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([writerId]) @@index([date]) @@map("notices") } /// 공지사항 첨부파일 (NoticeAttachment) /// 공지사항에 첨부되는 파일 (최대 1개, 30MB 미만) model NoticeAttachment { id String @id @default(uuid()) noticeId String @unique // 공지사항 ID notice Notice @relation(fields: [noticeId], references: [id], onDelete: Cascade) fileName String // 파일명 filePath String // 파일 저장 경로 fileSize Int // 파일 크기 (bytes) createdAt DateTime @default(now()) @@map("notice_attachments") } // ============================================ // 학습 자료 관련 모델 // ============================================ /// 학습 자료 (Resource) /// 학습 자료실 페이지에서 사용 model Resource { id String @id @default(uuid()) title String // 제목 description String? @db.Text // 설명 filePath String? // 파일 경로 (파일이 있는 경우) fileName String? // 파일명 fileSize Int? // 파일 크기 (bytes) category String? // 카테고리 views Int @default(0) // 조회수 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([category]) @@index([createdAt]) @@map("resources") } // ============================================ // 수강 및 수료 관련 모델 // ============================================ /// 수강 등록 (Enrollment) /// 사용자가 강좌를 수강하는 관계 model Enrollment { id String @id @default(uuid()) userId String // 사용자 ID user User @relation(fields: [userId], references: [id], onDelete: Cascade) lessonId String // 강좌 ID lesson Lesson @relation(fields: [lessonId], references: [id], onDelete: Cascade) progress Int @default(0) // 학습 진행률 (0-100) completedAt DateTime? // 완료일 enrolledAt DateTime @default(now()) // 등록일 @@unique([userId, lessonId]) @@index([userId]) @@index([lessonId]) @@map("enrollments") } /// 수료증 (Certificate) /// 수료증 발급/검증키 관리 페이지에서 사용 model Certificate { id String @id @default(uuid()) userId String // 사용자 ID user User @relation(fields: [userId], references: [id], onDelete: Cascade) lessonId String? // 강좌 ID (강좌 완료 시 발급) courseId String? // 교육과정 ID (과정 완료 시 발급) verificationKey String @unique // 검증 키 issuedAt DateTime @default(now()) // 발급일 @@index([userId]) @@index([verificationKey]) @@map("certificates") } // ============================================ // 로그 관련 모델 // ============================================ /// 로그 (Log) /// 로그/접속 기록 페이지에서 사용 model Log { id String @id @default(uuid()) userId String? // 사용자 ID (로그인한 경우) user User? @relation(fields: [userId], references: [id], onDelete: SetNull) action String // 액션 (예: LOGIN, LOGOUT, VIEW_LESSON, etc.) ipAddress String? // IP 주소 userAgent String? // User Agent details Json? // 추가 상세 정보 createdAt DateTime @default(now()) // 기록 시간 @@index([userId]) @@index([action]) @@index([createdAt]) @@map("logs") }