generator client { provider = "prisma-client" output = "generated/prisma/client/postgres" previewFeatures = ["views"] } datasource db { provider = "postgresql" } model Users { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid first_name String last_name String email String @unique phone_number String residence String? role Roles @default(EMPLOYEE) notifications Notifications? @relation("UserNotification") employee Employees? @relation("UserEmployee") oauth_sessions OAuthSessions[] @relation("UserOAuthSessions") preferences Preferences? @relation("UserPreferences") user_module_access userModuleAccess? @relation("UserModuleAccess") @@map("users") } model Notifications { id Int @id @default(autoincrement()) user_id String @unique @db.Uuid affected_module Modules subject String description String metadata Json @db.JsonB created_at DateTime @default(now()) viewed_at DateTime? user Users @relation("UserNotification", fields: [user_id], references: [id]) @@map("notifications") } model userModuleAccess { id Int @id @default(autoincrement()) user_id String @unique @db.Uuid timesheets Boolean @default(true) timesheets_approval Boolean @default(false) employee_list Boolean @default(true) employee_management Boolean @default(false) personal_profile Boolean @default(true) dashboard Boolean @default(true) chatbot Boolean @default(false) ticket Boolean @default(false) ticket_management Boolean @default(false) user Users @relation("UserModuleAccess", fields: [user_id], references: [id]) @@map("user_module_access") } model Employees { id Int @id @default(autoincrement()) user_id String @unique @db.Uuid external_payroll_id Int company_code Int daily_expected_hours Int @default(24) first_work_day DateTime @db.Date last_work_day DateTime? @db.Date supervisor_id Int? job_title String? is_supervisor Boolean @default(false) applicable_overtime ApplicableOvertime[] @default([WEEKLY]) schedule_preset_id Int? schedule_preset SchedulePresets? @relation("EmployeesSchedulePreset", fields: [schedule_preset_id], references: [id]) supervisor Employees? @relation("EmployeeSupervisor", fields: [supervisor_id], references: [id]) crew Employees[] @relation("EmployeeSupervisor") user Users @relation("UserEmployee", fields: [user_id], references: [id]) leave_request LeaveRequests[] @relation("LeaveRequestEmployee") timesheet Timesheets[] @relation("TimesheetEmployee") paid_time_off PaidTimeOff? @relation("EmployeePaidTimeOff") @@map("employees") } model LeaveRequests { id Int @id @default(autoincrement()) employee_id Int leave_type LeaveTypes comment String approval_status LeaveApprovalStatus @default(PENDING) bank_code_id Int payable_hours Decimal? @db.Decimal(5, 2) requested_hours Decimal? @db.Decimal(5, 2) dates DateTime[] @db.Date bank_code BankCodes @relation("LeaveRequestBankCodes", fields: [bank_code_id], references: [id]) employee Employees @relation("LeaveRequestEmployee", fields: [employee_id], references: [id]) archive LeaveRequestsArchive? @relation("LeaveRequestToArchive") @@unique([employee_id, leave_type, dates], name: "leave_per_employee_date") @@index([employee_id, dates]) @@map("leave_requests") } model LeaveRequestsArchive { id Int @id @default(autoincrement()) leave_request_id Int @unique archived_at DateTime @default(now()) employee_id Int leave_type LeaveTypes comment String approval_status LeaveApprovalStatus date DateTime @db.Date payable_hours Decimal? @db.Decimal(5, 2) requested_hours Decimal? @db.Decimal(5, 2) leave_request LeaveRequests @relation("LeaveRequestToArchive", fields: [leave_request_id], references: [id]) @@index([employee_id, date]) @@map("leave_requests_archive") } model Timesheets { id Int @id @default(autoincrement()) employee_id Int is_approved Boolean @default(false) start_date DateTime @db.Date // hours_to_bank Decimal? @db.Decimal(5, 2) //will need to be implemented in the future expense Expenses[] @relation("ExpensesTimesheet") shift Shifts[] @relation("ShiftTimesheet") employee Employees @relation("TimesheetEmployee", fields: [employee_id], references: [id]) archive TimesheetsArchive[] @relation("TimesheetsToArchive") // @@unique([employee_id, start_date], name: "employee_id_start_date") @@map("timesheets") } model TimesheetsArchive { id Int @id @default(autoincrement()) timesheet_id Int archive_at DateTime @default(now()) employee_id Int is_approved Boolean timesheet Timesheets @relation("TimesheetsToArchive", fields: [timesheet_id], references: [id]) @@map("timesheets_archive") } model SchedulePresets { id Int @id @default(autoincrement()) name String is_default Boolean @default(false) employees Employees[] @relation("EmployeesSchedulePreset") shifts SchedulePresetShifts[] @relation("SchedulePresetShiftsSchedulePreset") @@map("schedule_presets") } model SchedulePresetShifts { id Int @id @default(autoincrement()) preset_id Int bank_code_id Int start_time DateTime @db.Time(0) end_time DateTime @db.Time(0) is_remote Boolean @default(false) week_day Weekday bank_code BankCodes @relation("SchedulePresetShiftsBankCodes", fields: [bank_code_id], references: [id]) preset SchedulePresets @relation("SchedulePresetShiftsSchedulePreset", fields: [preset_id], references: [id]) @@index([preset_id, week_day]) @@map("schedule_preset_shifts") } model Shifts { id Int @id @default(autoincrement()) timesheet_id Int date DateTime @db.Date start_time DateTime @db.Time(0) end_time DateTime @db.Time(0) bank_code_id Int is_approved Boolean @default(false) is_remote Boolean @default(false) comment String? bank_code BankCodes @relation("ShiftBankCodes", fields: [bank_code_id], references: [id]) timesheet Timesheets @relation("ShiftTimesheet", fields: [timesheet_id], references: [id]) archive ShiftsArchive[] @relation("ShiftsToArchive") // @@unique([timesheet_id, date, start_time], name: "unique_ts_id_date_start_time") @@map("shifts") } model ShiftsArchive { id Int @id @default(autoincrement()) shift_id Int archive_at DateTime @default(now()) timesheet_id Int date DateTime @db.Date start_time DateTime @db.Time(0) end_time DateTime @db.Time(0) bank_code_id Int comment String? shift Shifts @relation("ShiftsToArchive", fields: [shift_id], references: [id]) @@map("shifts_archive") } model BankCodes { id Int @id @default(autoincrement()) type String categorie String modifier Float bank_code String expenses Expenses[] @relation("ExpenseBankCodes") leaveRequests LeaveRequests[] @relation("LeaveRequestBankCodes") SchedulePresetShifts SchedulePresetShifts[] @relation("SchedulePresetShiftsBankCodes") shifts Shifts[] @relation("ShiftBankCodes") @@map("bank_codes") } model Expenses { id Int @id @default(autoincrement()) timesheet_id Int date DateTime @db.Date amount Decimal? @db.Decimal(12, 2) is_approved Boolean @default(false) supervisor_comment String? bank_code_id Int comment String attachment_key String? attachment_name String? mileage Decimal? @db.Decimal(12, 2) bank_code BankCodes @relation("ExpenseBankCodes", fields: [bank_code_id], references: [id]) timesheet Timesheets @relation("ExpensesTimesheet", fields: [timesheet_id], references: [id]) archive ExpensesArchive[] @relation("ExpensesToArchive") @@unique([timesheet_id, date, amount, mileage], name: "unique_ts_id_date_amount_mileage") @@map("expenses") } model ExpensesArchive { id Int @id @default(autoincrement()) expense_id Int timesheet_id Int archived_at DateTime @default(now()) date DateTime @db.Date amount Decimal? @db.Decimal(12, 2) is_approved Boolean supervisor_comment String? bank_code_id Int comment String? mileage Decimal? @db.Decimal(12, 2) expense Expenses @relation("ExpensesToArchive", fields: [expense_id], references: [id]) @@map("expenses_archive") } model OAuthSessions { id String @id @default(cuid()) user_id String @db.Uuid application String access_token String @unique refresh_token String @unique access_token_expiry DateTime refresh_token_expiry DateTime? is_revoked Boolean @default(false) scopes Json @default("[]") created_at DateTime @default(now()) updated_at DateTime? sid String @unique user Users @relation("UserOAuthSessions", fields: [user_id], references: [id]) @@map("oauth_sessions") } model Sessions { id String @id sid String @unique data String expiresAt DateTime @@map("sessions") } model Preferences { user_id String @unique @db.Uuid id Int @id @default(autoincrement()) display_language String @default("fr-FR") is_dark_mode Boolean? @default(false) is_employee_list_grid Boolean @default(true) is_lefty_mode Boolean @default(false) is_timesheet_approval_grid Boolean @default(true) notifications Boolean @default(true) user Users @relation("UserPreferences", fields: [user_id], references: [id]) @@map("preferences") } model PaidTimeOff { id Int @id @default(autoincrement()) employee_id Int @unique vacation_hours Decimal @default(0) @db.Decimal(12, 2) banked_hours Decimal @default(0) @db.Decimal(12, 2) sick_hours Decimal @default(0) @db.Decimal(12, 2) last_updated DateTime? @db.Date employee Employees @relation("EmployeePaidTimeOff", fields: [employee_id], references: [id]) @@map("paid_time_off") } view PayPeriods { pay_year Int pay_period_no Int period_start DateTime @db.Date period_end DateTime @db.Date payday DateTime @db.Date label String @@map("pay_period") } enum AttachmentStatus { ACTIVE DELETED } enum RetentionPolicy { EXPENSE_7Y TICKET_2Y PROFILE_KEEP_LAST3 } enum Roles { ADMIN SUPERVISOR HR ACCOUNTING EMPLOYEE DEALER CUSTOMER GUEST @@map("roles") } enum Modules { timesheets timesheets_approval employee_list employee_management personal_profile dashboard ticket ticket_management chatbot @@map("modules") } enum LeaveTypes { SICK VACATION UNPAID BEREAVEMENT PARENTAL LEGAL WEDDING HOLIDAY @@map("leave_types") } enum LeaveApprovalStatus { PENDING APPROVED DENIED CANCELLED ESCALATED @@map("leave_approval_status") } enum Weekday { SUN MON TUE WED THU FRI SAT } enum ApplicableOvertime { DAILY WEEKLY PAYPERIOD }