generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// ─── 사용자 ──────────────────────────────────────────────────

model User {
  id         String   @id @default(cuid())
  email      String   @unique
  password   String
  name       String
  role       Role     @default(MEMBER)
  department String?
  isActive   Boolean  @default(true)
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  createdTasks  Task[]       @relation("CreatedTasks")
  assignedTasks Task[]       @relation("AssignedTasks")
  taskDetails   TaskDetail[]
  uploadedFiles File[]
  auditLogs     AuditLog[]

  @@map("users")
}

// ─── 팀 인원 (조직도 마스터) ─────────────────────────────────

model TeamMember {
  id        String   @id @default(cuid())
  name      String
  rank      String?  // 직급 (수석연구원, 선임연구원 등)
  role      String?  // 직책 (팀장, 셀장, 팀원 등)
  cell      String?  // 셀 (HR, 총무, 리더 — 리더/빈값이면 상단 팀장 영역)
  contact   String?
  photoUrl  String?
  sortOrder Int      @default(0)
  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  pmTasks       Task[]         @relation("PmTasks")
  taskAssignees TaskAssignee[]
  milestonePmTasks       Milestone[]           @relation("MilestonePm")
  milestoneAssignees     MilestoneAssignee[]

  @@index([cell])
  @@index([isActive])
  @@map("team_members")
}

enum Role {
  ADMIN
  MANAGER
  MEMBER
}

// ─── 업무 ────────────────────────────────────────────────────

model Task {
  id          String     @id @default(cuid())
  title       String
  description String?
  status      TaskStatus @default(TODO)
  priority    Priority   @default(MEDIUM)
  quarter     String     // 예: "2026-Q2"
  category    String?
  section     String?    // HR | 운영관리
  tag         String?    // Growth | Policy | Performance | Culture | Asset | Space | Safety | Environment
  taskType    String?    // 상시업무 | 프로젝트
  progress    Int        @default(0)
  issueNote     String?
  issueEntries  Json?
  startDate   DateTime?
  dueDate     DateTime?
  showDate    Boolean   @default(true)
  showDescription Boolean @default(true)
  showStatus      Boolean @default(true)
  showIssue       Boolean @default(true)
  showProgress    Boolean @default(true)
  creatorId   String
  assigneeId  String?
  pmMemberId  String?
  createdAt   DateTime   @default(now())
  updatedAt   DateTime   @updatedAt

  creator    User         @relation("CreatedTasks", fields: [creatorId], references: [id])
  assignee   User?        @relation("AssignedTasks", fields: [assigneeId], references: [id])
  pmMember   TeamMember?  @relation("PmTasks", fields: [pmMemberId], references: [id])
  taskAssignees TaskAssignee[]
  details     TaskDetail[]
  kpiMetrics  KpiMetric[]
  files       File[]
  milestones  Milestone[]

  @@index([quarter])
  @@index([status])
  @@index([assigneeId])
  @@index([pmMemberId])
  @@index([section])
  @@map("tasks")
}

model TaskAssignee {
  taskId   String
  memberId String

  task   Task       @relation(fields: [taskId], references: [id], onDelete: Cascade)
  member TeamMember @relation(fields: [memberId], references: [id], onDelete: Cascade)

  @@id([taskId, memberId])
  @@index([memberId])
  @@map("task_assignees")
}

enum TaskStatus {
  TODO
  IN_PROGRESS
  REVIEW
  DONE
  CANCELLED
}

enum Priority {
  LOW
  MEDIUM
  HIGH
  URGENT
}

// ─── 업무 상세 / 진행 기록 ────────────────────────────────────

model TaskDetail {
  id          String   @id @default(cuid())
  taskId      String
  milestoneId String?
  content     String
  authorName  String?  // 피드백 작성자 표시명 (자유 입력)
  updatedBy   String
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  task      Task       @relation(fields: [taskId], references: [id], onDelete: Cascade)
  milestone Milestone? @relation(fields: [milestoneId], references: [id], onDelete: Cascade)
  author    User       @relation(fields: [updatedBy], references: [id])

  @@index([taskId])
  @@index([milestoneId])
  @@map("task_details")
}

// ─── KPI 지표 ────────────────────────────────────────────────

model KpiMetric {
  id        String   @id @default(cuid())
  taskId    String
  quarter   String
  target    Float
  actual    Float    @default(0)
  unit      String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)

  @@index([quarter])
  @@map("kpi_metrics")
}

// ─── 파일 ────────────────────────────────────────────────────

model File {
  id           String   @id @default(cuid())
  taskId       String
  milestoneId  String?
  filename     String   // 저장된 파일명 (UUID)
  originalName String   // 원본 파일명
  displayName  String?  // 표시명 (없으면 originalName 사용)
  sortOrder    Int      @default(0)
  mimetype     String
  size         Int
  path         String
  uploadedBy   String
  createdAt    DateTime @default(now())

  task      Task       @relation(fields: [taskId], references: [id], onDelete: Cascade)
  milestone Milestone? @relation(fields: [milestoneId], references: [id], onDelete: SetNull)
  uploader  User       @relation(fields: [uploadedBy], references: [id])

  @@index([taskId])
  @@index([milestoneId])
  @@map("files")
}

// ─── 마일스톤 (프로세스 단계) ─────────────────────────────────

model Milestone {
  id          String    @id @default(cuid())
  taskId      String
  title       String
  subtitle    String?
  description String?
  startDate   DateTime?
  dueDate     DateTime?
  periodEntries Json?
  progress    Int       @default(0)
  links       String?   // JSON: [{ "label": string, "url": string }]
  completedAt DateTime?
  order       Int       @default(0)
  pmMemberId  String?
  createdAt   DateTime  @default(now())
  updatedAt   DateTime  @updatedAt

  task                Task                 @relation(fields: [taskId], references: [id], onDelete: Cascade)
  pmMember            TeamMember?          @relation("MilestonePm", fields: [pmMemberId], references: [id])
  milestoneAssignees  MilestoneAssignee[]
  details             TaskDetail[]
  files               File[]

  @@index([taskId])
  @@index([pmMemberId])
  @@map("milestones")
}

model MilestoneAssignee {
  milestoneId String
  memberId    String

  milestone Milestone  @relation(fields: [milestoneId], references: [id], onDelete: Cascade)
  member    TeamMember @relation(fields: [memberId], references: [id], onDelete: Cascade)

  @@id([milestoneId, memberId])
  @@index([memberId])
  @@map("milestone_assignees")
}

// ─── 컬럼 설정 ───────────────────────────────────────────────

model ColumnConfig {
  key       String   @id         // "HR" | "운영관리"
  title     String
  titleEn   String?
  subtitle  String?
  cardOrder String?              // JSON 배열: task id 순서
  updatedAt DateTime @updatedAt

  @@map("column_configs")
}

// ─── 허브 설정 (분기 중점 과제·일정·상시 라벨) ─────────────────

model HubConfig {
  id        String   @id @default("default")
  config    Json
  updatedAt DateTime @updatedAt

  @@map("hub_configs")
}

// ─── 감사 로그 ───────────────────────────────────────────────

model AuditLog {
  id        String   @id @default(cuid())
  userId    String
  action    String   // CREATE, UPDATE, DELETE, LOGIN 등
  entity    String   // Task, User, File 등
  entityId  String?
  details   Json?
  ipAddress String?
  createdAt DateTime @default(now())

  user User @relation(fields: [userId], references: [id])

  @@index([userId])
  @@index([createdAt])
  @@map("audit_logs")
}
