feat: introduce Teams & OKRs feature with models, types, and UI components for team management and objective tracking
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 12m53s

This commit is contained in:
Julien Froidefond
2026-01-07 10:11:59 +01:00
parent e3a47dd7e5
commit 5f661c8bfd
35 changed files with 3993 additions and 0 deletions

View File

@@ -25,6 +25,9 @@ model User {
yearReviewSessions YearReviewSession[]
sharedYearReviewSessions YRSessionShare[]
yearReviewSessionEvents YRSessionEvent[]
// Teams & OKRs relations
createdTeams Team[]
teamMembers TeamMember[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
@@ -274,3 +277,91 @@ model YRSessionEvent {
@@index([sessionId, createdAt])
}
// ============================================
// Teams & OKRs
// ============================================
enum TeamRole {
ADMIN
MEMBER
}
enum OKRStatus {
NOT_STARTED
IN_PROGRESS
COMPLETED
CANCELLED
}
enum KeyResultStatus {
NOT_STARTED
IN_PROGRESS
COMPLETED
AT_RISK
}
model Team {
id String @id @default(cuid())
name String
description String?
createdById String
creator User @relation(fields: [createdById], references: [id], onDelete: Cascade)
members TeamMember[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([createdById])
}
model TeamMember {
id String @id @default(cuid())
teamId String
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role TeamRole @default(MEMBER)
okrs OKR[]
joinedAt DateTime @default(now())
@@unique([teamId, userId])
@@index([teamId])
@@index([userId])
}
model OKR {
id String @id @default(cuid())
teamMemberId String
teamMember TeamMember @relation(fields: [teamMemberId], references: [id], onDelete: Cascade)
objective String
description String?
period String // Q1 2025, Q2 2025, H1 2025, 2025, etc.
startDate DateTime
endDate DateTime
status OKRStatus @default(NOT_STARTED)
keyResults KeyResult[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([teamMemberId])
@@index([teamMemberId, period])
@@index([status])
}
model KeyResult {
id String @id @default(cuid())
okrId String
okr OKR @relation(fields: [okrId], references: [id], onDelete: Cascade)
title String
targetValue Float
currentValue Float @default(0)
unit String @default("%") // %, nombre, etc.
status KeyResultStatus @default(NOT_STARTED)
order Int @default(0)
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([okrId])
@@index([okrId, order])
}