- workflow_instances 解耦 reimbursement FK:新增 reimbursement_id/leave_request_id + 回填迁移 - 新增 leave_requests 表与 /api/leave-requests 最小链路(create/submit) - workflow approve/reject/return 支持 leave 状态更新;transfer 非报销任务禁用 - seed-config 增加 leave workflow definition;更新 v3 CSV 状态推进
678 行
21 KiB
Plaintext
678 行
21 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
}
|
|
|
|
enum RoleCode {
|
|
employee
|
|
manager
|
|
ceo
|
|
finance
|
|
finance_mgr
|
|
administration
|
|
hr
|
|
admin
|
|
}
|
|
|
|
enum EmployeeStatus {
|
|
active
|
|
archived
|
|
}
|
|
|
|
enum DelegationGrantScope {
|
|
reimbursement_submit
|
|
all
|
|
}
|
|
|
|
enum ReimbursementStatus {
|
|
draft
|
|
reviewing
|
|
approved
|
|
paid
|
|
rejected
|
|
cancelled
|
|
}
|
|
|
|
enum LeaveRequestStatus {
|
|
draft
|
|
reviewing
|
|
approved
|
|
rejected
|
|
cancelled
|
|
}
|
|
|
|
enum InvoicePoolStatus {
|
|
pending_ocr
|
|
ocr_failed
|
|
available
|
|
bound
|
|
archived
|
|
}
|
|
|
|
enum InvoiceArchivedReason {
|
|
used_complete
|
|
unused_timeout
|
|
manual
|
|
}
|
|
|
|
enum OcrProvider {
|
|
tencent
|
|
}
|
|
|
|
enum OcrType {
|
|
vat
|
|
train
|
|
flight
|
|
taxi
|
|
general
|
|
}
|
|
|
|
enum DocumentResetPeriod {
|
|
none
|
|
daily
|
|
monthly
|
|
yearly
|
|
}
|
|
|
|
enum WorkflowInstanceStatus {
|
|
pending
|
|
approved
|
|
rejected
|
|
cancelled
|
|
terminated
|
|
}
|
|
|
|
enum WorkflowTaskStatus {
|
|
pending
|
|
completed
|
|
rejected
|
|
cancelled
|
|
skipped
|
|
}
|
|
|
|
enum WorkflowTaskOutcome {
|
|
approved
|
|
rejected
|
|
returned
|
|
start
|
|
transfer
|
|
skipped
|
|
}
|
|
|
|
enum ApprovalTransferStatus {
|
|
active
|
|
cancelled
|
|
}
|
|
|
|
enum ExpenseCategory {
|
|
travel
|
|
rd
|
|
production
|
|
office
|
|
business
|
|
assets
|
|
other
|
|
}
|
|
|
|
model Department {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
name String
|
|
parent_id String? @db.Uuid
|
|
archived_at DateTime?
|
|
archived_by String? @db.Uuid
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
parent Department? @relation("DepartmentToParent", fields: [parent_id], references: [id], onDelete: Restrict)
|
|
children Department[] @relation("DepartmentToParent")
|
|
|
|
employees Employee[]
|
|
reimbursement_forms ReimbursementForm[]
|
|
leave_requests LeaveRequest[]
|
|
workflow_instances WorkflowInstance[]
|
|
|
|
@@index([parent_id])
|
|
@@map("departments")
|
|
}
|
|
|
|
model Employee {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
employee_no String @unique
|
|
name String
|
|
phone String @unique
|
|
email String @unique
|
|
department_id String @db.Uuid
|
|
title String
|
|
direct_manager_id String? @db.Uuid
|
|
hire_date DateTime @db.Date
|
|
status EmployeeStatus @default(active)
|
|
|
|
bank_account_encrypted String
|
|
bank_name String
|
|
id_number_encrypted String?
|
|
|
|
password_hash String
|
|
token_version Int @default(0)
|
|
must_change_password Boolean @default(false)
|
|
login_failed_count Int @default(0)
|
|
login_failed_first_at DateTime?
|
|
login_locked_until DateTime?
|
|
archived_at DateTime?
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
department Department @relation(fields: [department_id], references: [id], onDelete: Restrict)
|
|
direct_manager Employee? @relation("EmployeeToManager", fields: [direct_manager_id], references: [id], onDelete: Restrict)
|
|
subordinates Employee[] @relation("EmployeeToManager")
|
|
|
|
roles EmployeeRole[]
|
|
|
|
delegation_grants_as_principal DelegationGrant[] @relation("DelegationPrincipal")
|
|
delegation_grants_as_delegate DelegationGrant[] @relation("DelegationDelegate")
|
|
|
|
auth_sessions AuthSession[]
|
|
audit_logs AuditLog[] @relation("AuditActor")
|
|
notifications Notification[]
|
|
|
|
submitted_reimbursements ReimbursementForm[] @relation("ReimbursementSubmitter")
|
|
owned_reimbursements ReimbursementForm[] @relation("ReimbursementOwner")
|
|
paid_reimbursements ReimbursementForm[] @relation("ReimbursementPaidBy")
|
|
leave_requests LeaveRequest[]
|
|
|
|
owned_invoices InvoicePool[] @relation("InvoiceOwner")
|
|
uploaded_invoices InvoicePool[] @relation("InvoiceUploader")
|
|
overridden_invoices InvoicePool[] @relation("InvoiceOverrideBy")
|
|
|
|
workflow_instances_started WorkflowInstance[] @relation("WorkflowInstanceSubmitter")
|
|
workflow_history_actions WorkflowHistory[] @relation("WorkflowHistoryActor")
|
|
workflow_tasks_assigned WorkflowTask[] @relation("WorkflowTaskAssignee")
|
|
workflow_tasks_completed WorkflowTask[] @relation("WorkflowTaskCompleter")
|
|
|
|
approval_transfers_from ApprovalTransfer[] @relation("TransferFrom")
|
|
approval_transfers_to ApprovalTransfer[] @relation("TransferTo")
|
|
password_reset_codes PasswordResetCode[]
|
|
|
|
@@index([department_id])
|
|
@@index([direct_manager_id])
|
|
@@map("employees")
|
|
}
|
|
|
|
model PasswordResetCode {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
employee_id String @db.Uuid
|
|
code_hash String
|
|
expires_at DateTime
|
|
used_at DateTime?
|
|
created_at DateTime @default(now())
|
|
created_ip String?
|
|
created_user_agent String?
|
|
|
|
employee Employee @relation(fields: [employee_id], references: [id], onDelete: Cascade)
|
|
|
|
@@index([employee_id, created_at])
|
|
@@index([expires_at])
|
|
@@map("password_reset_codes")
|
|
}
|
|
|
|
model EmployeeRole {
|
|
employee_id String @db.Uuid
|
|
role_code RoleCode
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
|
|
employee Employee @relation(fields: [employee_id], references: [id], onDelete: Cascade)
|
|
|
|
@@id([employee_id, role_code])
|
|
@@map("employee_roles")
|
|
}
|
|
|
|
model DelegationGrant {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
principal_employee_id String @db.Uuid
|
|
delegate_employee_id String @db.Uuid
|
|
scope DelegationGrantScope
|
|
valid_from DateTime @default(now())
|
|
valid_to DateTime?
|
|
revoked_at DateTime?
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
|
|
principal_employee Employee @relation("DelegationPrincipal", fields: [principal_employee_id], references: [id], onDelete: Restrict)
|
|
delegate_employee Employee @relation("DelegationDelegate", fields: [delegate_employee_id], references: [id], onDelete: Restrict)
|
|
|
|
@@index([principal_employee_id])
|
|
@@index([delegate_employee_id])
|
|
@@map("delegation_grants")
|
|
}
|
|
|
|
model AuthSession {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
employee_id String @db.Uuid
|
|
refresh_token_hash String
|
|
device_fingerprint String
|
|
ip_address String
|
|
user_agent String
|
|
created_at DateTime @default(now())
|
|
last_seen_at DateTime @default(now())
|
|
expires_at DateTime
|
|
revoked_at DateTime?
|
|
|
|
employee Employee @relation(fields: [employee_id], references: [id], onDelete: Cascade)
|
|
|
|
@@index([employee_id])
|
|
@@index([expires_at])
|
|
@@index([revoked_at])
|
|
@@map("auth_sessions")
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
request_id String
|
|
actor_id String @db.Uuid
|
|
action String
|
|
target_type String
|
|
target_id String? @db.Uuid
|
|
ip_address String?
|
|
user_agent String?
|
|
extra Json
|
|
created_at DateTime @default(now())
|
|
|
|
actor Employee @relation("AuditActor", fields: [actor_id], references: [id], onDelete: Restrict)
|
|
|
|
@@index([request_id])
|
|
@@index([actor_id, created_at])
|
|
@@index([created_at, actor_id, action], map: "idx_audit_logs_query")
|
|
@@index([target_type, created_at], map: "idx_audit_logs_target_type_created_at")
|
|
@@map("audit_logs")
|
|
}
|
|
|
|
model Notification {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
recipient_employee_id String @db.Uuid
|
|
type String @db.VarChar(64)
|
|
title String @db.VarChar(200)
|
|
body String?
|
|
target_type String? @db.VarChar(64)
|
|
target_id String? @db.Uuid
|
|
read_at DateTime?
|
|
created_at DateTime @default(now())
|
|
|
|
recipient Employee @relation(fields: [recipient_employee_id], references: [id], onDelete: Cascade)
|
|
|
|
@@index([recipient_employee_id, created_at])
|
|
@@index([recipient_employee_id, read_at, created_at], map: "idx_notifications_unread_query")
|
|
@@map("notifications")
|
|
}
|
|
|
|
model ExpenseType {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
code String @unique
|
|
name String
|
|
description String?
|
|
category ExpenseCategory
|
|
sort_order Int
|
|
account_code_default String?
|
|
is_system_default Boolean @default(false)
|
|
enabled Boolean @default(true)
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
reimbursement_items ReimbursementItem[]
|
|
|
|
@@index([enabled, sort_order])
|
|
@@map("expense_types")
|
|
}
|
|
|
|
model DocumentSequence {
|
|
document_type String @id
|
|
prefix String
|
|
date_format String
|
|
separator String
|
|
number_length Int @default(4)
|
|
reset_period DocumentResetPeriod
|
|
current_number Int @default(0)
|
|
last_reset_date DateTime?
|
|
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
@@map("document_sequences")
|
|
}
|
|
|
|
model ReimbursementForm {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
form_number String? @unique
|
|
submitter_id String @db.Uuid
|
|
owner_id String @db.Uuid
|
|
department_id String @db.Uuid
|
|
reimbursement_date DateTime @db.Date
|
|
total_amount Decimal @default(0) @db.Decimal(14, 2)
|
|
status ReimbursementStatus @default(draft)
|
|
description String?
|
|
payment_voucher_no String? @db.VarChar(50)
|
|
payment_date DateTime? @db.Date
|
|
payment_channel String? @db.VarChar(20)
|
|
paid_at DateTime?
|
|
paid_by String? @db.Uuid
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
submitter Employee @relation("ReimbursementSubmitter", fields: [submitter_id], references: [id], onDelete: Restrict)
|
|
owner Employee @relation("ReimbursementOwner", fields: [owner_id], references: [id], onDelete: Restrict)
|
|
paid_by_employee Employee? @relation("ReimbursementPaidBy", fields: [paid_by], references: [id], onDelete: SetNull)
|
|
department Department @relation(fields: [department_id], references: [id], onDelete: Restrict)
|
|
|
|
items ReimbursementItem[]
|
|
invoice_pool_items InvoicePool[]
|
|
workflow_instances WorkflowInstance[]
|
|
approval_transfers ApprovalTransfer[]
|
|
|
|
@@index([owner_id])
|
|
@@index([submitter_id])
|
|
@@index([department_id])
|
|
@@index([paid_by])
|
|
@@index([status])
|
|
@@index([reimbursement_date])
|
|
@@index([owner_id, status, updated_at], map: "idx_reimbursement_owner_status_updated_at")
|
|
@@map("reimbursement_forms")
|
|
}
|
|
|
|
model ReimbursementItem {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
reimbursement_id String @db.Uuid
|
|
expense_type_id String @db.Uuid
|
|
expense_date DateTime @db.Date
|
|
amount Decimal @db.Decimal(14, 2)
|
|
description String
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
reimbursement_form ReimbursementForm @relation(fields: [reimbursement_id], references: [id], onDelete: Cascade)
|
|
expense_type ExpenseType @relation(fields: [expense_type_id], references: [id], onDelete: Restrict)
|
|
|
|
invoice_pool_items InvoicePool[]
|
|
|
|
@@index([reimbursement_id])
|
|
@@index([expense_type_id])
|
|
@@index([expense_date])
|
|
@@map("reimbursement_items")
|
|
}
|
|
|
|
model LeaveRequest {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
owner_id String @db.Uuid
|
|
department_id String @db.Uuid
|
|
start_date DateTime @db.Date
|
|
end_date DateTime @db.Date
|
|
reason String?
|
|
status LeaveRequestStatus @default(draft)
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
owner Employee @relation(fields: [owner_id], references: [id], onDelete: Restrict)
|
|
department Department @relation(fields: [department_id], references: [id], onDelete: Restrict)
|
|
|
|
workflow_instances WorkflowInstance[]
|
|
|
|
@@index([owner_id])
|
|
@@index([department_id])
|
|
@@index([status])
|
|
@@index([owner_id, status, updated_at], map: "idx_leave_owner_status_updated_at")
|
|
@@map("leave_requests")
|
|
}
|
|
|
|
model OcrResult {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
file_sha256 String
|
|
ocr_provider OcrProvider @default(tencent)
|
|
ocr_type OcrType
|
|
result_json Json
|
|
confidence Int?
|
|
created_at DateTime @default(now())
|
|
|
|
invoice_pool_items InvoicePool[]
|
|
|
|
@@unique([file_sha256, ocr_provider, ocr_type])
|
|
@@index([file_sha256])
|
|
@@map("ocr_results")
|
|
}
|
|
|
|
model InvoicePool {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
owner_employee_id String @db.Uuid
|
|
uploaded_by_employee_id String @db.Uuid
|
|
storage_path String
|
|
original_name String
|
|
mime_type String
|
|
file_size Int
|
|
file_sha256 String
|
|
|
|
status InvoicePoolStatus @default(pending_ocr)
|
|
archived_reason InvoiceArchivedReason?
|
|
archived_at DateTime?
|
|
|
|
linked_reimbursement_id String? @db.Uuid
|
|
linked_item_id String? @db.Uuid
|
|
remarks String?
|
|
|
|
ocr_provider OcrProvider @default(tencent)
|
|
ocr_type OcrType @default(general)
|
|
ocr_result_id String? @db.Uuid
|
|
ocr_attempts Int @default(0)
|
|
ocr_last_requested_at DateTime?
|
|
ocr_last_error String?
|
|
ocr_completed_at DateTime?
|
|
ocr_locked_at DateTime?
|
|
ocr_lock_owner String? @db.VarChar(128)
|
|
|
|
invoice_code String?
|
|
invoice_number String?
|
|
invoice_date DateTime? @db.Date
|
|
seller_name String?
|
|
buyer_name String?
|
|
amount Decimal? @db.Decimal(14, 2)
|
|
tax_amount Decimal? @db.Decimal(14, 2)
|
|
total_amount Decimal? @db.Decimal(14, 2)
|
|
|
|
is_duplicate_override Boolean @default(false)
|
|
override_ref_form_number String?
|
|
override_reason String?
|
|
overridden_by String? @db.Uuid
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
owner_employee Employee @relation("InvoiceOwner", fields: [owner_employee_id], references: [id], onDelete: Restrict)
|
|
uploaded_by_employee Employee @relation("InvoiceUploader", fields: [uploaded_by_employee_id], references: [id], onDelete: Restrict)
|
|
overridden_by_employee Employee? @relation("InvoiceOverrideBy", fields: [overridden_by], references: [id], onDelete: Restrict)
|
|
|
|
ocr_result OcrResult? @relation(fields: [ocr_result_id], references: [id], onDelete: SetNull)
|
|
linked_reimbursement ReimbursementForm? @relation(fields: [linked_reimbursement_id], references: [id], onDelete: SetNull)
|
|
linked_item ReimbursementItem? @relation(fields: [linked_item_id], references: [id], onDelete: SetNull)
|
|
|
|
@@index([owner_employee_id])
|
|
@@index([uploaded_by_employee_id])
|
|
@@index([file_sha256])
|
|
@@index([invoice_code, invoice_number])
|
|
@@index([status])
|
|
@@index([status, ocr_locked_at, created_at], map: "idx_invoice_pool_ocr_queue")
|
|
@@index([owner_employee_id, status, created_at], map: "idx_invoice_pool_owner_status_created_at")
|
|
@@index([linked_reimbursement_id])
|
|
@@map("invoice_pool")
|
|
}
|
|
|
|
model WorkflowDefinition {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
name String
|
|
entity_type String
|
|
definition_json Json
|
|
version Int
|
|
is_active Boolean @default(true)
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
|
|
workflow_instances WorkflowInstance[]
|
|
|
|
@@unique([entity_type, version])
|
|
@@index([entity_type, is_active])
|
|
@@map("workflow_definitions")
|
|
}
|
|
|
|
model WorkflowInstance {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
workflow_id String @db.Uuid
|
|
entity_type String
|
|
entity_id String @db.Uuid
|
|
reimbursement_id String? @db.Uuid
|
|
leave_request_id String? @db.Uuid
|
|
submitter_id String @db.Uuid
|
|
current_status WorkflowInstanceStatus @default(pending)
|
|
current_step_id String
|
|
context_data Json
|
|
started_at DateTime @default(now())
|
|
completed_at DateTime?
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
workflow_definition WorkflowDefinition @relation(fields: [workflow_id], references: [id], onDelete: Restrict)
|
|
reimbursement_form ReimbursementForm? @relation(fields: [reimbursement_id], references: [id], onDelete: Cascade)
|
|
leave_request LeaveRequest? @relation(fields: [leave_request_id], references: [id], onDelete: Cascade)
|
|
submitter Employee @relation("WorkflowInstanceSubmitter", fields: [submitter_id], references: [id], onDelete: Restrict)
|
|
department Department? @relation(fields: [context_department_id], references: [id], onDelete: SetNull)
|
|
|
|
workflow_tasks WorkflowTask[]
|
|
workflow_history WorkflowHistory[]
|
|
|
|
/// Denormalized for fast filtering (must match context_data.department_id)
|
|
context_department_id String? @db.Uuid
|
|
|
|
@@index([workflow_id])
|
|
@@index([entity_type, entity_id])
|
|
@@index([reimbursement_id])
|
|
@@index([leave_request_id])
|
|
@@index([current_status])
|
|
@@index([submitter_id])
|
|
@@index([context_department_id])
|
|
@@map("workflow_instances")
|
|
}
|
|
|
|
model WorkflowTask {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
instance_id String @db.Uuid
|
|
step_id String
|
|
step_name String
|
|
assignee_id String? @db.Uuid
|
|
assignee_role RoleCode?
|
|
status WorkflowTaskStatus @default(pending)
|
|
outcome WorkflowTaskOutcome?
|
|
comment String?
|
|
due_date DateTime?
|
|
created_at DateTime @default(now())
|
|
completed_at DateTime?
|
|
completed_by String? @db.Uuid
|
|
|
|
workflow_instance WorkflowInstance @relation(fields: [instance_id], references: [id], onDelete: Cascade)
|
|
assignee_employee Employee? @relation("WorkflowTaskAssignee", fields: [assignee_id], references: [id], onDelete: SetNull)
|
|
completer_employee Employee? @relation("WorkflowTaskCompleter", fields: [completed_by], references: [id], onDelete: SetNull)
|
|
|
|
workflow_history WorkflowHistory[]
|
|
|
|
@@index([instance_id])
|
|
@@index([status])
|
|
@@index([assignee_id])
|
|
@@index([assignee_role])
|
|
@@index([status, assignee_id, assignee_role], map: "idx_workflow_tasks_status_assignee")
|
|
@@index([status, assignee_id, created_at], map: "idx_workflow_tasks_status_assignee_id_created_at")
|
|
@@index([status, assignee_role, created_at], map: "idx_workflow_tasks_status_assignee_role_created_at")
|
|
@@map("workflow_tasks")
|
|
}
|
|
|
|
model WorkflowHistory {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
instance_id String @db.Uuid
|
|
task_id String? @db.Uuid
|
|
actor_id String @db.Uuid
|
|
action String
|
|
comment String?
|
|
payload Json?
|
|
created_at DateTime @default(now())
|
|
|
|
workflow_instance WorkflowInstance @relation(fields: [instance_id], references: [id], onDelete: Cascade)
|
|
workflow_task WorkflowTask? @relation(fields: [task_id], references: [id], onDelete: SetNull)
|
|
actor Employee @relation("WorkflowHistoryActor", fields: [actor_id], references: [id], onDelete: Restrict)
|
|
|
|
@@index([instance_id, created_at])
|
|
@@index([task_id])
|
|
@@index([actor_id])
|
|
@@map("workflow_history")
|
|
}
|
|
|
|
model ApprovalRule {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
name String
|
|
min_amount Decimal @db.Decimal(14, 2)
|
|
max_amount Decimal? @db.Decimal(14, 2)
|
|
level1_role RoleCode
|
|
level2_role RoleCode?
|
|
level3_role RoleCode?
|
|
enabled Boolean @default(true)
|
|
priority Int
|
|
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
updated_at DateTime @updatedAt
|
|
updated_by String? @db.Uuid
|
|
|
|
@@index([enabled, priority])
|
|
@@map("approval_rules")
|
|
}
|
|
|
|
model ApprovalTransfer {
|
|
id String @id @default(uuid()) @db.Uuid
|
|
reimbursement_id String @db.Uuid
|
|
from_approver_id String @db.Uuid
|
|
to_approver_id String @db.Uuid
|
|
reason String
|
|
status ApprovalTransferStatus @default(active)
|
|
created_at DateTime @default(now())
|
|
created_by String? @db.Uuid
|
|
|
|
reimbursement_form ReimbursementForm @relation(fields: [reimbursement_id], references: [id], onDelete: Cascade)
|
|
from_approver Employee @relation("TransferFrom", fields: [from_approver_id], references: [id], onDelete: Restrict)
|
|
to_approver Employee @relation("TransferTo", fields: [to_approver_id], references: [id], onDelete: Restrict)
|
|
|
|
@@index([reimbursement_id])
|
|
@@index([from_approver_id])
|
|
@@index([to_approver_id])
|
|
@@map("approval_transfers")
|
|
}
|