补齐借款对账界面验收并记录 S0 只读核实(09-17-company-loan-principal-repayment)
电脑和手机覆盖提交清单、失败归属、晚到补记、部分及全额追回和有依据的误报关闭;不修改应用业务代码。最终隔离验证 81 迁移、HTTP 95、浏览器 19、数据库约束 9 组通过,脚本和治理检查通过。 获准只读核实:生产 OA 借款模块当前无记录,已应用 73 个迁移与本地校验值一致,待执行 8 个;不证明银行或线下没有付款。记录迁移差集、发布步骤和回退边界。 人员、银行材料、真实样本及业务独立验收待完成;正式发布门禁尚未运行。本次仅本地提交,不推送、不部署。
这个提交包含在:
@@ -1301,6 +1301,33 @@ module.exports = async function runLoanHttpFixture(pool, scratch) {
|
||||
}
|
||||
(recovery ? reconciliationUi.recoveryBatches : reconciliationUi.terminalBatches).push({ id: batch.id, instruction: ref });
|
||||
}
|
||||
reconciliationUi.failures = []; reconciliationUi.late = [];
|
||||
for (const mode of ['desktop', 'mobile']) {
|
||||
const failLender = await verifiedLender(`合成失败界面-${mode}`, null, '7');
|
||||
const failLoan = await confirmedLoan(failLender.id, '100.00', `合成失败归属-${mode}`);
|
||||
const target = await repay(failLender.id, failLoan.id, '7.00');
|
||||
const competitor = await repay(failLender.id, failLoan.id, '7.00');
|
||||
for (const b of [target, competitor]) { await call(manager, 'POST', `/payment-batches/${b.id}/review`, {}); await exportOrder(b.id); }
|
||||
const reference = `UI-FAIL-${mode}`.toUpperCase();
|
||||
await receipt(target.id, '700', reference, { payeeAccount: failLender.bankAccount, transactionStatus: 'failed' });
|
||||
reconciliationUi.failures.push({ id: target.id, repaymentId: target.loanRepaymentId, reference });
|
||||
|
||||
const lateLender = await verifiedLender(`合成追回界面-${mode}`, null, '8');
|
||||
const lateLoan = await confirmedLoan(lateLender.id, '100.00', `合成晚到追回-${mode}`);
|
||||
const original = await repay(lateLender.id, lateLoan.id, '80.00');
|
||||
await call(manager, 'POST', `/payment-batches/${original.id}/review`, {}); await exportOrder(original.id);
|
||||
const exp = await prisma.paymentOrderExport.findFirstOrThrow({ where: { payment_batch_id: original.id } });
|
||||
const sub = await register(original.id, `UI-ORIGINAL-${mode}`, exp.id); await attest(original.id);
|
||||
const fact = await proposeFact(original.id, { submissionId: sub.id, kind: 'termination_evidence', terminalStatus: 'failed', evidenceId: await uploadEvidence(original.id) });
|
||||
await reviewFact(original.id, fact.id); await confirmNotPaid(original.id); await cancelBatch(original.id);
|
||||
const paid = await repay(lateLender.id, lateLoan.id, '60.00');
|
||||
await call(manager, 'POST', `/payment-batches/${paid.id}/review`, {}); await exportOrder(paid.id);
|
||||
await receipt(paid.id, '6000', `UI-PAID-${mode}`, { payeeAccount: lateLender.bankAccount });
|
||||
await call(finance, 'POST', `/payment-batches/${paid.id}/execute`, {});
|
||||
const saved = await prisma.paymentBatch.findUniqueOrThrow({ where: { id: original.id } });
|
||||
reconciliationUi.late.push({ id: original.id, lenderId: lateLender.id, reference: `UI-LATE-${mode}`,
|
||||
payer: decryptStringOrThrow(config, saved.payment_account_snapshot_json.accountNumberEncrypted), payee: lateLender.bankAccount });
|
||||
}
|
||||
await require('./company-loan-browser.cjs')({ app, finance, manager, ordinary, password, company, bank, lender, loan, config, prisma, attributionUi, reconciliationUi });
|
||||
}
|
||||
console.log(JSON.stringify({ stage: 'loan_ledger_http', status: 'PASS', checks }));
|
||||
|
||||
在新工单中引用
屏蔽一个用户