Sistema completo de gestão de PDI com: - Autenticação com email/senha e Google OAuth - Workspaces privados isolados - Sistema de convites com código único - Interface profissional com Next.js 14 - Backend NestJS com PostgreSQL - Docker com Nginx e SSL Desenvolvido por Sergio Correa
381 lines
9.6 KiB
Plaintext
381 lines
9.6 KiB
Plaintext
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")
|
|
}
|