完善借款、编号、付款与预算并发及验收(09-06-release-gate-integrity)
汇总已落盘的借款本金与还款、兼容历史编号的周期化编号、付款责任与回单核验、报销进度和排序、PWA/采购事务、错误原因与日期校验及ERP退役。 统一共享预算池锁序和锁后判断,恢复差旅原预算选择,补原因码固定夹具及反向完整性检查。 纳入配套迁移、测试、受管QA、分层验收合同、规约及任务记录;原始证据留在ignored artifacts。 关联任务:09-17-company-loan-principal-repayment、09-17-erp-exclusive-retirement、09-18-reimbursement-periodic-numbering、09-08-reimbursement-payment-closeout、09-18-local-concurrency-product-fixes、09-19-budget-pool-concurrency、09-05-error-explainability-payment-readiness。 预算补审由Claude定向验证2文件928项通过,原4446/28及r6结果仍仅对应各自历史输入;本轮未重跑测试。 完整新候选门禁、R1真实入口接入与12项公网义务仍开放。生产编号未启用、差旅仍冻结;不推送、不部署,不宣称发布资格。
这个提交包含在:
@@ -273,6 +273,7 @@ enum PaymentBatchStatus {
|
||||
enum PaymentBatchEntityType {
|
||||
reimbursement
|
||||
travel_order
|
||||
loan_repayment
|
||||
}
|
||||
|
||||
enum BudgetControlRuleEntityType {
|
||||
@@ -731,6 +732,9 @@ model Employee {
|
||||
@@index([legal_entity_id], map: "idx_employees_legal_entity")
|
||||
@@index([bank_institution_id], map: "idx_employees_bank_institution")
|
||||
@@index([direct_manager_id])
|
||||
loan_lender_identities LoanLender[]
|
||||
loan_evidence_uploads LoanEvidence[]
|
||||
|
||||
@@map("employees")
|
||||
}
|
||||
|
||||
@@ -949,6 +953,26 @@ model ReimbursementTemplate {
|
||||
@@map("reimbursement_templates")
|
||||
}
|
||||
|
||||
// Absent policy means legacy numbering. Migration never activates v2.
|
||||
model BusinessNumberPolicy {
|
||||
version Int @id
|
||||
effective_at DateTime
|
||||
enabled Boolean @default(false)
|
||||
updated_at DateTime @default(now()) @updatedAt
|
||||
updated_by String @db.Uuid
|
||||
reference String
|
||||
|
||||
@@map("business_number_policies")
|
||||
}
|
||||
|
||||
model BusinessNumberCounter {
|
||||
key String @id
|
||||
current_number BigInt @default(0)
|
||||
updated_at DateTime @default(now()) @updatedAt
|
||||
|
||||
@@map("business_number_counters")
|
||||
}
|
||||
|
||||
model DocumentSequence {
|
||||
document_type String @id
|
||||
prefix String
|
||||
@@ -997,6 +1021,8 @@ model LegalEntity {
|
||||
|
||||
@@index([enabled, archived_at], map: "idx_legal_entities_status")
|
||||
@@index([default_holiday_calendar_id], map: "idx_legal_entities_default_calendar")
|
||||
loan_lenders LoanLender[]
|
||||
|
||||
@@map("legal_entities")
|
||||
}
|
||||
|
||||
@@ -1016,6 +1042,8 @@ model BankInstitution {
|
||||
payment_accounts PaymentAccount[]
|
||||
|
||||
@@index([enabled, archived_at], map: "idx_bank_institutions_status")
|
||||
loan_lenders LoanLender[]
|
||||
|
||||
@@map("bank_institutions")
|
||||
}
|
||||
|
||||
@@ -1168,6 +1196,7 @@ model Supplier {
|
||||
}
|
||||
|
||||
model PurchaseRequest {
|
||||
numbering_version Int @default(1)
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
request_no String? @unique
|
||||
applicant_id String @db.Uuid
|
||||
@@ -1901,6 +1930,8 @@ model EntityRiskFlag {
|
||||
}
|
||||
|
||||
model PaymentBatch {
|
||||
loan_repayment_id String? @db.Uuid
|
||||
loan_repayment LoanRepayment? @relation(fields: [loan_repayment_id], references: [id], onDelete: Restrict)
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
batch_no String @unique @db.VarChar(64)
|
||||
entity_type PaymentBatchEntityType
|
||||
@@ -3809,3 +3840,142 @@ model ApprovalTransfer {
|
||||
@@index([to_approver_id])
|
||||
@@map("approval_transfers")
|
||||
}
|
||||
|
||||
|
||||
model LoanLender {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
legal_entity_id String @db.Uuid
|
||||
name String @db.VarChar(120)
|
||||
employee_id String? @db.Uuid
|
||||
identity_status String @default("unverified") @db.VarChar(16)
|
||||
identity_version Int @default(1)
|
||||
account_version Int @default(1)
|
||||
identity_confirmed_by String? @db.Uuid
|
||||
identity_confirmed_at DateTime?
|
||||
identity_confirmation String?
|
||||
bank_institution_id String @db.Uuid
|
||||
bank_name String @db.VarChar(200)
|
||||
bank_account_encrypted String
|
||||
account_name_encrypted String
|
||||
archived_at DateTime?
|
||||
created_at DateTime @default(now())
|
||||
created_by String @db.Uuid
|
||||
updated_at DateTime @updatedAt
|
||||
updated_by String @db.Uuid
|
||||
request_key String @db.Uuid
|
||||
|
||||
legal_entity LegalEntity @relation(fields: [legal_entity_id], references: [id], onDelete: Restrict)
|
||||
employee Employee? @relation(fields: [employee_id], references: [id], onDelete: Restrict)
|
||||
bank_institution BankInstitution @relation(fields: [bank_institution_id], references: [id], onDelete: Restrict)
|
||||
loans CompanyLoan[]
|
||||
repayments LoanRepayment[]
|
||||
|
||||
@@unique([legal_entity_id, id])
|
||||
@@unique([created_by, request_key])
|
||||
@@index([employee_id])
|
||||
@@map("loan_lenders")
|
||||
}
|
||||
|
||||
model CompanyLoan {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
loan_no String @unique @db.VarChar(64)
|
||||
origin_reference String @db.VarChar(200)
|
||||
legal_entity_id String @db.Uuid
|
||||
lender_id String @db.Uuid
|
||||
currency_code String @default("CNY") @db.VarChar(8)
|
||||
original_principal Decimal @db.Decimal(14, 2)
|
||||
opening_outstanding_principal Decimal @db.Decimal(14, 2)
|
||||
received_date DateTime @db.Date
|
||||
balance_as_of DateTime @db.Date
|
||||
historical_entry Boolean
|
||||
confirmation_status String @default("unconfirmed") @db.VarChar(16)
|
||||
version Int @default(1)
|
||||
confirmed_by String? @db.Uuid
|
||||
confirmed_at DateTime?
|
||||
accounting_confirmation_ref String? @db.VarChar(200)
|
||||
created_at DateTime @default(now())
|
||||
created_by String @db.Uuid
|
||||
updated_at DateTime @updatedAt
|
||||
updated_by String @db.Uuid
|
||||
request_key String @db.Uuid
|
||||
|
||||
lender LoanLender @relation(fields: [legal_entity_id, lender_id], references: [legal_entity_id, id], onDelete: Restrict)
|
||||
allocations LoanRepaymentAllocation[]
|
||||
evidences LoanEvidence[]
|
||||
|
||||
@@unique([created_by, request_key])
|
||||
@@unique([legal_entity_id, lender_id, origin_reference])
|
||||
@@index([lender_id, confirmation_status, received_date])
|
||||
@@map("company_loans")
|
||||
}
|
||||
|
||||
model LoanRepayment {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
repayment_no String @unique @db.VarChar(64)
|
||||
legal_entity_id String @db.Uuid
|
||||
lender_id String @db.Uuid
|
||||
currency_code String @default("CNY") @db.VarChar(8)
|
||||
reason String @db.VarChar(500)
|
||||
amount Decimal @db.Decimal(14, 2)
|
||||
version Int @default(1)
|
||||
submitted_by String @db.Uuid
|
||||
submitted_at DateTime @default(now())
|
||||
lender_identity_version Int
|
||||
lender_account_version Int
|
||||
payee_snapshot_json Json
|
||||
bank_result_state String @default("not_sent") @db.VarChar(24)
|
||||
bank_result_ref String? @db.VarChar(500)
|
||||
accounting_handoff_by String? @db.Uuid
|
||||
accounting_handoff_at DateTime?
|
||||
accounting_handoff_ref String? @db.VarChar(200)
|
||||
request_key String @db.Uuid
|
||||
|
||||
lender LoanLender @relation(fields: [legal_entity_id, lender_id], references: [legal_entity_id, id], onDelete: Restrict)
|
||||
allocations LoanRepaymentAllocation[]
|
||||
batches PaymentBatch[]
|
||||
|
||||
@@unique([submitted_by, request_key])
|
||||
@@index([lender_id, submitted_at])
|
||||
@@map("loan_repayments")
|
||||
}
|
||||
|
||||
model LoanRepaymentAllocation {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
repayment_id String @db.Uuid
|
||||
loan_id String @db.Uuid
|
||||
amount Decimal @db.Decimal(14, 2)
|
||||
loan_version Int
|
||||
reservation_state String @default("reserved") @db.VarChar(16)
|
||||
settled_at DateTime?
|
||||
released_at DateTime?
|
||||
release_reason String? @db.VarChar(500)
|
||||
|
||||
repayment LoanRepayment @relation(fields: [repayment_id], references: [id], onDelete: Restrict)
|
||||
loan CompanyLoan @relation(fields: [loan_id], references: [id], onDelete: Restrict)
|
||||
|
||||
@@unique([repayment_id, loan_id])
|
||||
@@index([loan_id, reservation_state])
|
||||
@@map("loan_repayment_allocations")
|
||||
}
|
||||
|
||||
model LoanEvidence {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
loan_id String @db.Uuid
|
||||
kind String @db.VarChar(32)
|
||||
original_name String @db.VarChar(255)
|
||||
storage_path String
|
||||
mime_type String @db.VarChar(100)
|
||||
file_size Int
|
||||
file_sha256 String @db.VarChar(64)
|
||||
governance_status String @default("pending") @db.VarChar(16)
|
||||
uploaded_by String @db.Uuid
|
||||
uploaded_at DateTime @default(now())
|
||||
archived_at DateTime?
|
||||
archive_reason String? @db.VarChar(500)
|
||||
|
||||
loan CompanyLoan @relation(fields: [loan_id], references: [id], onDelete: Restrict)
|
||||
uploader Employee @relation(fields: [uploaded_by], references: [id], onDelete: Restrict)
|
||||
|
||||
@@unique([loan_id, file_sha256, kind])
|
||||
@@map("loan_evidences")
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户