generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // ═══════════════════════════════════════ // USUÁRIOS E AUTENTICAÇÃO // ═══════════════════════════════════════ enum Role { EMPLOYEE MANAGER HR_ADMIN } model User { id String @id @default(cuid()) email String @unique name String avatar String? role Role @default(EMPLOYEE) googleId String? @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt lastLoginAt DateTime? workspacesAsEmployee Workspace[] @relation("EmployeeWorkspaces") workspacesAsManager Workspace[] @relation("ManagerWorkspaces") workspacesAsHR Workspace[] @relation("HRWorkspaces") journalEntries JournalEntry[] comments Comment[] reactions Reaction[] goals Goal[] assessmentResults AssessmentResult[] oneOnOnesAsEmployee OneOnOne[] @relation("EmployeeOneOnOnes") oneOnOnesAsManager OneOnOne[] @relation("ManagerOneOnOnes") @@index([email]) @@map("users") } // ═══════════════════════════════════════ // WORKSPACES (Salas 1:1) // ═══════════════════════════════════════ enum WorkspaceStatus { ACTIVE ARCHIVED PENDING_INVITE } model Workspace { id String @id @default(cuid()) slug String @unique employeeId String employee User @relation("EmployeeWorkspaces", fields: [employeeId], references: [id]) managerId String manager User @relation("ManagerWorkspaces", fields: [managerId], references: [id]) hrId String? hr User? @relation("HRWorkspaces", fields: [hrId], references: [id]) status WorkspaceStatus @default(ACTIVE) config Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt journalEntries JournalEntry[] goals Goal[] oneOnOnes OneOnOne[] assessmentResults AssessmentResult[] @@unique([employeeId, managerId]) @@index([slug]) @@index([employeeId]) @@index([managerId]) @@map("workspaces") } // ═══════════════════════════════════════ // DIÁRIO DE ATIVIDADES // ═══════════════════════════════════════ enum JournalVisibility { PUBLIC PRIVATE SUMMARY } model JournalEntry { id String @id @default(cuid()) workspaceId String workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) authorId String author User @relation(fields: [authorId], references: [id]) date DateTime @default(now()) whatIDid String @db.Text whatILearned String? @db.Text difficulties String? @db.Text tags String[] attachments Json[] needsFeedback Boolean @default(false) markedFor1on1 Boolean @default(false) visibility JournalVisibility @default(PUBLIC) moodScore Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt comments Comment[] reactions Reaction[] linkedGoals Goal[] @relation("JournalGoalLinks") @@index([workspaceId, date]) @@index([authorId]) @@map("journal_entries") } model Comment { id String @id @default(cuid()) journalEntryId String journalEntry JournalEntry @relation(fields: [journalEntryId], references: [id], onDelete: Cascade) authorId String author User @relation(fields: [authorId], references: [id]) content String @db.Text createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([journalEntryId]) @@map("comments") } model Reaction { id String @id @default(cuid()) journalEntryId String journalEntry JournalEntry @relation(fields: [journalEntryId], references: [id], onDelete: Cascade) userId String user User @relation(fields: [userId], references: [id]) emoji String createdAt DateTime @default(now()) @@unique([journalEntryId, userId, emoji]) @@index([journalEntryId]) @@map("reactions") } // ═══════════════════════════════════════ // PDI - PLANO DE DESENVOLVIMENTO // ═══════════════════════════════════════ enum GoalType { TECHNICAL SOFT_SKILL LEADERSHIP CAREER } enum GoalStatus { NOT_STARTED IN_PROGRESS COMPLETED CANCELLED } model Goal { id String @id @default(cuid()) workspaceId String workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) ownerId String owner User @relation(fields: [ownerId], references: [id]) title String description String @db.Text type GoalType why String? @db.Text status GoalStatus @default(NOT_STARTED) progress Int @default(0) startDate DateTime? targetDate DateTime? completedDate DateTime? successMetrics String? @db.Text createdAt DateTime @default(now()) updatedAt DateTime @updatedAt actions Action[] linkedJournals JournalEntry[] @relation("JournalGoalLinks") @@index([workspaceId]) @@index([ownerId]) @@map("goals") } enum ActionStatus { PENDING IN_PROGRESS DONE BLOCKED } model Action { id String @id @default(cuid()) goalId String goal Goal @relation(fields: [goalId], references: [id], onDelete: Cascade) title String description String? @db.Text status ActionStatus @default(PENDING) dueDate DateTime? completedAt DateTime? assignedTo String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([goalId]) @@map("actions") } // ═══════════════════════════════════════ // TESTES E PERFIS // ═══════════════════════════════════════ enum AssessmentType { PERSONALITY BEHAVIORAL MOTIVATIONAL VOCATIONAL CUSTOM } model Assessment { id String @id @default(cuid()) title String description String @db.Text type AssessmentType questions Json scoringLogic Json isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt results AssessmentResult[] @@map("assessments") } model AssessmentResult { id String @id @default(cuid()) assessmentId String assessment Assessment @relation(fields: [assessmentId], references: [id]) workspaceId String workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) userId String user User @relation(fields: [userId], references: [id]) answers Json result Json primaryType String? scores Json? completedAt DateTime @default(now()) managerNotes String? @db.Text @@index([workspaceId]) @@index([userId]) @@map("assessment_results") } // ═══════════════════════════════════════ // REUNIÕES 1:1 // ═══════════════════════════════════════ enum OneOnOneStatus { SCHEDULED COMPLETED CANCELLED } model OneOnOne { id String @id @default(cuid()) workspaceId String workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade) employeeId String employee User @relation("EmployeeOneOnOnes", fields: [employeeId], references: [id]) managerId String manager User @relation("ManagerOneOnOnes", fields: [managerId], references: [id]) scheduledFor DateTime status OneOnOneStatus @default(SCHEDULED) agenda Json[] notes String? @db.Text decisions Json[] nextSteps Json[] completedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([workspaceId]) @@index([scheduledFor]) @@map("one_on_ones") } // ═══════════════════════════════════════ // CONVITES // ═══════════════════════════════════════ enum InviteStatus { PENDING ACCEPTED EXPIRED CANCELLED } model Invite { id String @id @default(cuid()) email String role Role token String @unique invitedBy String workspaceId String? status InviteStatus @default(PENDING) expiresAt DateTime acceptedAt DateTime? createdAt DateTime @default(now()) @@index([email]) @@index([token]) @@map("invites") }