1165 lines
58 KiB
Plaintext
1165 lines
58 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
previewFeatures = []
|
|
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
|
engineType = "library"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
email String @unique
|
|
username String @unique
|
|
password String
|
|
role Role @default(USER)
|
|
isActive Boolean @default(false)
|
|
canDownload Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
department String @default("")
|
|
dingtalkUserId String?
|
|
loginType String @default("normal")
|
|
realName String?
|
|
phone String?
|
|
avatar String?
|
|
managedDepartment String?
|
|
isSuperAdmin Boolean @default(false)
|
|
departmentId String?
|
|
employmentStatus String? @default("active")
|
|
resignationDate DateTime?
|
|
transferDate DateTime?
|
|
transferToDeptId String?
|
|
employmentNote String?
|
|
statusChangedBy String?
|
|
statusChangedAt DateTime?
|
|
status String @default("pending")
|
|
lastLoginAt DateTime?
|
|
lastLoginIp String?
|
|
loginCount Int @default(0)
|
|
archivedAt DateTime?
|
|
managedDepartments Department[] @relation("DepartmentManager")
|
|
downloadLogs MaterialDownloadLog[]
|
|
favorites MaterialFavorite[]
|
|
likes MaterialLike[]
|
|
materialLogs MaterialLog[]
|
|
materialTransfersFrom MaterialTransfer[] @relation("MaterialTransferFromUser")
|
|
materialTransfersTo MaterialTransfer[] @relation("MaterialTransferToUser")
|
|
materialTransfersAsOperator MaterialTransfer[] @relation("MaterialTransferOperator")
|
|
materials Material[] @relation("MaterialOwner")
|
|
taskDetailRequestedMaterials Material[] @relation("TaskDetailRequester")
|
|
productPackageUploadJobs ProductPackageUploadJob[] @relation("ProductPackageUploadJobOperator")
|
|
departmentRef Department? @relation("UserDepartment", fields: [departmentId], references: [id])
|
|
transferToDept Department? @relation("UserTransferDepartment", fields: [transferToDeptId], references: [id])
|
|
|
|
@@index([status])
|
|
@@index([archivedAt])
|
|
@@index([departmentId])
|
|
@@index([employmentStatus])
|
|
@@index([transferToDeptId])
|
|
@@map("users")
|
|
}
|
|
|
|
model Material {
|
|
id String @id @default(uuid())
|
|
previewUrl String
|
|
productModel String
|
|
reportTitle String? @map("report_title")
|
|
categoryName String
|
|
sceneName String
|
|
materialType String @default("3DMAX")
|
|
renderer String @default("CR")
|
|
authorName String
|
|
zipFileName String @default("")
|
|
zipFilePath String @default("")
|
|
zipFileSize BigInt @default(0)
|
|
downloadCount Int @default(0)
|
|
likeCount Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
userId String
|
|
displayImages String[] @default([])
|
|
platformName String @default("")
|
|
uploadId String?
|
|
videoSourceUrl String?
|
|
videoPreview540Url String?
|
|
videoPreviewClipUrl String?
|
|
videoCoverUrl String?
|
|
videoDuration Int?
|
|
videoProcessingStatus String?
|
|
transcodeLastError String? @map("transcodelasterror")
|
|
transcodeAttempts Int? @map("transcodeattempts")
|
|
deletedAt DateTime?
|
|
productCategoryName String @default("")
|
|
originalOwnerId String?
|
|
transferredAt DateTime?
|
|
transferredBy String?
|
|
transferNote String?
|
|
taskNo String? @map("task_no")
|
|
dingtalkApprovalNo String? @map("dingtalk_approval_no")
|
|
taskStatus String? @map("task_status")
|
|
taskFetchedAt DateTime? @map("task_fetched_at")
|
|
isFullSet Boolean @default(false) @map("is_full_set")
|
|
isAiGenerated Boolean @default(false) @map("is_ai_generated")
|
|
taskDetailSourceType String? @map("task_detail_source_type")
|
|
taskDetailRequesterUserId String? @map("task_detail_requester_user_id")
|
|
taskDetailRequesterName String? @map("task_detail_requester_name")
|
|
assets MaterialAsset[]
|
|
downloadLogs MaterialDownloadLog[]
|
|
favorites MaterialFavorite[]
|
|
likes MaterialLike[]
|
|
logs MaterialLog[]
|
|
skus MaterialSku[]
|
|
transfers MaterialTransfer[]
|
|
transcodeProgresses VideoTranscodeProgress[] @relation("MaterialTranscodeProgress")
|
|
productPackageUploadJobs ProductPackageUploadJob[]
|
|
user User @relation("MaterialOwner", fields: [userId], references: [id], onDelete: Cascade)
|
|
taskDetailRequester User? @relation("TaskDetailRequester", fields: [taskDetailRequesterUserId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([userId])
|
|
@@index([taskDetailRequesterUserId])
|
|
@@index([createdAt])
|
|
@@index([categoryName])
|
|
@@index([sceneName])
|
|
@@index([platformName])
|
|
@@index([productCategoryName])
|
|
@@index([materialType])
|
|
@@index([downloadCount])
|
|
@@index([likeCount])
|
|
@@index([deletedAt])
|
|
@@index([originalOwnerId])
|
|
@@index([transferredAt])
|
|
@@index([taskNo])
|
|
@@index([dingtalkApprovalNo])
|
|
@@index([taskStatus])
|
|
@@index([isFullSet])
|
|
@@index([productModel])
|
|
@@index([reportTitle])
|
|
@@index([authorName])
|
|
@@map("materials")
|
|
}
|
|
|
|
model ProductPackageUploadJob {
|
|
id String @id @default(uuid())
|
|
materialId String @map("material_id")
|
|
operatorUserId String @map("operator_user_id")
|
|
taskNo String? @map("task_no")
|
|
dingtalkApprovalNo String? @map("dingtalk_approval_no")
|
|
assets Json
|
|
options Json?
|
|
status String
|
|
stage String
|
|
progress Int @default(0)
|
|
errorMessage String? @map("error_message")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
startedAt DateTime? @map("started_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
operator User @relation("ProductPackageUploadJobOperator", fields: [operatorUserId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([materialId])
|
|
@@index([operatorUserId, createdAt])
|
|
@@index([status, createdAt])
|
|
@@map("product_package_upload_jobs")
|
|
}
|
|
|
|
model MaterialLike {
|
|
id String @id @default(uuid())
|
|
materialId String
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([materialId, userId])
|
|
@@index([materialId])
|
|
@@index([userId])
|
|
@@map("material_likes")
|
|
}
|
|
|
|
model MaterialFavorite {
|
|
id String @id @default(uuid())
|
|
materialId String
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([materialId, userId])
|
|
@@index([materialId])
|
|
@@index([userId])
|
|
@@map("material_favorites")
|
|
}
|
|
|
|
model MaterialDownloadLog {
|
|
id String @id @default(uuid())
|
|
materialId String
|
|
userId String
|
|
downloadedAt DateTime @default(now())
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([materialId])
|
|
@@index([userId])
|
|
@@index([downloadedAt])
|
|
@@index([materialId, userId, downloadedAt])
|
|
@@map("material_download_logs")
|
|
}
|
|
|
|
model MaterialLog {
|
|
id String @id @default(uuid())
|
|
materialId String
|
|
userId String
|
|
action String
|
|
changes String?
|
|
timestamp DateTime @default(now())
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([materialId])
|
|
@@index([userId])
|
|
@@index([timestamp])
|
|
@@map("material_logs")
|
|
}
|
|
|
|
model MaterialSku {
|
|
id String @id @default(uuid())
|
|
materialId String @map("material_id")
|
|
skuName String @map("sku_name")
|
|
filePath String @map("file_path")
|
|
fileSize BigInt @default(0) @map("file_size")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
fileName String? @map("file_name")
|
|
previewUrl String? @map("preview_url")
|
|
deletedAt DateTime? @map("deleted_at")
|
|
whiteBackgroundSourceType String? @map("white_background_source_type")
|
|
whiteBackgroundUploadedBy String? @map("white_background_uploaded_by")
|
|
whiteBackgroundUploadedAt DateTime? @map("white_background_uploaded_at")
|
|
barcodes MaterialSkuBarcode[]
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([materialId])
|
|
@@index([skuName, deletedAt])
|
|
@@index([sortOrder])
|
|
@@index([deletedAt])
|
|
@@index([whiteBackgroundSourceType])
|
|
@@index([whiteBackgroundUploadedBy])
|
|
@@index([whiteBackgroundUploadedAt])
|
|
@@map("material_skus")
|
|
}
|
|
|
|
model ProductCategory {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
createdAt DateTime @default(now())
|
|
|
|
@@map("product_categories")
|
|
}
|
|
|
|
model Category {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
createdAt DateTime @default(now())
|
|
|
|
@@map("categories")
|
|
}
|
|
|
|
model Scene {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
createdAt DateTime @default(now())
|
|
|
|
@@map("scenes")
|
|
}
|
|
|
|
model Platform {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
createdAt DateTime @default(now())
|
|
|
|
@@map("platforms")
|
|
}
|
|
|
|
model SystemSettings {
|
|
id String @id @default(uuid())
|
|
headerBgColor String @default("#1f2937")
|
|
siteName String @default("由壹点3D素材")
|
|
updatedAt DateTime @updatedAt
|
|
createdAt DateTime @default(now())
|
|
headerLogoUrl String @default("http://s3.1080p.hk/shuzhou/2025/05/18/8ebadf0a7cc34eaea00e8619b8efb827.png")
|
|
loginLogoUrl String @default("http://s3.1080p.hk/shuzhou/2025/05/18/8ebadf0a7cc34eaea00e8619b8efb827.png")
|
|
s3AccessKey String @default("")
|
|
s3Bucket String @default("")
|
|
s3Endpoint String @default("")
|
|
s3PublicUrl String @default("")
|
|
s3Region String @default("us-east-1")
|
|
s3SecretKey String @default("")
|
|
maintenanceEnabled Boolean @default(false) @map("maintenance_enabled")
|
|
maintenanceMessage String? @map("maintenance_message")
|
|
maintenanceStartTime DateTime? @map("maintenance_start_time")
|
|
maintenanceEndTime DateTime? @map("maintenance_end_time")
|
|
|
|
@@map("system_settings")
|
|
}
|
|
|
|
model Department {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
createdAt DateTime @default(now())
|
|
parentId String?
|
|
level Int @default(1)
|
|
status String @default("active")
|
|
managerId String?
|
|
code String? @unique
|
|
description String?
|
|
sortOrder Int @default(0)
|
|
updatedAt DateTime @updatedAt
|
|
manager User? @relation("DepartmentManager", fields: [managerId], references: [id])
|
|
parent Department? @relation("DepartmentHierarchy", fields: [parentId], references: [id])
|
|
children Department[] @relation("DepartmentHierarchy")
|
|
users User[] @relation("UserDepartment")
|
|
transferredUsers User[] @relation("UserTransferDepartment")
|
|
|
|
@@index([parentId])
|
|
@@index([status])
|
|
@@index([level])
|
|
@@index([managerId])
|
|
@@map("departments")
|
|
}
|
|
|
|
model Danmaku {
|
|
id String @id @default(uuid())
|
|
content String
|
|
username String
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([createdAt])
|
|
@@map("danmakus")
|
|
}
|
|
|
|
model DepartmentMaterialPermission {
|
|
id String @id @default(uuid())
|
|
department String
|
|
materialType String
|
|
canView Boolean @default(false)
|
|
canDownload Boolean @default(false)
|
|
canShare Boolean @default(true)
|
|
linkedToDepartment String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
canDownloadSource Boolean @default(false) @map("can_download_source")
|
|
|
|
@@unique([department, materialType])
|
|
@@index([department])
|
|
@@index([materialType])
|
|
@@index([linkedToDepartment])
|
|
@@map("department_material_permissions")
|
|
}
|
|
|
|
model MaterialTransfer {
|
|
id String @id @default(uuid())
|
|
materialId String
|
|
fromUserId String
|
|
toUserId String
|
|
transferredBy String
|
|
transferNote String?
|
|
transferredAt DateTime @default(now())
|
|
fromUser User @relation("MaterialTransferFromUser", fields: [fromUserId], references: [id])
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
toUser User @relation("MaterialTransferToUser", fields: [toUserId], references: [id])
|
|
operator User @relation("MaterialTransferOperator", fields: [transferredBy], references: [id])
|
|
|
|
@@index([materialId])
|
|
@@index([fromUserId])
|
|
@@index([toUserId])
|
|
@@index([transferredAt])
|
|
@@map("material_transfers")
|
|
}
|
|
|
|
model MaterialAsset {
|
|
id String @id @default(uuid())
|
|
materialId String @map("material_id")
|
|
assetType String @map("asset_type")
|
|
fileUrl String @map("file_url")
|
|
fileName String? @map("file_name")
|
|
fileSize BigInt @default(0) @map("file_size")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
skuCode String? @map("sku_code")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
|
|
barcodes MaterialAssetBarcode[]
|
|
|
|
@@index([materialId])
|
|
@@index([assetType])
|
|
@@index([sortOrder])
|
|
@@map("material_assets")
|
|
}
|
|
|
|
model MaterialAssetBarcode {
|
|
id String @id @default(uuid())
|
|
assetId String @map("asset_id")
|
|
barcode String
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
asset MaterialAsset @relation(fields: [assetId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([assetId, barcode])
|
|
@@index([barcode])
|
|
@@index([assetId])
|
|
@@map("material_asset_barcodes")
|
|
}
|
|
|
|
model MaterialSkuBarcode {
|
|
id String @id @default(uuid())
|
|
skuId String @map("sku_id")
|
|
barcode String
|
|
deletedAt DateTime? @map("deleted_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
sku MaterialSku @relation(fields: [skuId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([barcode])
|
|
@@index([skuId])
|
|
@@index([deletedAt])
|
|
@@map("material_sku_barcodes")
|
|
}
|
|
|
|
model ApiKey {
|
|
id String @id @default(uuid())
|
|
name String
|
|
key String @unique
|
|
isActive Boolean @default(true) @map("is_active")
|
|
createdBy String @map("created_by")
|
|
lastUsedAt DateTime? @map("last_used_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
callLogs ApiCallLog[]
|
|
externalMaterialImportJobs ExternalMaterialImportJob[]
|
|
idempotencyRecords ExternalApiIdempotencyRecord[]
|
|
|
|
@@index([key])
|
|
@@index([isActive])
|
|
@@map("api_keys")
|
|
}
|
|
|
|
model ExternalApiIdempotencyRecord {
|
|
id String @id @default(uuid())
|
|
apiKeyId String @map("api_key_id")
|
|
operationType String @map("operation_type")
|
|
clientRequestId String @map("client_request_id")
|
|
requestHash String @map("request_hash")
|
|
status String
|
|
responseStatus Int? @map("response_status")
|
|
responseBody Json? @map("response_body")
|
|
completedAt DateTime? @map("completed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([apiKeyId, operationType, clientRequestId])
|
|
@@index([apiKeyId])
|
|
@@index([operationType])
|
|
@@index([clientRequestId])
|
|
@@index([status])
|
|
@@index([createdAt])
|
|
@@map("external_api_idempotency_records")
|
|
}
|
|
|
|
model ApiCallLog {
|
|
id String @id @default(uuid())
|
|
apiKeyId String @map("api_key_id")
|
|
endpoint String
|
|
method String
|
|
taskNo String? @map("task_no")
|
|
queryType String? @map("query_type")
|
|
queryValue String? @map("query_value")
|
|
statusCode Int @map("status_code")
|
|
duration Int
|
|
ipAddress String? @map("ip_address")
|
|
userAgent String? @map("user_agent")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([apiKeyId])
|
|
@@index([taskNo])
|
|
@@index([queryType])
|
|
@@index([queryValue])
|
|
@@index([createdAt])
|
|
@@map("api_call_logs")
|
|
}
|
|
|
|
model ExternalMaterialImportJob {
|
|
id String @id @default(uuid())
|
|
apiKeyId String @map("api_key_id")
|
|
clientRequestId String @map("client_request_id")
|
|
materialType String @map("material_type")
|
|
taskNo String @map("task_no")
|
|
status String
|
|
resolvedUserId String? @map("resolved_user_id")
|
|
requestPayload Json @map("request_payload")
|
|
submissionSnapshot Json @map("submission_snapshot")
|
|
resultMaterialId String? @map("result_material_id")
|
|
errorCode String? @map("error_code")
|
|
errorMessage String? @map("error_message")
|
|
completedAt DateTime? @map("completed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([apiKeyId, clientRequestId])
|
|
@@index([taskNo, status])
|
|
@@index([status])
|
|
@@index([createdAt])
|
|
@@map("external_material_import_jobs")
|
|
}
|
|
|
|
model PerformanceSurveyEmployeeProfile {
|
|
id String @id @default(uuid())
|
|
dingtalkUserId String? @unique @map("dingtalk_user_id")
|
|
dingEmail String? @map("ding_email")
|
|
jobNumber String? @unique @map("job_number")
|
|
flowerName String? @map("flower_name")
|
|
realName String? @map("real_name")
|
|
displayName String @map("display_name")
|
|
departmentName String? @map("department_name")
|
|
departmentPath String? @map("department_path")
|
|
positionTitle String? @map("position_title")
|
|
positionLevel String? @map("position_level")
|
|
levelType String? @map("level_type")
|
|
isLeadership Boolean @default(false) @map("is_leadership")
|
|
isDingtalkAdmin Boolean @default(false) @map("is_dingtalk_admin")
|
|
isDingtalkBoss Boolean @default(false) @map("is_dingtalk_boss")
|
|
isDingtalkSenior Boolean @default(false) @map("is_dingtalk_senior")
|
|
managerDingtalkUserId String? @map("manager_dingtalk_user_id")
|
|
managerJobNumber String? @map("manager_job_number")
|
|
managerName String? @map("manager_name")
|
|
employmentStatus String? @map("employment_status")
|
|
workPlace String? @map("work_place")
|
|
sourcePayload Json? @map("source_payload")
|
|
syncedAt DateTime? @map("synced_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
evaluatorAssignments PerformanceSurveyAssignment[] @relation("PerformanceSurveyEvaluator")
|
|
targetRecords PerformanceSurveyTarget[] @relation("PerformanceSurveyTargetEmployee")
|
|
responses PerformanceSurveyResponse[] @relation("PerformanceSurveyRespondentEmployee")
|
|
submittedWorkItems PerformanceSurveyWorkItem[] @relation("PerformanceSurveyWorkItemSubmitter")
|
|
workItemScores PerformanceSurveyWorkItemScore[] @relation("PerformanceSurveyWorkItemScoreEvaluator")
|
|
notifications PerformanceSurveyNotification[]
|
|
manualPositionAssignments PerformanceSurveyEmployeePositionAssignment[]
|
|
departmentMemberships PerformanceSurveyEmployeeDepartmentMembership[]
|
|
submittedWorkReviewProjects WorkReviewProject[] @relation("WorkReviewSubmitter")
|
|
managedWorkReviewProjects WorkReviewProject[] @relation("WorkReviewManager")
|
|
finalWorkReviewProjects WorkReviewProject[] @relation("WorkReviewFinalReviewer")
|
|
workReviews WorkReviewReview[] @relation("WorkReviewReviewer")
|
|
|
|
@@index([displayName])
|
|
@@index([dingEmail])
|
|
@@index([departmentName])
|
|
@@index([positionLevel])
|
|
@@index([levelType])
|
|
@@index([isLeadership])
|
|
@@index([isDingtalkAdmin])
|
|
@@index([managerDingtalkUserId])
|
|
@@index([employmentStatus])
|
|
@@map("performance_survey_employee_profiles")
|
|
}
|
|
|
|
model PerformanceSurveyEmployeeDepartmentMembership {
|
|
id String @id @default(uuid())
|
|
employeeProfileId String @map("employee_profile_id")
|
|
sourceDeptId String @map("source_dept_id")
|
|
departmentName String? @map("department_name")
|
|
departmentPath String? @map("department_path")
|
|
isPrimary Boolean @default(false) @map("is_primary")
|
|
syncedAt DateTime? @map("synced_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
employeeProfile PerformanceSurveyEmployeeProfile @relation(fields: [employeeProfileId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([employeeProfileId, sourceDeptId], map: "ps_employee_dept_profile_dept_key")
|
|
@@index([sourceDeptId], map: "ps_employee_dept_source_dept_idx")
|
|
@@index([departmentName], map: "ps_employee_dept_name_idx")
|
|
@@index([departmentPath], map: "ps_employee_dept_path_idx")
|
|
@@index([employeeProfileId, isPrimary], map: "ps_employee_dept_profile_primary_idx")
|
|
@@map("performance_survey_employee_department_memberships")
|
|
}
|
|
|
|
model PerformanceSurveyDepartmentProfile {
|
|
id String @id @default(uuid())
|
|
name String @unique
|
|
parentName String? @map("parent_name")
|
|
sourceDeptId String? @map("source_dept_id")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
employeeCount Int @default(0) @map("employee_count")
|
|
syncedAt DateTime? @map("synced_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@index([parentName])
|
|
@@index([sourceDeptId])
|
|
@@map("performance_survey_department_profiles")
|
|
}
|
|
|
|
model PerformanceSurveyTemplate {
|
|
id String @id @default(uuid())
|
|
code String @unique
|
|
name String
|
|
description String?
|
|
surveyType String @default("person_period") @map("survey_type")
|
|
weight Float @default(1)
|
|
questions Json
|
|
scoreBands Json @map("score_bands")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
archivedAt DateTime? @map("archived_at")
|
|
archivedByUserId String? @map("archived_by_user_id")
|
|
archivedByName String? @map("archived_by_name")
|
|
archiveReason String? @map("archive_reason") @db.VarChar(500)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
versions PerformanceSurveyTemplateVersion[]
|
|
|
|
@@index([surveyType])
|
|
@@index([isActive])
|
|
@@index([archivedAt])
|
|
@@map("performance_survey_templates")
|
|
}
|
|
|
|
model PerformanceSurveyTemplateVersion {
|
|
id String @id @default(uuid())
|
|
templateId String @map("template_id")
|
|
version Int
|
|
status String @default("draft")
|
|
effectiveMonth String? @map("effective_month")
|
|
definition Json
|
|
publishedAt DateTime? @map("published_at")
|
|
createdByUserId String? @map("created_by_user_id")
|
|
createdByName String? @map("created_by_name")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
template PerformanceSurveyTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
|
positionPlanItems PerformanceSurveyPositionPlanItem[]
|
|
surveys PerformanceSurvey[]
|
|
|
|
@@unique([templateId, version], map: "performance_survey_template_version_unique")
|
|
@@index([status, effectiveMonth], map: "performance_survey_template_version_status_month_idx")
|
|
@@map("performance_survey_template_versions")
|
|
}
|
|
|
|
model PerformanceSurveyPositionGroup {
|
|
id String @id @default(uuid())
|
|
code String @unique
|
|
name String
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
isSystem Boolean @default(false) @map("is_system")
|
|
archivedAt DateTime? @map("archived_at")
|
|
archivedByUserId String? @map("archived_by_user_id")
|
|
archivedByName String? @map("archived_by_name")
|
|
archiveReason String? @map("archive_reason") @db.VarChar(500)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
rules PerformanceSurveyPositionRule[]
|
|
plans PerformanceSurveyPositionPlan[]
|
|
surveys PerformanceSurvey[]
|
|
manualAssignments PerformanceSurveyEmployeePositionAssignment[]
|
|
|
|
@@index([isActive, sortOrder], map: "performance_survey_position_group_active_sort_idx")
|
|
@@index([archivedAt, sortOrder], map: "performance_survey_position_group_archived_sort_idx")
|
|
@@map("performance_survey_position_groups")
|
|
}
|
|
|
|
model PerformanceSurveyPositionRule {
|
|
id String @id @default(uuid())
|
|
positionGroupId String @map("position_group_id")
|
|
departmentPathPrefix String? @map("department_path_prefix")
|
|
positionTitle String? @map("position_title")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
positionGroup PerformanceSurveyPositionGroup @relation(fields: [positionGroupId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([positionGroupId, isActive, sortOrder], map: "performance_survey_position_rule_group_idx")
|
|
@@index([positionTitle], map: "performance_survey_position_rule_title_idx")
|
|
@@map("performance_survey_position_rules")
|
|
}
|
|
|
|
model PerformanceSurveyPositionPlan {
|
|
id String @id @default(uuid())
|
|
positionGroupId String @map("position_group_id")
|
|
version Int
|
|
status String @default("draft")
|
|
effectiveMonth String? @map("effective_month")
|
|
matchRules Json @default("[]") @map("match_rules")
|
|
groupConfig Json? @map("group_config")
|
|
publishedAt DateTime? @map("published_at")
|
|
createdByUserId String? @map("created_by_user_id")
|
|
createdByName String? @map("created_by_name")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
positionGroup PerformanceSurveyPositionGroup @relation(fields: [positionGroupId], references: [id], onDelete: Cascade)
|
|
items PerformanceSurveyPositionPlanItem[]
|
|
|
|
@@unique([positionGroupId, version], map: "performance_survey_position_plan_version_unique")
|
|
@@index([positionGroupId, status, effectiveMonth], map: "performance_survey_position_plan_group_status_month_idx")
|
|
@@map("performance_survey_position_plans")
|
|
}
|
|
|
|
model PerformanceSurveyEmployeePositionAssignment {
|
|
id String @id @default(uuid())
|
|
employeeProfileId String @map("employee_profile_id")
|
|
assignmentType String @map("assignment_type")
|
|
positionGroupId String? @map("position_group_id")
|
|
startMonth String @map("start_month")
|
|
endMonth String? @map("end_month")
|
|
reason String @db.VarChar(500)
|
|
status String @default("active")
|
|
createdByUserId String @map("created_by_user_id")
|
|
createdByName String @map("created_by_name")
|
|
archivedAt DateTime? @map("archived_at")
|
|
archivedByUserId String? @map("archived_by_user_id")
|
|
archivedByName String? @map("archived_by_name")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
employeeProfile PerformanceSurveyEmployeeProfile @relation(fields: [employeeProfileId], references: [id], onDelete: Restrict)
|
|
positionGroup PerformanceSurveyPositionGroup? @relation(fields: [positionGroupId], references: [id], onDelete: Restrict)
|
|
|
|
@@index([employeeProfileId, status, startMonth, endMonth], map: "performance_survey_manual_assignment_employee_range_idx")
|
|
@@index([positionGroupId], map: "performance_survey_manual_assignment_group_idx")
|
|
@@index([status, startMonth, endMonth], map: "performance_survey_manual_assignment_status_range_idx")
|
|
@@map("performance_survey_employee_position_assignments")
|
|
}
|
|
|
|
model PerformanceSurveyPositionPlanItem {
|
|
id String @id @default(uuid())
|
|
positionPlanId String @map("position_plan_id")
|
|
templateVersionId String @map("template_version_id")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
isEnabled Boolean @default(true) @map("is_enabled")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
positionPlan PerformanceSurveyPositionPlan @relation(fields: [positionPlanId], references: [id], onDelete: Cascade)
|
|
templateVersion PerformanceSurveyTemplateVersion @relation(fields: [templateVersionId], references: [id], onDelete: Restrict)
|
|
|
|
@@unique([positionPlanId, templateVersionId], map: "performance_survey_position_plan_item_unique")
|
|
@@index([positionPlanId, isEnabled, sortOrder], map: "performance_survey_position_plan_item_sort_idx")
|
|
@@map("performance_survey_position_plan_items")
|
|
}
|
|
|
|
model PerformanceSurvey {
|
|
id String @id @default(uuid())
|
|
title String
|
|
description String?
|
|
surveyKind String @default("person_period") @map("survey_kind")
|
|
templateCode String @map("template_code")
|
|
templateSnapshot Json @map("template_snapshot")
|
|
templateVersionId String? @map("template_version_id")
|
|
positionGroupId String? @map("position_group_id")
|
|
positionGroupCode String? @map("position_group_code")
|
|
positionGroupSnapshot Json? @map("position_group_snapshot")
|
|
status String @default("draft")
|
|
creatorUserId String @map("creator_user_id")
|
|
creatorName String @map("creator_name")
|
|
creatorEmployeeId String? @map("creator_employee_id")
|
|
departmentName String? @map("department_name")
|
|
assessmentMonth String? @map("assessment_month")
|
|
dueAt DateTime? @map("due_at")
|
|
openedAt DateTime? @map("opened_at")
|
|
closedAt DateTime? @map("closed_at")
|
|
cancelledAt DateTime? @map("cancelled_at")
|
|
cancelledByUserId String? @map("cancelled_by_user_id")
|
|
cancelledByName String? @map("cancelled_by_name")
|
|
cancelReason String? @db.VarChar(500) @map("cancel_reason")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
targets PerformanceSurveyTarget[]
|
|
assignments PerformanceSurveyAssignment[]
|
|
responses PerformanceSurveyResponse[]
|
|
workItems PerformanceSurveyWorkItem[]
|
|
workItemScores PerformanceSurveyWorkItemScore[]
|
|
notifications PerformanceSurveyNotification[]
|
|
templateVersion PerformanceSurveyTemplateVersion? @relation(fields: [templateVersionId], references: [id], onDelete: SetNull)
|
|
positionGroup PerformanceSurveyPositionGroup? @relation(fields: [positionGroupId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([status])
|
|
@@index([surveyKind])
|
|
@@index([templateCode])
|
|
@@index([templateVersionId])
|
|
@@index([positionGroupId, assessmentMonth], map: "performance_surveys_position_group_month_idx")
|
|
@@index([positionGroupCode, assessmentMonth], map: "performance_surveys_position_group_code_month_idx")
|
|
@@index([templateCode, assessmentMonth], map: "performance_surveys_template_month_idx")
|
|
@@index([creatorUserId])
|
|
@@index([departmentName])
|
|
@@index([assessmentMonth])
|
|
@@index([dueAt])
|
|
@@map("performance_surveys")
|
|
}
|
|
|
|
model PerformanceSurveyTarget {
|
|
id String @id @default(uuid())
|
|
surveyId String @map("survey_id")
|
|
targetType String @default("employee") @map("target_type")
|
|
employeeProfileId String? @map("employee_profile_id")
|
|
targetName String @map("target_name")
|
|
targetSnapshot Json @map("target_snapshot")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
survey PerformanceSurvey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
employeeProfile PerformanceSurveyEmployeeProfile? @relation("PerformanceSurveyTargetEmployee", fields: [employeeProfileId], references: [id])
|
|
assignments PerformanceSurveyAssignment[]
|
|
responses PerformanceSurveyResponse[]
|
|
workItems PerformanceSurveyWorkItem[]
|
|
workItemScores PerformanceSurveyWorkItemScore[]
|
|
notifications PerformanceSurveyNotification[]
|
|
|
|
@@index([surveyId])
|
|
@@index([targetType])
|
|
@@index([employeeProfileId])
|
|
@@index([employeeProfileId, surveyId], map: "performance_survey_targets_employee_survey_idx")
|
|
@@map("performance_survey_targets")
|
|
}
|
|
|
|
model PerformanceSurveyAssignment {
|
|
id String @id @default(uuid())
|
|
surveyId String @map("survey_id")
|
|
targetId String @map("target_id")
|
|
evaluatorEmployeeId String? @map("evaluator_employee_id")
|
|
evaluatorUserId String? @map("evaluator_user_id")
|
|
evaluatorDingtalkUserId String? @map("evaluator_dingtalk_user_id")
|
|
evaluatorKey String @map("evaluator_key")
|
|
evaluatorName String @map("evaluator_name")
|
|
evaluatorSnapshot Json @map("evaluator_snapshot")
|
|
workflowStageKey String @default("legacy") @map("workflow_stage_key")
|
|
workflowStageOrder Int @default(0) @map("workflow_stage_order")
|
|
reviewerSource String @default("manual_selection") @map("reviewer_source")
|
|
releasedAt DateTime? @map("released_at")
|
|
status String @default("pending")
|
|
submittedAt DateTime? @map("submitted_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
survey PerformanceSurvey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
target PerformanceSurveyTarget @relation(fields: [targetId], references: [id], onDelete: Cascade)
|
|
evaluatorEmployee PerformanceSurveyEmployeeProfile? @relation("PerformanceSurveyEvaluator", fields: [evaluatorEmployeeId], references: [id])
|
|
response PerformanceSurveyResponse?
|
|
workItemScores PerformanceSurveyWorkItemScore[]
|
|
notifications PerformanceSurveyNotification[]
|
|
|
|
@@unique([targetId, evaluatorKey, workflowStageKey], map: "performance_survey_assignment_target_evaluator_stage_key")
|
|
@@index([surveyId])
|
|
@@index([targetId])
|
|
@@index([evaluatorEmployeeId])
|
|
@@index([evaluatorUserId])
|
|
@@index([evaluatorDingtalkUserId])
|
|
@@index([evaluatorKey])
|
|
@@index([surveyId, targetId, workflowStageOrder], map: "performance_survey_assignment_stage_idx")
|
|
@@index([status])
|
|
@@map("performance_survey_assignments")
|
|
}
|
|
|
|
model PerformanceSurveyResponse {
|
|
id String @id @default(uuid())
|
|
surveyId String @map("survey_id")
|
|
targetId String @map("target_id")
|
|
assignmentId String @unique @map("assignment_id")
|
|
respondentUserId String @map("respondent_user_id")
|
|
respondentEmployeeId String? @map("respondent_employee_id")
|
|
respondentName String @map("respondent_name")
|
|
respondentSnapshot Json @map("respondent_snapshot")
|
|
scores Json
|
|
comment String?
|
|
totalScore Float @map("total_score")
|
|
achievementScore Float @map("achievement_score")
|
|
kpiScore Float @map("kpi_score")
|
|
weightedScore Float @map("weighted_score")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
survey PerformanceSurvey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
target PerformanceSurveyTarget @relation(fields: [targetId], references: [id], onDelete: Cascade)
|
|
assignment PerformanceSurveyAssignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
|
respondentEmployee PerformanceSurveyEmployeeProfile? @relation("PerformanceSurveyRespondentEmployee", fields: [respondentEmployeeId], references: [id])
|
|
|
|
@@index([surveyId])
|
|
@@index([targetId])
|
|
@@index([respondentUserId])
|
|
@@index([respondentEmployeeId])
|
|
@@index([createdAt])
|
|
@@map("performance_survey_responses")
|
|
}
|
|
|
|
model PerformanceSurveyWorkItem {
|
|
id String @id @default(uuid())
|
|
surveyId String @map("survey_id")
|
|
targetId String @map("target_id")
|
|
submitterUserId String? @map("submitter_user_id")
|
|
submitterEmployeeId String? @map("submitter_employee_id")
|
|
title String
|
|
description String?
|
|
imageUrls Json @map("image_urls")
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
status String @default("submitted")
|
|
submittedAt DateTime? @map("submitted_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
survey PerformanceSurvey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
target PerformanceSurveyTarget @relation(fields: [targetId], references: [id], onDelete: Cascade)
|
|
submitterEmployee PerformanceSurveyEmployeeProfile? @relation("PerformanceSurveyWorkItemSubmitter", fields: [submitterEmployeeId], references: [id])
|
|
scores PerformanceSurveyWorkItemScore[]
|
|
|
|
@@index([surveyId])
|
|
@@index([targetId])
|
|
@@index([submitterUserId])
|
|
@@index([submitterEmployeeId])
|
|
@@index([status])
|
|
@@map("performance_survey_work_items")
|
|
}
|
|
|
|
model PerformanceSurveyWorkItemScore {
|
|
id String @id @default(uuid())
|
|
workItemId String @map("work_item_id")
|
|
surveyId String @map("survey_id")
|
|
targetId String @map("target_id")
|
|
assignmentId String @map("assignment_id")
|
|
evaluatorUserId String @map("evaluator_user_id")
|
|
evaluatorEmployeeId String? @map("evaluator_employee_id")
|
|
evaluatorName String @map("evaluator_name")
|
|
scores Json
|
|
comment String?
|
|
totalScore Float @map("total_score")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
workItem PerformanceSurveyWorkItem @relation(fields: [workItemId], references: [id], onDelete: Cascade)
|
|
survey PerformanceSurvey @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
target PerformanceSurveyTarget @relation(fields: [targetId], references: [id], onDelete: Cascade)
|
|
assignment PerformanceSurveyAssignment @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
|
evaluatorEmployee PerformanceSurveyEmployeeProfile? @relation("PerformanceSurveyWorkItemScoreEvaluator", fields: [evaluatorEmployeeId], references: [id])
|
|
|
|
@@unique([workItemId, assignmentId], map: "performance_survey_work_item_score_unique")
|
|
@@index([surveyId])
|
|
@@index([targetId])
|
|
@@index([assignmentId])
|
|
@@index([evaluatorUserId])
|
|
@@index([evaluatorEmployeeId])
|
|
@@map("performance_survey_work_item_scores")
|
|
}
|
|
|
|
model PerformanceSurveyNotification {
|
|
id String @id @default(uuid())
|
|
surveyId String? @map("survey_id")
|
|
targetId String? @map("target_id")
|
|
assignmentId String? @map("assignment_id")
|
|
recipientEmployeeId String? @map("recipient_employee_id")
|
|
recipientUserId String? @map("recipient_user_id")
|
|
dingtalkUserId String? @map("dingtalk_user_id")
|
|
recipientName String @map("recipient_name")
|
|
eventType String @map("event_type")
|
|
businessKey String @map("business_key")
|
|
title String
|
|
content String
|
|
actionUrl String? @map("action_url")
|
|
status String @default("pending")
|
|
attemptCount Int @default(0) @map("attempt_count")
|
|
maxAttempts Int @default(5) @map("max_attempts")
|
|
nextRetryAt DateTime? @map("next_retry_at")
|
|
lastStatusCode Int? @map("last_status_code")
|
|
lastResponseBody String? @map("last_response_body")
|
|
lastError String? @map("last_error")
|
|
providerType String @default("work_notice") @map("provider_type")
|
|
providerMessageId String? @map("provider_message_id")
|
|
readStatus String @default("unknown") @map("read_status")
|
|
readAt DateTime? @map("read_at")
|
|
readStatusCheckedAt DateTime? @map("read_status_checked_at")
|
|
sentAt DateTime? @map("sent_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
survey PerformanceSurvey? @relation(fields: [surveyId], references: [id], onDelete: Cascade)
|
|
target PerformanceSurveyTarget? @relation(fields: [targetId], references: [id], onDelete: Cascade)
|
|
assignment PerformanceSurveyAssignment? @relation(fields: [assignmentId], references: [id], onDelete: Cascade)
|
|
recipientEmployee PerformanceSurveyEmployeeProfile? @relation(fields: [recipientEmployeeId], references: [id])
|
|
|
|
@@unique([eventType, businessKey], map: "performance_survey_notification_event_key")
|
|
@@index([surveyId])
|
|
@@index([targetId])
|
|
@@index([assignmentId])
|
|
@@index([recipientEmployeeId])
|
|
@@index([recipientUserId])
|
|
@@index([dingtalkUserId])
|
|
@@index([status, nextRetryAt])
|
|
@@index([readStatus, readStatusCheckedAt], map: "performance_survey_notifications_read_status_checked_at_idx")
|
|
@@index([createdAt])
|
|
@@map("performance_survey_notifications")
|
|
}
|
|
|
|
model PerformanceSurveyConfigAuditLog {
|
|
id String @id @default(uuid())
|
|
action String
|
|
targetType String @map("target_type")
|
|
targetId String? @map("target_id")
|
|
actorUserId String @map("actor_user_id")
|
|
actorName String @map("actor_name")
|
|
reason String? @db.VarChar(500)
|
|
beforeSnapshot Json? @map("before_snapshot")
|
|
afterSnapshot Json? @map("after_snapshot")
|
|
metadata Json?
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@index([targetType, targetId, createdAt], map: "performance_survey_config_audit_target_idx")
|
|
@@index([actorUserId, createdAt], map: "performance_survey_config_audit_actor_idx")
|
|
@@index([createdAt], map: "performance_survey_config_audit_created_idx")
|
|
@@map("performance_survey_config_audit_logs")
|
|
}
|
|
|
|
model WorkReviewProject {
|
|
id String @id @default(uuid())
|
|
title String
|
|
description String?
|
|
workDate DateTime @db.Date @map("work_date")
|
|
submitterUserId String @map("submitter_user_id")
|
|
submitterEmployeeId String @map("submitter_employee_id")
|
|
submitterName String @map("submitter_name")
|
|
submitterSnapshot Json @map("submitter_snapshot")
|
|
managerEmployeeId String @map("manager_employee_id")
|
|
managerUserId String? @map("manager_user_id")
|
|
managerDingtalkUserId String? @map("manager_dingtalk_user_id")
|
|
managerName String @map("manager_name")
|
|
finalReviewerEmployeeId String @map("final_reviewer_employee_id")
|
|
finalReviewerUserId String? @map("final_reviewer_user_id")
|
|
finalReviewerDingtalkUserId String? @map("final_reviewer_dingtalk_user_id")
|
|
finalReviewerName String @map("final_reviewer_name")
|
|
status String @default("pending_review")
|
|
latestVersion Int @default(1) @map("latest_version")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
submitterEmployee PerformanceSurveyEmployeeProfile @relation("WorkReviewSubmitter", fields: [submitterEmployeeId], references: [id], onDelete: Restrict)
|
|
managerEmployee PerformanceSurveyEmployeeProfile @relation("WorkReviewManager", fields: [managerEmployeeId], references: [id], onDelete: Restrict)
|
|
finalReviewerEmployee PerformanceSurveyEmployeeProfile @relation("WorkReviewFinalReviewer", fields: [finalReviewerEmployeeId], references: [id], onDelete: Restrict)
|
|
versions WorkReviewVersion[]
|
|
notifications WorkReviewNotification[]
|
|
|
|
@@index([submitterUserId, workDate], map: "work_review_projects_submitter_date_idx")
|
|
@@index([submitterEmployeeId, workDate], map: "work_review_projects_submitter_employee_date_idx")
|
|
@@index([managerEmployeeId, status], map: "work_review_projects_manager_status_idx")
|
|
@@index([finalReviewerEmployeeId, status], map: "work_review_projects_final_reviewer_status_idx")
|
|
@@index([status, workDate], map: "work_review_projects_status_date_idx")
|
|
@@index([updatedAt], map: "work_review_projects_updated_at_idx")
|
|
@@map("work_review_projects")
|
|
}
|
|
|
|
model WorkReviewVersion {
|
|
id String @id @default(uuid())
|
|
projectId String @map("project_id")
|
|
version Int
|
|
submissionNote String? @map("submission_note")
|
|
imageUrls Json @map("image_urls")
|
|
status String @default("pending_review")
|
|
submittedAt DateTime @default(now()) @map("submitted_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
project WorkReviewProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
reviews WorkReviewReview[]
|
|
notifications WorkReviewNotification[]
|
|
|
|
@@unique([projectId, version], map: "work_review_versions_project_version_key")
|
|
@@index([projectId, submittedAt], map: "work_review_versions_project_submitted_idx")
|
|
@@index([status, submittedAt], map: "work_review_versions_status_submitted_idx")
|
|
@@map("work_review_versions")
|
|
}
|
|
|
|
model WorkReviewReview {
|
|
id String @id @default(uuid())
|
|
versionId String @map("version_id")
|
|
reviewerRole String @map("reviewer_role")
|
|
reviewerEmployeeId String @map("reviewer_employee_id")
|
|
reviewerUserId String? @map("reviewer_user_id")
|
|
reviewerName String @map("reviewer_name")
|
|
reviewerSnapshot Json @map("reviewer_snapshot")
|
|
decision String
|
|
imageComments Json @map("image_comments")
|
|
generalComment String? @map("general_comment")
|
|
reviewedAt DateTime @default(now()) @map("reviewed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
version WorkReviewVersion @relation(fields: [versionId], references: [id], onDelete: Cascade)
|
|
reviewerEmployee PerformanceSurveyEmployeeProfile @relation("WorkReviewReviewer", fields: [reviewerEmployeeId], references: [id], onDelete: Restrict)
|
|
|
|
@@unique([versionId, reviewerRole], map: "work_review_reviews_version_role_key")
|
|
@@index([reviewerEmployeeId, reviewedAt], map: "work_review_reviews_reviewer_reviewed_idx")
|
|
@@index([decision], map: "work_review_reviews_decision_idx")
|
|
@@map("work_review_reviews")
|
|
}
|
|
|
|
model WorkReviewNotification {
|
|
id String @id @default(uuid())
|
|
projectId String @map("project_id")
|
|
versionId String @map("version_id")
|
|
recipientEmployeeId String? @map("recipient_employee_id")
|
|
recipientUserId String? @map("recipient_user_id")
|
|
dingtalkUserId String? @map("dingtalk_user_id")
|
|
recipientName String @map("recipient_name")
|
|
eventType String @map("event_type")
|
|
businessKey String @map("business_key")
|
|
title String
|
|
content String
|
|
actionUrl String? @map("action_url")
|
|
status String @default("pending")
|
|
attemptCount Int @default(0) @map("attempt_count")
|
|
maxAttempts Int @default(5) @map("max_attempts")
|
|
nextRetryAt DateTime? @map("next_retry_at")
|
|
providerType String @default("work_notice") @map("provider_type")
|
|
providerMessageId String? @map("provider_message_id")
|
|
lastError String? @map("last_error")
|
|
sentAt DateTime? @map("sent_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
project WorkReviewProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
version WorkReviewVersion @relation(fields: [versionId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([eventType, businessKey], map: "work_review_notifications_event_key")
|
|
@@index([projectId, createdAt], map: "work_review_notifications_project_created_idx")
|
|
@@index([versionId], map: "work_review_notifications_version_idx")
|
|
@@index([recipientEmployeeId], map: "work_review_notifications_recipient_employee_idx")
|
|
@@index([recipientUserId], map: "work_review_notifications_recipient_user_idx")
|
|
@@index([dingtalkUserId], map: "work_review_notifications_dingtalk_user_idx")
|
|
@@index([status, nextRetryAt], map: "work_review_notifications_status_retry_idx")
|
|
@@map("work_review_notifications")
|
|
}
|
|
|
|
model VideoTranscodeProgress {
|
|
id String @id @default(uuid())
|
|
materialId String @map("material_id")
|
|
stage String
|
|
progress Int @default(0)
|
|
status String @default("waiting") @map("status")
|
|
priority Int @default(0)
|
|
startedAt DateTime @default(now()) @map("started_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
errorMessage String? @map("error_message")
|
|
retryCount Int @default(0) @map("retry_count")
|
|
lastHeartbeat DateTime? @map("last_heartbeat")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
material Material @relation("MaterialTranscodeProgress", fields: [materialId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([materialId, stage])
|
|
@@index([status])
|
|
@@index([priority, status])
|
|
@@index([materialId])
|
|
@@index([lastHeartbeat])
|
|
@@map("video_transcode_progresses")
|
|
}
|
|
|
|
enum Role {
|
|
USER
|
|
ADMIN
|
|
DEPT_ADMIN
|
|
SYSTEM_ADMIN
|
|
}
|