1636 lines
54 KiB
Plaintext
1636 lines
54 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum RoleKey {
|
|
owner
|
|
leader
|
|
employee
|
|
}
|
|
|
|
enum DepartmentKey {
|
|
marketing
|
|
administracion
|
|
capital_humano
|
|
operaciones
|
|
proyectos
|
|
}
|
|
|
|
enum MarketingMeetingStatus {
|
|
requested
|
|
scheduled
|
|
completed
|
|
cancelled
|
|
}
|
|
|
|
enum MarketingInitiativeType {
|
|
evento
|
|
campania
|
|
cambio
|
|
implementacion
|
|
otro
|
|
}
|
|
|
|
enum MarketingInitiativeStatus {
|
|
planning
|
|
in_progress
|
|
completion
|
|
results
|
|
evaluation
|
|
}
|
|
|
|
enum MarketingTaskStatus {
|
|
todo
|
|
in_progress
|
|
blocked
|
|
done
|
|
}
|
|
|
|
enum MarketingPublicOpinion {
|
|
positive
|
|
mixed
|
|
negative
|
|
}
|
|
|
|
enum MarketingMilestoneStatus {
|
|
pending
|
|
in_progress
|
|
completed
|
|
}
|
|
|
|
enum MeetingResponseStatus {
|
|
pending
|
|
accepted
|
|
declined
|
|
}
|
|
|
|
enum ProjectCalendarVisibility {
|
|
personal
|
|
team
|
|
}
|
|
|
|
enum ProjectCaptureEvidenceKind {
|
|
photo
|
|
document
|
|
link
|
|
}
|
|
|
|
enum CaptureMode {
|
|
manual
|
|
auto
|
|
hybrid
|
|
}
|
|
|
|
enum CaptureAutomationRunStatus {
|
|
queued
|
|
running
|
|
success
|
|
failed
|
|
}
|
|
|
|
enum WeeklyKpiStatus {
|
|
on_track
|
|
watch
|
|
risk
|
|
no_score
|
|
}
|
|
|
|
enum MarketingSyncRunStatus {
|
|
queued
|
|
running
|
|
success
|
|
failed
|
|
}
|
|
|
|
enum EmploymentStatus {
|
|
active
|
|
leave
|
|
terminated
|
|
}
|
|
|
|
enum EmployeeLifecycleEventType {
|
|
hire
|
|
transfer
|
|
leave
|
|
termination
|
|
rehire
|
|
}
|
|
|
|
enum HrUpdateSeverity {
|
|
info
|
|
warning
|
|
critical
|
|
}
|
|
|
|
enum WorkspaceConfigStatus {
|
|
draft
|
|
published
|
|
archived
|
|
}
|
|
|
|
enum HrFileRecordStatus {
|
|
missing
|
|
submitted
|
|
verified
|
|
rejected
|
|
}
|
|
|
|
enum HrVacancyStatus {
|
|
draft
|
|
open
|
|
interviewing
|
|
offered
|
|
hired
|
|
closed
|
|
cancelled
|
|
}
|
|
|
|
enum HrPayrollFrequency {
|
|
weekly
|
|
biweekly
|
|
}
|
|
|
|
enum HrPayrollLineType {
|
|
percepciones
|
|
deducciones
|
|
aportaciones
|
|
}
|
|
|
|
enum HrImportJobStatus {
|
|
queued
|
|
success
|
|
partial
|
|
failed
|
|
}
|
|
|
|
enum HrCareerContentType {
|
|
announcement
|
|
course
|
|
}
|
|
|
|
enum HrCareerAssignmentStatus {
|
|
not_started
|
|
in_progress
|
|
completed
|
|
}
|
|
|
|
enum HrComplianceBody {
|
|
imss
|
|
infonavit
|
|
fonacot
|
|
other
|
|
}
|
|
|
|
enum HrComplianceStatus {
|
|
on_time
|
|
due_soon
|
|
overdue
|
|
paid
|
|
blocked
|
|
}
|
|
|
|
enum HrCompliancePaymentStatus {
|
|
scheduled
|
|
paid
|
|
late
|
|
failed
|
|
}
|
|
|
|
enum HrAutomationTaskStatus {
|
|
queued
|
|
success
|
|
warning
|
|
failed
|
|
}
|
|
|
|
enum FactoryAssetState {
|
|
draft
|
|
active
|
|
down
|
|
retired
|
|
}
|
|
|
|
enum PmTemplateState {
|
|
draft
|
|
active
|
|
archived
|
|
}
|
|
|
|
enum PmWorkOrderState {
|
|
draft
|
|
scheduled
|
|
in_progress
|
|
completed
|
|
verified
|
|
overdue
|
|
cancelled
|
|
}
|
|
|
|
enum ReminderEventState {
|
|
queued
|
|
sent
|
|
acknowledged
|
|
escalated
|
|
failed
|
|
}
|
|
|
|
enum ApprovalState {
|
|
draft
|
|
submitted
|
|
pending_owner
|
|
approved
|
|
rejected
|
|
changes_requested
|
|
cancelled
|
|
}
|
|
|
|
enum SalesForecastState {
|
|
draft
|
|
published
|
|
superseded
|
|
}
|
|
|
|
enum ProductionPlanState {
|
|
draft
|
|
simulated
|
|
locked
|
|
approved
|
|
released
|
|
replanned
|
|
}
|
|
|
|
enum ExperienceTemplateState {
|
|
draft
|
|
published
|
|
archived
|
|
}
|
|
|
|
enum ExperienceFindingPriority {
|
|
low
|
|
medium
|
|
high
|
|
critical
|
|
}
|
|
|
|
enum ExperienceFindingStatus {
|
|
open
|
|
in_progress
|
|
resolved
|
|
closed
|
|
}
|
|
|
|
enum ExperienceScoreAggregationMode {
|
|
weighted_recent
|
|
moving_average
|
|
full_average
|
|
}
|
|
|
|
enum ExperienceTrendDirection {
|
|
up
|
|
down
|
|
flat
|
|
}
|
|
|
|
enum ExperienceSignalStatus {
|
|
green
|
|
yellow
|
|
red
|
|
}
|
|
|
|
enum ExperienceEvidenceKind {
|
|
photo
|
|
document
|
|
link
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
name String?
|
|
email String @unique
|
|
emailVerified DateTime?
|
|
image String?
|
|
passwordHash String?
|
|
status String @default("active")
|
|
department DepartmentKey?
|
|
departmentRole String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
accounts Account[]
|
|
sessions Session[]
|
|
userRoles UserRole[]
|
|
invitations Invitation[] @relation("InvitedByUser")
|
|
marketingMeetingsRequested MarketingMeeting[] @relation("RequestedByUser")
|
|
marketingInitiativesOwned MarketingInitiative[] @relation("MarketingInitiativeOwner")
|
|
marketingInitiativesUpdated MarketingInitiative[] @relation("MarketingInitiativeUpdatedBy")
|
|
marketingInitiativeContributorLinks MarketingInitiativeContributor[]
|
|
marketingInitiativeEvidenceCreated MarketingInitiativeEvidence[] @relation("MarketingInitiativeEvidenceCreatedBy")
|
|
marketingTasksAssigned MarketingTask[] @relation("MarketingTaskAssignee")
|
|
marketingTaskEvidenceCreated MarketingTaskEvidence[] @relation("MarketingTaskEvidenceCreatedBy")
|
|
marketingInitiativeEdits MarketingInitiativeEdit[] @relation("MarketingInitiativeEditBy")
|
|
marketingBrandPulsesUpdated MarketingBrandPulse[] @relation("MarketingBrandPulseUpdatedBy")
|
|
marketingMilestonesCreated MarketingMilestone[] @relation("MarketingMilestoneCreatedBy")
|
|
marketingMilestoneCheckpointsCreated MarketingMilestoneCheckpoint[] @relation("MarketingMilestoneCheckpointCreatedBy")
|
|
projectMeetingParticipants MarketingMeetingParticipant[] @relation("MarketingMeetingParticipantUser")
|
|
projectCalendarEventsOwned ProjectCalendarEvent[] @relation("ProjectCalendarEventOwner")
|
|
projectCaptureEvidenceUploaded ProjectCaptureEvidence[] @relation("ProjectCaptureEvidenceUploadedBy")
|
|
kpiCaptureCatalogOwned KpiCaptureCatalog[] @relation("KpiCaptureCatalogOwner")
|
|
kpiCaptureCatalogLastCaptured KpiCaptureCatalog[] @relation("KpiCaptureCatalogLastCapturedBy")
|
|
kpiCaptureEvidenceUploaded KpiCaptureEvidence[] @relation("KpiCaptureEvidenceUploadedBy")
|
|
kpiCaptureAutomationRunsTriggered KpiCaptureAutomationRun[] @relation("KpiCaptureAutomationRunTriggeredBy")
|
|
employeeProfile EmployeeProfile?
|
|
employeeLifecycleTarget EmployeeLifecycleEvent[] @relation("EmployeeLifecycleTarget")
|
|
employeeLifecycleCreated EmployeeLifecycleEvent[] @relation("EmployeeLifecycleCreatedBy")
|
|
hrUpdatesAuthored HrUpdate[] @relation("HrUpdateAuthor")
|
|
managedLocations Location[] @relation("LocationManager")
|
|
experienceTemplatesCreated ExperienceTemplate[] @relation("ExperienceTemplateCreatedBy")
|
|
experienceEvaluationsCreated ExperienceEvaluation[] @relation("ExperienceEvaluationCreatedBy")
|
|
experienceFindingsCreated ExperienceFinding[] @relation("ExperienceFindingCreatedBy")
|
|
experienceFindingsAssigned ExperienceFinding[] @relation("ExperienceFindingAssignedTo")
|
|
experienceEvidenceUploaded ExperienceEvidence[] @relation("ExperienceEvidenceUploadedBy")
|
|
experienceScoringPoliciesCreated ExperienceScoringPolicy[] @relation("ExperienceScoringPolicyCreatedBy")
|
|
}
|
|
|
|
model Role {
|
|
id String @id @default(cuid())
|
|
key RoleKey @unique
|
|
name String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
userRoles UserRole[]
|
|
}
|
|
|
|
model UserRole {
|
|
userId String
|
|
roleId String
|
|
assignedAt DateTime @default(now())
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([userId, roleId])
|
|
}
|
|
|
|
model Invitation {
|
|
id String @id @default(cuid())
|
|
inviteeName String
|
|
email String
|
|
roleKey RoleKey
|
|
department DepartmentKey
|
|
departmentRole String
|
|
tokenHash String @unique
|
|
expiresAt DateTime
|
|
acceptedAt DateTime?
|
|
invitedById String?
|
|
createdAt DateTime @default(now())
|
|
invitedBy User? @relation("InvitedByUser", fields: [invitedById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([email, expiresAt])
|
|
}
|
|
|
|
model PasswordResetToken {
|
|
id String @id @default(cuid())
|
|
email String
|
|
tokenHash String @unique
|
|
expiresAt DateTime
|
|
usedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([email, expiresAt])
|
|
}
|
|
|
|
model MarketingMeeting {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
title String
|
|
agenda String
|
|
status MarketingMeetingStatus @default(requested)
|
|
requestedById String?
|
|
requestedByName String
|
|
participantNames Json
|
|
suggestedTimes Json
|
|
scheduledFor DateTime?
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
requestedBy User? @relation("RequestedByUser", fields: [requestedById], references: [id], onDelete: SetNull)
|
|
commitments MarketingCommitment[]
|
|
participants MarketingMeetingParticipant[]
|
|
calendarEvent ProjectCalendarEvent? @relation("ProjectMeetingCalendarEvent")
|
|
|
|
@@index([department, status, scheduledFor])
|
|
}
|
|
|
|
model MarketingCommitment {
|
|
id String @id @default(cuid())
|
|
meetingId String
|
|
title String
|
|
description String?
|
|
ownerName String?
|
|
dueDate DateTime?
|
|
status String @default("pendiente")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
meeting MarketingMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([meetingId, dueDate])
|
|
}
|
|
|
|
model MarketingInitiative {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
name String
|
|
type MarketingInitiativeType
|
|
status MarketingInitiativeStatus @default(planning)
|
|
isGlobal Boolean @default(false)
|
|
ownerId String?
|
|
dueDate DateTime
|
|
completedAt DateTime?
|
|
importanceWeight Float @default(1)
|
|
leadRating1to5 Int @default(3)
|
|
trackScore Boolean @default(true)
|
|
trackTickets Boolean @default(true)
|
|
trackRevenue Boolean @default(true)
|
|
target Float @default(0)
|
|
actual Float @default(0)
|
|
ticketsTarget Int @default(0)
|
|
ticketsActual Int @default(0)
|
|
revenueTarget Float @default(0)
|
|
revenueActual Float @default(0)
|
|
plannedCost Float @default(0)
|
|
actualCost Float @default(0)
|
|
targetTicketPrice Float @default(0)
|
|
actualTicketPrice Float @default(0)
|
|
attributionChannel String?
|
|
attributionPageId String?
|
|
attributionCampaign String?
|
|
attributionStart DateTime?
|
|
attributionEnd DateTime?
|
|
autoActual Float?
|
|
autoTicketsActual Int?
|
|
autoRevenueActual Float?
|
|
autoUpdatedAt DateTime?
|
|
projectsSchemaVersion Int @default(1)
|
|
opinionPublica MarketingPublicOpinion @default(mixed)
|
|
queFunciono String @default("")
|
|
queNo String @default("")
|
|
proximoIntento String @default("")
|
|
updatedById String?
|
|
updatedByName String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
owner User? @relation("MarketingInitiativeOwner", fields: [ownerId], references: [id], onDelete: SetNull)
|
|
updatedBy User? @relation("MarketingInitiativeUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
|
|
contributors MarketingInitiativeContributor[]
|
|
locations MarketingInitiativeLocation[]
|
|
evidenceLinks MarketingInitiativeEvidence[]
|
|
tasks MarketingTask[]
|
|
edits MarketingInitiativeEdit[]
|
|
milestones MarketingMilestone[]
|
|
captureEvidence ProjectCaptureEvidence[]
|
|
kpiCaptureEvidence KpiCaptureEvidence[]
|
|
|
|
@@index([department, status, dueDate])
|
|
}
|
|
|
|
model MarketingInitiativeContributor {
|
|
initiativeId String
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([initiativeId, userId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model MarketingInitiativeLocation {
|
|
id String @id @default(cuid())
|
|
initiativeId String
|
|
locationId String
|
|
createdAt DateTime @default(now())
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([initiativeId, locationId])
|
|
@@index([locationId])
|
|
}
|
|
|
|
model MarketingInitiativeEvidence {
|
|
id String @id @default(cuid())
|
|
initiativeId String
|
|
url String
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
createdBy User? @relation("MarketingInitiativeEvidenceCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([initiativeId, createdAt])
|
|
}
|
|
|
|
model MarketingTask {
|
|
id String @id @default(cuid())
|
|
initiativeId String
|
|
title String
|
|
description String @default("")
|
|
assigneeId String?
|
|
status MarketingTaskStatus @default(todo)
|
|
dueDate DateTime
|
|
updatedAt DateTime @updatedAt
|
|
createdAt DateTime @default(now())
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
assignee User? @relation("MarketingTaskAssignee", fields: [assigneeId], references: [id], onDelete: SetNull)
|
|
evidenceLinks MarketingTaskEvidence[]
|
|
captureEvidence ProjectCaptureEvidence[]
|
|
kpiCaptureEvidence KpiCaptureEvidence[]
|
|
|
|
@@index([initiativeId, status, dueDate])
|
|
@@index([assigneeId])
|
|
}
|
|
|
|
model MarketingTaskEvidence {
|
|
id String @id @default(cuid())
|
|
taskId String
|
|
url String
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
task MarketingTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
createdBy User? @relation("MarketingTaskEvidenceCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([taskId, createdAt])
|
|
}
|
|
|
|
model MarketingInitiativeEdit {
|
|
id String @id @default(cuid())
|
|
initiativeId String
|
|
editedById String?
|
|
editedByName String
|
|
summary String
|
|
createdAt DateTime @default(now())
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
editedBy User? @relation("MarketingInitiativeEditBy", fields: [editedById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([initiativeId, createdAt])
|
|
}
|
|
|
|
model MarketingMilestone {
|
|
id String @id @default(cuid())
|
|
initiativeId String
|
|
title String
|
|
description String @default("")
|
|
dueDate DateTime
|
|
status MarketingMilestoneStatus @default(pending)
|
|
sortOrder Int @default(0)
|
|
createdById String?
|
|
createdByName String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
initiative MarketingInitiative @relation(fields: [initiativeId], references: [id], onDelete: Cascade)
|
|
createdBy User? @relation("MarketingMilestoneCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
checkpoints MarketingMilestoneCheckpoint[]
|
|
|
|
@@index([initiativeId, dueDate, status])
|
|
}
|
|
|
|
model MarketingMilestoneCheckpoint {
|
|
id String @id @default(cuid())
|
|
milestoneId String
|
|
note String
|
|
createdById String?
|
|
createdByName String?
|
|
createdAt DateTime @default(now())
|
|
milestone MarketingMilestone @relation(fields: [milestoneId], references: [id], onDelete: Cascade)
|
|
createdBy User? @relation("MarketingMilestoneCheckpointCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([milestoneId, createdAt])
|
|
}
|
|
|
|
model MarketingMeetingParticipant {
|
|
id String @id @default(cuid())
|
|
meetingId String
|
|
userId String?
|
|
displayName String
|
|
responseStatus MeetingResponseStatus @default(pending)
|
|
respondedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
meeting MarketingMeeting @relation(fields: [meetingId], references: [id], onDelete: Cascade)
|
|
user User? @relation("MarketingMeetingParticipantUser", fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
@@unique([meetingId, userId])
|
|
@@index([meetingId, responseStatus])
|
|
@@index([userId])
|
|
}
|
|
|
|
model ProjectCalendarEvent {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(proyectos)
|
|
ownerUserId String
|
|
meetingId String? @unique
|
|
title String
|
|
notes String?
|
|
startAt DateTime
|
|
endAt DateTime
|
|
visibility ProjectCalendarVisibility @default(personal)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
ownerUser User @relation("ProjectCalendarEventOwner", fields: [ownerUserId], references: [id], onDelete: Cascade)
|
|
meeting MarketingMeeting? @relation("ProjectMeetingCalendarEvent", fields: [meetingId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, startAt, endAt])
|
|
@@index([ownerUserId, startAt])
|
|
}
|
|
|
|
model ProjectCaptureEvidence {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(proyectos)
|
|
initiativeId String?
|
|
taskId String?
|
|
uploadedById String
|
|
kind ProjectCaptureEvidenceKind
|
|
title String
|
|
note String?
|
|
url String?
|
|
storagePath String?
|
|
mimeType String?
|
|
sizeBytes Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
initiative MarketingInitiative? @relation(fields: [initiativeId], references: [id], onDelete: SetNull)
|
|
task MarketingTask? @relation(fields: [taskId], references: [id], onDelete: SetNull)
|
|
uploadedBy User @relation("ProjectCaptureEvidenceUploadedBy", fields: [uploadedById], references: [id], onDelete: Restrict)
|
|
|
|
@@index([department, createdAt])
|
|
@@index([initiativeId, createdAt])
|
|
@@index([taskId, createdAt])
|
|
@@index([uploadedById, createdAt])
|
|
}
|
|
|
|
model KpiCaptureCatalog {
|
|
id String @id @default(cuid())
|
|
weekStart DateTime
|
|
sectionKey String
|
|
rowKey String
|
|
weeklyKpiRowId String? @unique
|
|
department DepartmentKey
|
|
captureMode CaptureMode @default(manual)
|
|
automationSource String?
|
|
ownerUserId String?
|
|
freshnessSlaHours Int @default(168)
|
|
captureNote String?
|
|
lastCapturedAt DateTime?
|
|
lastCapturedById String?
|
|
lastAutomationAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
weeklyKpiRow WeeklyKpiRow? @relation(fields: [weeklyKpiRowId], references: [id], onDelete: SetNull)
|
|
ownerUser User? @relation("KpiCaptureCatalogOwner", fields: [ownerUserId], references: [id], onDelete: SetNull)
|
|
lastCapturedBy User? @relation("KpiCaptureCatalogLastCapturedBy", fields: [lastCapturedById], references: [id], onDelete: SetNull)
|
|
evidence KpiCaptureEvidence[]
|
|
|
|
@@unique([weekStart, sectionKey, rowKey])
|
|
@@index([department, weekStart])
|
|
@@index([ownerUserId, weekStart])
|
|
}
|
|
|
|
model KpiCaptureEvidence {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
weekStart DateTime
|
|
sectionKey String
|
|
rowKey String
|
|
catalogId String?
|
|
weeklyKpiRowId String?
|
|
initiativeId String?
|
|
taskId String?
|
|
uploadedById String
|
|
kind ProjectCaptureEvidenceKind
|
|
title String
|
|
note String?
|
|
url String?
|
|
storagePath String?
|
|
mimeType String?
|
|
sizeBytes Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
catalog KpiCaptureCatalog? @relation(fields: [catalogId], references: [id], onDelete: SetNull)
|
|
weeklyKpiRow WeeklyKpiRow? @relation(fields: [weeklyKpiRowId], references: [id], onDelete: SetNull)
|
|
initiative MarketingInitiative? @relation(fields: [initiativeId], references: [id], onDelete: SetNull)
|
|
task MarketingTask? @relation(fields: [taskId], references: [id], onDelete: SetNull)
|
|
uploadedBy User @relation("KpiCaptureEvidenceUploadedBy", fields: [uploadedById], references: [id], onDelete: Restrict)
|
|
|
|
@@index([department, weekStart, createdAt])
|
|
@@index([sectionKey, rowKey, weekStart])
|
|
@@index([catalogId, createdAt])
|
|
@@index([initiativeId, createdAt])
|
|
@@index([taskId, createdAt])
|
|
@@index([uploadedById, createdAt])
|
|
}
|
|
|
|
model KpiCaptureAutomationRun {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
weekStart DateTime
|
|
source String
|
|
status CaptureAutomationRunStatus @default(queued)
|
|
rowsTouched Int @default(0)
|
|
errorMessage String?
|
|
triggeredById String?
|
|
startedAt DateTime @default(now())
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
triggeredBy User? @relation("KpiCaptureAutomationRunTriggeredBy", fields: [triggeredById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, weekStart, createdAt])
|
|
@@index([status, createdAt])
|
|
}
|
|
|
|
model MarketingSocialSnapshot {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
channel String
|
|
range String
|
|
followersStart Int
|
|
followersEnd Int
|
|
engagementRate Float
|
|
reach Int
|
|
impressions Int
|
|
capturedAt DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([department, range, channel, capturedAt])
|
|
}
|
|
|
|
model MarketingBrandPulse {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey
|
|
month String
|
|
rating1to5 Int
|
|
notes String @default("")
|
|
updatedById String?
|
|
updatedByName String?
|
|
updatedAt DateTime @updatedAt
|
|
createdAt DateTime @default(now())
|
|
updatedBy User? @relation("MarketingBrandPulseUpdatedBy", fields: [updatedById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, month])
|
|
}
|
|
|
|
model MarketingMetaConnection {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(marketing)
|
|
accountId String
|
|
pageId String
|
|
pageName String
|
|
pageAccessToken String
|
|
tokenExpiresAt DateTime?
|
|
connectedById String?
|
|
isActive Boolean @default(true)
|
|
lastSyncedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
metrics MarketingSocialMetricDaily[]
|
|
syncRuns MarketingSyncRun[]
|
|
|
|
@@unique([department, pageId, isActive])
|
|
@@index([department, isActive])
|
|
}
|
|
|
|
model MarketingSocialMetricDaily {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(marketing)
|
|
connectionId String
|
|
channel String
|
|
metricDate DateTime
|
|
followers Int
|
|
reach Int
|
|
impressions Int
|
|
engagements Int
|
|
engagementRate Float
|
|
createdAt DateTime @default(now())
|
|
connection MarketingMetaConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([connectionId, channel, metricDate])
|
|
@@index([department, channel, metricDate])
|
|
}
|
|
|
|
model MarketingSyncRun {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(marketing)
|
|
connectionId String?
|
|
status MarketingSyncRunStatus @default(queued)
|
|
message String?
|
|
rowsIngested Int @default(0)
|
|
triggeredById String?
|
|
startedAt DateTime @default(now())
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
connection MarketingMetaConnection? @relation(fields: [connectionId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, createdAt])
|
|
@@index([status, createdAt])
|
|
}
|
|
|
|
model EmployeeProfile {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
employeeCode String?
|
|
hireDate DateTime?
|
|
employmentType String?
|
|
managerUserId String?
|
|
locationId String?
|
|
fte Float @default(1)
|
|
employmentStatus EmploymentStatus @default(active)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([employmentStatus, hireDate])
|
|
}
|
|
|
|
model EmployeeLifecycleEvent {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
eventType EmployeeLifecycleEventType
|
|
effectiveAt DateTime
|
|
reason String?
|
|
isVoluntary Boolean?
|
|
metadata Json?
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
user User @relation("EmployeeLifecycleTarget", fields: [userId], references: [id], onDelete: Cascade)
|
|
createdBy User? @relation("EmployeeLifecycleCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([userId, effectiveAt])
|
|
@@index([eventType, effectiveAt])
|
|
}
|
|
|
|
model HrMetricSnapshot {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey?
|
|
snapshotDate DateTime
|
|
headcount Int
|
|
hires Int
|
|
exits Int
|
|
churnPct Float
|
|
medianTenureMonths Float
|
|
peopleHealthScore Float
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([snapshotDate, department])
|
|
}
|
|
|
|
model HrUpdate {
|
|
id String @id @default(cuid())
|
|
title String
|
|
body String
|
|
severity HrUpdateSeverity @default(info)
|
|
audience String @default("hc_leadership")
|
|
status String @default("draft")
|
|
publishedAt DateTime?
|
|
authorId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
author User? @relation("HrUpdateAuthor", fields: [authorId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([status, publishedAt])
|
|
}
|
|
|
|
model HrWorkspaceConfigVersion {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
version Int
|
|
status WorkspaceConfigStatus @default(draft)
|
|
name String @default("Capital Humano Workspace")
|
|
tabs Json
|
|
changeSummary String?
|
|
createdById String?
|
|
publishedById String?
|
|
publishedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([department, version])
|
|
@@index([department, status, version])
|
|
}
|
|
|
|
model HrFileRequirement {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
key String
|
|
label String
|
|
description String?
|
|
fieldType String @default("document")
|
|
isRequired Boolean @default(true)
|
|
isActive Boolean @default(true)
|
|
sortOrder Int @default(0)
|
|
createdById String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
records HrEmployeeFileRecord[]
|
|
|
|
@@unique([department, key])
|
|
@@index([department, isActive, sortOrder])
|
|
}
|
|
|
|
model HrEmployeeFileRecord {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
requirementId String
|
|
status HrFileRecordStatus @default(missing)
|
|
valueText String?
|
|
evidenceUrl String?
|
|
note String?
|
|
verifiedAt DateTime?
|
|
verifiedById String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
requirement HrFileRequirement @relation(fields: [requirementId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, requirementId])
|
|
@@index([userId, status])
|
|
@@index([requirementId, status])
|
|
}
|
|
|
|
model HrIdealOrgTarget {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
locationCode String
|
|
roleKey String
|
|
targetCount Int
|
|
isActive Boolean @default(true)
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([department, locationCode, roleKey])
|
|
@@index([department, locationCode, roleKey])
|
|
}
|
|
|
|
model HrVacancy {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
locationCode String
|
|
roleKey String
|
|
title String
|
|
status HrVacancyStatus @default(open)
|
|
priority String @default("medium")
|
|
openedAt DateTime @default(now())
|
|
targetStartAt DateTime?
|
|
closedAt DateTime?
|
|
hiringManagerUserId String?
|
|
ownerUserId String?
|
|
notes String?
|
|
createdById String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([department, status, openedAt])
|
|
@@index([department, locationCode, roleKey])
|
|
}
|
|
|
|
model HrPayrollRun {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
source String @default("contpaqi_csv")
|
|
externalRef String?
|
|
periodStart DateTime
|
|
periodEnd DateTime
|
|
frequency HrPayrollFrequency
|
|
locationCode String?
|
|
status String @default("imported")
|
|
rawHash String?
|
|
importedById String?
|
|
importedAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
lines HrPayrollLine[]
|
|
importJobs HrPayrollImportJob[]
|
|
|
|
@@index([department, periodStart, periodEnd])
|
|
@@index([department, frequency, locationCode])
|
|
@@index([rawHash])
|
|
}
|
|
|
|
model HrPayrollLine {
|
|
id String @id @default(cuid())
|
|
runId String
|
|
userId String?
|
|
personIdentifier String
|
|
lineType HrPayrollLineType
|
|
concept String
|
|
amount Float
|
|
currency String @default("MXN")
|
|
locationCode String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
run HrPayrollRun @relation(fields: [runId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([runId, lineType])
|
|
@@index([userId])
|
|
@@index([locationCode, lineType])
|
|
}
|
|
|
|
model HrPayrollImportJob {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
status HrImportJobStatus @default(queued)
|
|
sourceFileName String?
|
|
requestHash String?
|
|
message String?
|
|
rowsRead Int @default(0)
|
|
rowsImported Int @default(0)
|
|
failedRows Int @default(0)
|
|
runId String?
|
|
triggeredById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
completedAt DateTime?
|
|
run HrPayrollRun? @relation(fields: [runId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, status, createdAt])
|
|
@@index([requestHash])
|
|
}
|
|
|
|
model HrCareerContent {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
contentType HrCareerContentType
|
|
title String
|
|
body String
|
|
sourceDepartment DepartmentKey?
|
|
sourceRef String?
|
|
startsAt DateTime?
|
|
endsAt DateTime?
|
|
isActive Boolean @default(true)
|
|
createdById String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
assignments HrCareerAssignment[]
|
|
|
|
@@index([department, contentType, isActive])
|
|
@@index([sourceDepartment, createdAt])
|
|
}
|
|
|
|
model HrCareerAssignment {
|
|
id String @id @default(cuid())
|
|
contentId String
|
|
userId String
|
|
status HrCareerAssignmentStatus @default(not_started)
|
|
progressPct Float @default(0)
|
|
assignedAt DateTime @default(now())
|
|
dueAt DateTime?
|
|
completedAt DateTime?
|
|
notes String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
content HrCareerContent @relation(fields: [contentId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([contentId, userId])
|
|
@@index([userId, status])
|
|
}
|
|
|
|
model HrComplianceObligation {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
body HrComplianceBody
|
|
title String
|
|
status HrComplianceStatus @default(due_soon)
|
|
locationCode String?
|
|
referencePeriod String?
|
|
dueDate DateTime?
|
|
lastPaymentAt DateTime?
|
|
lastPaymentAmount Float?
|
|
notes String?
|
|
createdById String?
|
|
updatedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
payments HrCompliancePayment[]
|
|
|
|
@@index([department, body, status, dueDate])
|
|
@@index([department, locationCode, body])
|
|
}
|
|
|
|
model HrCompliancePayment {
|
|
id String @id @default(cuid())
|
|
obligationId String
|
|
paymentDate DateTime
|
|
amount Float
|
|
status HrCompliancePaymentStatus @default(paid)
|
|
referencePeriod String?
|
|
receiptUrl String?
|
|
note String?
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
obligation HrComplianceObligation @relation(fields: [obligationId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([obligationId, paymentDate])
|
|
}
|
|
|
|
model HrAutomationTask {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
taskType String
|
|
status HrAutomationTaskStatus @default(queued)
|
|
title String
|
|
message String?
|
|
payload Json?
|
|
runAt DateTime
|
|
resolvedAt DateTime?
|
|
assignedToId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([department, status, runAt])
|
|
}
|
|
|
|
model HrExceptionQueueItem {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(capital_humano)
|
|
source String
|
|
errorCode String?
|
|
message String
|
|
payload Json?
|
|
status String @default("open")
|
|
retryCount Int @default(0)
|
|
lastRetriedAt DateTime?
|
|
resolvedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([department, status, createdAt])
|
|
@@index([source, status])
|
|
}
|
|
|
|
model FactoryAsset {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(operaciones)
|
|
assetCode String @unique
|
|
name String
|
|
category String
|
|
locationId String?
|
|
criticality Int @default(3)
|
|
state FactoryAssetState @default(active)
|
|
serviceStrategy String?
|
|
lastMaintenanceAt DateTime?
|
|
nextMaintenanceAt DateTime?
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
templates PmTemplate[]
|
|
workOrders PmWorkOrder[]
|
|
|
|
@@index([department, state])
|
|
@@index([nextMaintenanceAt, state])
|
|
}
|
|
|
|
model PmTemplate {
|
|
id String @id @default(cuid())
|
|
assetId String
|
|
title String
|
|
description String?
|
|
cadenceDays Int?
|
|
cadenceHours Int?
|
|
state PmTemplateState @default(active)
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
asset FactoryAsset @relation(fields: [assetId], references: [id], onDelete: Cascade)
|
|
workOrders PmWorkOrder[]
|
|
|
|
@@index([assetId, state])
|
|
}
|
|
|
|
model PmWorkOrder {
|
|
id String @id @default(cuid())
|
|
assetId String
|
|
templateId String?
|
|
title String
|
|
description String?
|
|
scheduledFor DateTime
|
|
dueBy DateTime
|
|
startedAt DateTime?
|
|
completedAt DateTime?
|
|
estimatedCost Float @default(0)
|
|
expectedDowntimeHours Float @default(0)
|
|
actualCost Float?
|
|
actualDowntimeHours Float?
|
|
state PmWorkOrderState @default(scheduled)
|
|
requestedById String?
|
|
approvedById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
asset FactoryAsset @relation(fields: [assetId], references: [id], onDelete: Cascade)
|
|
template PmTemplate? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
|
reminders ReminderEvent[]
|
|
approvalRequests ApprovalRequest[]
|
|
|
|
@@index([assetId, state, dueBy])
|
|
@@index([state, scheduledFor])
|
|
}
|
|
|
|
model ReminderEvent {
|
|
id String @id @default(cuid())
|
|
workOrderId String
|
|
remindAt DateTime
|
|
channel String @default("in_app")
|
|
message String?
|
|
state ReminderEventState @default(queued)
|
|
acknowledgedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
workOrder PmWorkOrder @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([workOrderId, state])
|
|
@@index([remindAt, state])
|
|
}
|
|
|
|
model MaintenanceApprovalPolicy {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(operaciones)
|
|
costThreshold Float @default(5000)
|
|
downtimeThresholdHours Float @default(4)
|
|
ownerUserId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([department])
|
|
}
|
|
|
|
model SalesForecast {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(operaciones)
|
|
weekStart DateTime
|
|
weekEnd DateTime
|
|
locationId String?
|
|
sku String?
|
|
forecastUnits Float
|
|
multiplier Float @default(1.2)
|
|
state SalesForecastState @default(draft)
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([department, weekStart, state])
|
|
}
|
|
|
|
model ProductionPlan {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(operaciones)
|
|
weekStart DateTime
|
|
weekEnd DateTime
|
|
lineName String
|
|
plannedUnits Float
|
|
forecastUnits Float
|
|
capacityUnits Float
|
|
varianceUnits Float
|
|
state ProductionPlanState @default(draft)
|
|
createdById String?
|
|
approvedById String?
|
|
approvedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
approvalRequests ApprovalRequest[]
|
|
|
|
@@index([department, weekStart, state])
|
|
}
|
|
|
|
model ApprovalRequest {
|
|
id String @id @default(cuid())
|
|
department DepartmentKey @default(operaciones)
|
|
requestType String
|
|
workOrderId String?
|
|
productionPlanId String?
|
|
submittedById String?
|
|
approverId String?
|
|
state ApprovalState @default(submitted)
|
|
reason String?
|
|
decidedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
workOrder PmWorkOrder? @relation(fields: [workOrderId], references: [id], onDelete: SetNull)
|
|
productionPlan ProductionPlan? @relation(fields: [productionPlanId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([department, state, createdAt])
|
|
}
|
|
|
|
model WeeklyKpiSnapshot {
|
|
id String @id @default(cuid())
|
|
weekStart DateTime @unique
|
|
weekEnd DateTime
|
|
source String @default("platform")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
sections WeeklyKpiSection[]
|
|
|
|
@@index([weekStart, weekEnd])
|
|
}
|
|
|
|
model WeeklyKpiSection {
|
|
id String @id @default(cuid())
|
|
snapshotId String
|
|
sectionKey String
|
|
rawSectionLabel String
|
|
mappedDepartment DepartmentKey?
|
|
ownerTeamLabel String?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
snapshot WeeklyKpiSnapshot @relation(fields: [snapshotId], references: [id], onDelete: Cascade)
|
|
rows WeeklyKpiRow[]
|
|
|
|
@@unique([snapshotId, sectionKey])
|
|
@@index([snapshotId, mappedDepartment, sortOrder])
|
|
}
|
|
|
|
model WeeklyKpiRow {
|
|
id String @id @default(cuid())
|
|
sectionId String
|
|
rowKey String
|
|
responsibilityText String
|
|
objectiveIndicatorText String?
|
|
quantityQualityText String?
|
|
complianceText String?
|
|
dueCommitmentText String?
|
|
targetValue Float?
|
|
quantityValue Float?
|
|
compliancePct Float?
|
|
dueDate DateTime?
|
|
lastCapturedAt DateTime?
|
|
lastCapturedById String?
|
|
lastAutomationAt DateTime?
|
|
captureNote String?
|
|
status WeeklyKpiStatus @default(no_score)
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
section WeeklyKpiSection @relation(fields: [sectionId], references: [id], onDelete: Cascade)
|
|
captureCatalog KpiCaptureCatalog?
|
|
captureEvidence KpiCaptureEvidence[]
|
|
|
|
@@unique([sectionId, rowKey])
|
|
@@index([sectionId, sortOrder])
|
|
@@index([status, dueDate])
|
|
}
|
|
|
|
model Location {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
name String
|
|
city String?
|
|
managerUserId String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
managerUser User? @relation("LocationManager", fields: [managerUserId], references: [id], onDelete: SetNull)
|
|
evaluations ExperienceEvaluation[]
|
|
findings ExperienceFinding[]
|
|
evidence ExperienceEvidence[]
|
|
metrics ExperienceLocationMetric?
|
|
|
|
@@index([isActive, name])
|
|
}
|
|
|
|
model ExperienceTemplate {
|
|
id String @id @default(cuid())
|
|
name String
|
|
version Int
|
|
state ExperienceTemplateState @default(draft)
|
|
isDefault Boolean @default(false)
|
|
createdById String?
|
|
publishedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
createdBy User? @relation("ExperienceTemplateCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
categories ExperienceTemplateCategory[]
|
|
evaluations ExperienceEvaluation[]
|
|
|
|
@@unique([name, version])
|
|
@@index([state, updatedAt])
|
|
}
|
|
|
|
model ExperienceTemplateCategory {
|
|
id String @id @default(cuid())
|
|
templateId String
|
|
key String
|
|
name String
|
|
weight Float @default(1)
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
template ExperienceTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
|
items ExperienceTemplateItem[]
|
|
responses ExperienceEvaluationResponse[]
|
|
|
|
@@unique([templateId, key])
|
|
@@index([templateId, sortOrder])
|
|
}
|
|
|
|
model ExperienceTemplateItem {
|
|
id String @id @default(cuid())
|
|
categoryId String
|
|
key String
|
|
label String
|
|
weight Float @default(1)
|
|
sortOrder Int @default(0)
|
|
allowsComment Boolean @default(true)
|
|
requiresObservation Boolean @default(false)
|
|
allowsEvidence Boolean @default(true)
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
category ExperienceTemplateCategory @relation(fields: [categoryId], references: [id], onDelete: Cascade)
|
|
responses ExperienceEvaluationResponse[]
|
|
|
|
@@unique([categoryId, key])
|
|
@@index([categoryId, sortOrder])
|
|
}
|
|
|
|
model ExperienceEvaluation {
|
|
id String @id @default(cuid())
|
|
locationId String
|
|
templateId String
|
|
createdById String?
|
|
evaluatedAt DateTime @default(now())
|
|
generalObservations String @default("")
|
|
strengths String @default("")
|
|
improvementAreas String @default("")
|
|
totalScore Float
|
|
signal ExperienceSignalStatus
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Restrict)
|
|
template ExperienceTemplate @relation(fields: [templateId], references: [id], onDelete: Restrict)
|
|
createdBy User? @relation("ExperienceEvaluationCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
responses ExperienceEvaluationResponse[]
|
|
findings ExperienceFinding[]
|
|
evidence ExperienceEvidence[]
|
|
metricAsLatest ExperienceLocationMetric[] @relation("ExperienceLocationMetricLastEvaluation")
|
|
|
|
@@index([locationId, evaluatedAt])
|
|
@@index([templateId, evaluatedAt])
|
|
}
|
|
|
|
model ExperienceEvaluationResponse {
|
|
id String @id @default(cuid())
|
|
evaluationId String
|
|
categoryId String
|
|
itemId String
|
|
score Int
|
|
scorePct Float
|
|
comment String?
|
|
observation String?
|
|
hasObservation Boolean @default(false)
|
|
categoryLabelSnapshot String
|
|
itemLabelSnapshot String
|
|
categoryWeightSnapshot Float
|
|
itemWeightSnapshot Float
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
evaluation ExperienceEvaluation @relation(fields: [evaluationId], references: [id], onDelete: Cascade)
|
|
category ExperienceTemplateCategory @relation(fields: [categoryId], references: [id], onDelete: Restrict)
|
|
item ExperienceTemplateItem @relation(fields: [itemId], references: [id], onDelete: Restrict)
|
|
evidence ExperienceEvidence[]
|
|
|
|
@@unique([evaluationId, itemId])
|
|
@@index([evaluationId, categoryId])
|
|
}
|
|
|
|
model ExperienceFinding {
|
|
id String @id @default(cuid())
|
|
locationId String
|
|
evaluationId String?
|
|
createdById String?
|
|
responsibleUserId String?
|
|
title String
|
|
description String @default("")
|
|
categoryKey String?
|
|
categoryLabel String?
|
|
priority ExperienceFindingPriority @default(medium)
|
|
status ExperienceFindingStatus @default(open)
|
|
dueDate DateTime?
|
|
resolvedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Restrict)
|
|
evaluation ExperienceEvaluation? @relation(fields: [evaluationId], references: [id], onDelete: SetNull)
|
|
createdBy User? @relation("ExperienceFindingCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
responsibleUser User? @relation("ExperienceFindingAssignedTo", fields: [responsibleUserId], references: [id], onDelete: SetNull)
|
|
evidence ExperienceEvidence[]
|
|
|
|
@@index([locationId, status, createdAt])
|
|
@@index([evaluationId])
|
|
@@index([responsibleUserId, status])
|
|
}
|
|
|
|
model ExperienceEvidence {
|
|
id String @id @default(cuid())
|
|
locationId String
|
|
evaluationId String?
|
|
findingId String?
|
|
responseId String?
|
|
uploadedById String?
|
|
kind ExperienceEvidenceKind
|
|
title String
|
|
note String?
|
|
url String?
|
|
storagePath String?
|
|
mimeType String?
|
|
sizeBytes Int?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Restrict)
|
|
evaluation ExperienceEvaluation? @relation(fields: [evaluationId], references: [id], onDelete: SetNull)
|
|
finding ExperienceFinding? @relation(fields: [findingId], references: [id], onDelete: SetNull)
|
|
response ExperienceEvaluationResponse? @relation(fields: [responseId], references: [id], onDelete: SetNull)
|
|
uploadedBy User? @relation("ExperienceEvidenceUploadedBy", fields: [uploadedById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([locationId, createdAt])
|
|
@@index([evaluationId, createdAt])
|
|
@@index([findingId, createdAt])
|
|
}
|
|
|
|
model ExperienceLocationMetric {
|
|
id String @id @default(cuid())
|
|
locationId String @unique
|
|
currentScore Float @default(0)
|
|
previousScore Float @default(0)
|
|
trendDelta Float @default(0)
|
|
trendDirection ExperienceTrendDirection @default(flat)
|
|
signal ExperienceSignalStatus @default(yellow)
|
|
totalEvaluations Int @default(0)
|
|
openFindings Int @default(0)
|
|
lastEvaluationAt DateTime?
|
|
lastEvaluationId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
|
|
lastEvaluation ExperienceEvaluation? @relation("ExperienceLocationMetricLastEvaluation", fields: [lastEvaluationId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([signal, currentScore])
|
|
}
|
|
|
|
model ExperienceScoringPolicy {
|
|
id String @id @default(cuid())
|
|
name String
|
|
isActive Boolean @default(true)
|
|
aggregationMode ExperienceScoreAggregationMode @default(weighted_recent)
|
|
recentWindow Int @default(3)
|
|
recentWeightsCsv String @default("0.5,0.3,0.2")
|
|
greenThreshold Float @default(85)
|
|
yellowThreshold Float @default(70)
|
|
createdById String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
createdBy User? @relation("ExperienceScoringPolicyCreatedBy", fields: [createdById], references: [id], onDelete: SetNull)
|
|
|
|
@@index([isActive, updatedAt])
|
|
}
|
|
|
|
model Account {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
type String
|
|
provider String
|
|
providerAccountId String
|
|
refresh_token String? @db.Text
|
|
access_token String? @db.Text
|
|
expires_at Int?
|
|
token_type String?
|
|
scope String?
|
|
id_token String? @db.Text
|
|
session_state String?
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([provider, providerAccountId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model Session {
|
|
id String @id @default(cuid())
|
|
sessionToken String @unique
|
|
userId String
|
|
expires DateTime
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
}
|
|
|
|
model VerificationToken {
|
|
identifier String
|
|
token String @unique
|
|
expires DateTime
|
|
|
|
@@unique([identifier, token])
|
|
}
|