generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" } model Region { id Int @id @default(autoincrement()) name String code String @unique hotels Hotel[] @@map("regions") } model Hotel { id Int @id @default(autoincrement()) name String code String @unique regionId Int @map("region_id") region Region @relation(fields: [regionId], references: [id]) status String @default("ACTIVE") // ACTIVE | INACTIVE users User[] sales SalesResult[] @@map("hotels") } model User { id Int @id @default(autoincrement()) username String @unique email String @unique passwordHash String @map("password_hash") role String // admin | director | hotel_manager | commercial_leader | analyst | auditor | collaborator hotelId Int @map("hotel_id") hotel Hotel @relation(fields: [hotelId], references: [id]) area String status String @default("ACTIVE") // ACTIVE | INACTIVE createdAt DateTime @default(now()) @map("created_at") goals Goal[] sales SalesResult[] @relation("ColaboradorSales") uploadedSales SalesResult[] @relation("UploaderSales") settlements Settlement[] @relation("ColaboradorSettlements") approvedSettlements Settlement[] @relation("ApproverSettlements") plansCreated CompensationPlan[] @relation("PlanCreator") auditLogs AuditLog[] notifications Notification[] importJobs SalesImportJob[] @@map("users") } model CompensationPlan { id Int @id @default(autoincrement()) name String code String validityStart DateTime @map("validity_start") validityEnd DateTime? @map("validity_end") type String // PERCENTAGE | SCALE | CONDITIONAL | FIXED formula String? // JSON or formula string metaAmount Decimal? @map("meta_amount") @db.Decimal(12, 2) percentageRate Decimal? @map("percentage_rate") @db.Decimal(5, 4) maxCap Decimal? @map("max_cap") @db.Decimal(12, 2) status String @default("DRAFT") // DRAFT | ACTIVE | INACTIVE version Int @default(1) createdBy Int @map("created_by") creator User @relation("PlanCreator", fields: [createdBy], references: [id]) createdAt DateTime @default(now()) @map("created_at") rules CalculationRule[] settlements Settlement[] @@map("compensation_plans") } model CalculationRule { id Int @id @default(autoincrement()) planId Int @map("plan_id") plan CompensationPlan @relation(fields: [planId], references: [id], onDelete: Cascade) type String // TIER | BONUS minAchievement Decimal @map("min_achievement") @db.Decimal(5, 4) maxAchievement Decimal @map("max_achievement") @db.Decimal(5, 4) rate Decimal @map("rate") @db.Decimal(5, 4) payoutAmount Decimal @map("payout_amount") @db.Decimal(12, 2) @@map("calculation_rules") } model Goal { id Int @id @default(autoincrement()) targetType String @map("target_type") // INDIVIDUAL | TEAM | HOTEL targetId Int @map("target_id") user User? @relation(fields: [targetId], references: [id]) period String @map("period") // YYYY-MM amount Decimal @db.Decimal(12, 2) createdAt DateTime @default(now()) @map("created_at") @@map("goals") } model SalesResult { id Int @id @default(autoincrement()) source String // EXCEL | API hotelId Int @map("hotel_id") hotel Hotel @relation(fields: [hotelId], references: [id]) userId Int @map("user_id") colaborador User @relation("ColaboradorSales", fields: [userId], references: [id]) period String @map("period") // YYYY-MM amount Decimal @db.Decimal(12, 2) salesCount Int @map("sales_count") status String @default("PENDING") // PENDING | PROCESSED idempotencyKey String @unique @map("idempotency_key") transactionId String? @map("transaction_id") uploadedBy Int @map("uploaded_by") uploader User @relation("UploaderSales", fields: [uploadedBy], references: [id]) isAnomaly Boolean @default(false) @map("is_anomaly") flaggedReason Json? @map("flagged_reason") createdAt DateTime @default(now()) @map("created_at") @@map("sales_results") } model Settlement { id Int @id @default(autoincrement()) period String @map("period") // YYYY-MM planId Int @map("plan_id") plan CompensationPlan @relation(fields: [planId], references: [id]) userId Int @map("user_id") colaborador User @relation("ColaboradorSettlements", fields: [userId], references: [id]) salesAmount Decimal @map("sales_amount") @db.Decimal(12, 2) goalAmount Decimal @map("goal_amount") @db.Decimal(12, 2) achievementPercentage Decimal @map("achievement_percentage") @db.Decimal(5, 4) calculatedCommission Decimal @map("calculated_commission") @db.Decimal(12, 2) calculatedBonus Decimal @map("calculated_bonus") @db.Decimal(12, 2) adjustmentAmount Decimal @map("adjustment_amount") @db.Decimal(12, 2) totalPayout Decimal @map("total_payout") @db.Decimal(12, 2) status String @default("SIMULATED") // SIMULATED | PENDING | APPROVED | REJECTED approvedBy Int? @map("approved_by") approver User? @relation("ApproverSettlements", fields: [approvedBy], references: [id]) approvedAt DateTime? @map("approved_at") rejectionReason String? @map("rejection_reason") originalSettlementId Int? @map("original_settlement_id") originalSettlement Settlement? @relation("SettlementAdjustments", fields: [originalSettlementId], references: [id]) adjustments Settlement[] @relation("SettlementAdjustments") adjustmentNotes String? @map("adjustment_notes") aiAudited Boolean @default(false) @map("ai_audited") aiAuditNotes Json? @map("ai_audit_notes") createdAt DateTime @default(now()) @map("created_at") @@map("settlements") } model AuditLog { id Int @id @default(autoincrement()) userId Int @map("user_id") user User @relation(fields: [userId], references: [id]) action String // CREATE | UPDATE | DELETE | APPROVE | REJECT | LOGIN targetTable String @map("target_table") targetId Int @map("target_id") previousValue Json? @map("previous_value") newValue Json? @map("new_value") ipAddress String? @map("ip_address") createdAt DateTime @default(now()) @map("created_at") @@map("audit_logs") } model Notification { id Int @id @default(autoincrement()) userId Int @map("user_id") user User @relation(fields: [userId], references: [id]) title String message String status String @default("UNREAD") // UNREAD | READ type String // EMAIL | PUSH sentAt DateTime @default(now()) @map("sent_at") @@map("notifications") } model SalesImportJob { id Int @id @default(autoincrement()) idempotencyKey String @unique @map("idempotency_key") status String @default("PROCESSING") // PROCESSING | SUCCESS | FAILED errorMessage String? @map("error_message") uploadedBy Int @map("uploaded_by") uploader User @relation(fields: [uploadedBy], references: [id]) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@map("sales_import_jobs") }