追回证据刷新期间禁用选择并修复员工资料登录误报(09-17-company-loan-principal-repayment)
- 上传银行证据后、刷新完成前,证据下拉框与确认按钮禁用并提示,避免空证据提交 - 员工来源版本去掉 updated_at(登录会刷新),保留全部真实资料字段的拦截 - 补登录误报回归、字段变更拦截、两项变异及刷新挂起的浏览器检查 - 任务记录 E 节与 AC52–55,独立只读复核无阻断项 Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -42,7 +42,7 @@ async function assertUniqueEmployeeLender(tx, employeeId, legalEntityId, lenderI
|
||||
|
||||
async function readEmployeeSource(db, config, employeeId, legalEntityId) {
|
||||
const employee = await db.employee.findUnique({ where: { id: employeeId }, select: {
|
||||
id: true, name: true, employee_no: true, legal_entity_id: true, status: true, archived_at: true, updated_at: true,
|
||||
id: true, name: true, employee_no: true, legal_entity_id: true, status: true, archived_at: true,
|
||||
bank_name: true, bank_institution_id: true, bank_account_encrypted: true,
|
||||
legal_entity: { select: { name: true } },
|
||||
bank_institution: { select: { id: true, code: true, name: true, enabled: true, archived_at: true } },
|
||||
@@ -67,10 +67,13 @@ async function readEmployeeSource(db, config, employeeId, legalEntityId) {
|
||||
else if (!/^\d{10,30}$/.test(bankAccount)) problems.push("account_invalid");
|
||||
} catch { problems.push("account_unavailable"); }
|
||||
}
|
||||
// Bind to all source fields, not just the millisecond timestamp. Ciphertext is
|
||||
// hashed without exposing it or making a plaintext account hash enumerable.
|
||||
// Bind to every mutable employee field the preview shows or the save copies
|
||||
// (employee_no is immutable in the database). updated_at is left out: a
|
||||
// successful login resets the failure counters and touches it without
|
||||
// changing any of these. Ciphertext is hashed without exposing it or making
|
||||
// a plaintext account hash enumerable.
|
||||
const sourceVersion = createHash("sha256").update(JSON.stringify([
|
||||
"loan-employee-source-v1", legalEntityId, employee.id, employee.updated_at,
|
||||
"loan-employee-source-v2", legalEntityId, employee.id,
|
||||
employee.name, employee.legal_entity_id, employee.status, employee.archived_at,
|
||||
employee.bank_name, employee.bank_institution_id, employee.bank_account_encrypted, bank,
|
||||
])).digest("hex");
|
||||
|
||||
在新工单中引用
屏蔽一个用户