const assert = require('node:assert/strict'); const { randomUUID } = require('node:crypto'); module.exports = async function freezeFixture(h) { const { prisma, call, req, finance, manager, verifiedLender, confirmedLoan, repay, exportOrder, uploadEvidence } = h; const freezes = req('./src/services/loanFreezes'); const lender = await verifiedLender('合成冻结出借人', null, '4'); const loan = await confirmedLoan(lender.id, '1000.00', '合成冻结借款'); const first = await repay(lender.id, loan.id, '10.00'); await call(manager, 'POST', `/payment-batches/${first.id}/review`, {}); await exportOrder(first.id); const draft = await repay(lender.id, loan.id, '20.00'); const request = { employee: { id: finance.id }, headers: {}, id: randomUUID(), ip: "127.0.0.1" }; const batch = await prisma.paymentBatch.findUniqueOrThrow({ where: { id: first.id }, include: { items: true } }); const open = (kind, key) => prisma.$transaction((tx) => freezes.openReason(tx, batch, request, kind, key)); const close = (kind, key) => prisma.$transaction((tx) => freezes.closeReason(tx, batch, request, kind, key, { action: 'synthetic_source_resolved', recordId: randomUUID() })); const key = randomUUID(); const other = randomUUID(); const reason = await open('late_success', key); await open('receivable', other); assert.equal((await open('late_success', key)).id, reason.id); await call(manager, 'POST', `/payment-batches/${draft.id}/review`, {}, 409, 'loan.lender_frozen'); await call(finance, 'POST', `/payment-batches/${first.id}/payment-order`, {}, 409, 'loan.lender_frozen'); await call(finance, 'POST', '/loan-repayments', { lenderId: lender.id, reason: '合成冻结后新付款', requestKey: randomUUID(), allocations: [{ loanId: loan.id, amount: '1.00' }] }, 409, 'loan.lender_frozen'); await uploadEvidence(first.id); // Facts remain recordable. await close('late_success', key); assert.equal((await freezes.state(prisma, lender.id)).frozen, true); await call(manager, 'POST', `/payment-batches/${draft.id}/review`, {}, 409, 'loan.lender_frozen'); await close('receivable', other); assert.equal((await freezes.state(prisma, lender.id)).frozen, false); await call(manager, 'POST', `/payment-batches/${draft.id}/review`, {}); await assert.rejects(prisma.loanFreezeReason.delete({ where: { id: reason.id } })); await assert.rejects(prisma.loanFreezeReason.update({ where: { id: reason.id }, data: { status: 'active' } })); return ['s5_all_active_causes_block_new_payment_review_export_but_allow_facts', 's5_individual_closure_never_unfreezes_other_causes_and_history_immutable']; };