借款对账 S4–S8:人工未提交、晚到补记、追回与界面收口(09-17-company-loan-principal-repayment)

新增三类证据与双人复核的人工未提交、逐原因冻结、晚到付款逐借款补记和实际退款追回;补齐对账与补证恢复界面,保护已消费依据、最终归属重验及全局交易唯一性。

验证:81 迁移、HTTP 95 组、浏览器 13 组、数据库约束 9 组;13 项有效变异被捕获,部分由下游或数据库保护检出。构建、类型、合同和治理检查通过;修复后同模型只读静态复核通过。

真实回单待验、整体业务验收未通过;S0 存量、人员、银行材料与业务独立验收未完成。3 个新增迁移须纳入获批发布清单。本次仅本地提交,不推送、不部署。
这个提交包含在:
2026-10-07 21:58:03 +08:00
父节点 2e00d30fd0
当前提交 431c36eae3
共修改 32 个文件,包含 1902 行新增和 25 行删除
@@ -1124,6 +1124,8 @@ await canReadReimbursementBusinessFact(prisma, reimbursement, employee.id);
- Recovery snapshots bind material revisions, submission/fact/receipt identities, verification versions, independent participants and the current same-amount candidate set. Material writers (including OCR persistence) serialize on the batch; candidate formation also locks the lender. A local batch revision alone cannot detect another batch becoming a candidate. Validate at submission, approval and final cancellation, with physical document digest checks before release.
- JSONB can reorder object keys. Compare snapshots using recursive key-canonicalized hashes, retaining array order, rather than hashing raw `JSON.stringify` results before and after storage. Keep snapshot payloads out of public response mapping. New evidence for the same bank transaction still requires new review.
- Verify recovery through `RUN_ISOLATED_LOAN_DB_TEST=1 node scripts/qa/test-company-loan-db.cjs` with the locked BIFF8 Python environment: real HTTP/evidence/OCR, stale-round repair, no fallback after withdrawal, atomic rollback and deterministic interleavings with evidence, submissions, OCR and candidate formation. Existing browser checks do not prove the deferred S8 recovery UI; inline self-review is not independent review.
- Manual no-submission is a separate terminal fact, never a bank termination claim: fixed documentary categories, complete reviewed export/submission inventory, two distinct independent reviews, material/candidate snapshot and physical digest checks at final release. An empty submission attestation is valid only for actual exports and no historical submission rows; withdrawn submissions do not prove non-submission.
- Late-payment supplements and bank returns use an append-only ledger, not exportable payment batches. Include supplemental principal in both application balance calculations and SQL capacity checks. Their keyed transaction claims must exclude ordinary receipt claims and aliases in both directions under the shared receipt lock. Freeze causes close independently; partial returns and unresolved reservation conflicts keep their own causes active. The ordinary pre-payment gate must not block factual reconciliation.
- ERP-specific API/adapters/jobs/enqueues are retired by `09-17-erp-exclusive-retirement`. Shared outbox/notification/WeCom and historical records remain. New ERP enqueue and direct dispatch reject; pending selection excludes `erp.*`; historical retry returns `integration.erp_retired` without mutating records. Never restore these retired consumers solely to satisfy old success-path tests.
@@ -1,3 +1,18 @@
## 2026-10-07 S4–S8 实施细化(沿已批准范围,尚待最终验收)
- Q6 使用独立的人工声明与复核记录,不混入银行终态事实。三类附件固定分类;查询及对账覆盖首次导出至登记日(公司时区),每个相关导出人均须有文件去向说明。完整空提交清单可以独立复核;撤回登记不能充当“未提交”。混合批次仍逐条验证已提交部分的银行终态。
- 每次人工声明绑定材料修订、全部导出/提交/核验、付款快照及同额候选。两名不同且当前合格的复核人分别决定。失效声明可以追加取代,原银行终态不改;最终取消重验全部条件、物理文件摘要及双审,数据库另外约束释放配对。
- 冻结按来源事件逐条记录;只在新申请、付款前复核及导出入口检查。关闭函数仅供对账业务事务调用,没有通用解冻接口。误报须经独立人员凭更正证据确认;仅不确定或证据不足不能关闭。
- 晚到成功及退款到账以人工核对银行原件的方式登记(不是 OCR 通过)。输入按既有回单归一化规则核对成功状态、双方账号、币种、金额和流水号,原始人工输入加密存储;查询完整输入必须填写用途并记审计。已取消批次可以另存银行证据,但不重开原付款回单、付款项或导出。
- 归属批准到入账之间再次出现同额候选,最终入账重验会拒绝。可用同一交易的新登记取代未入账的旧批准,再独立复核;取代时保持至少一条冻结。银行交易的唯一认领在最终入账事务中消费,复核仅做冲突检查,避免尚未入账的失效批准占死交易身份。已入账的银行事实不能被重提覆盖。
- 晚到补记与追回使用独立银行事件、交易认领及逐借款补记表,不创建付款批次。交易认领和原核销/别名空间相互排斥;复核与入账同样校验密钥和交易身份。补记成功之后,新申请可用本金要扣掉补记结清额,数据库容量检查也包含这部分。
- 未释放的原占用在补记事务中以被银行事实推翻为原因释放,保留原终态和取消信息;其他仅占用的申请须先处理,不能算作已付。已经付掉的部分按差额列待追回;整笔超额时也保留银行全额和零结清记录。追回只接受实际到账并经复核,不用冲抵;部分到账不解冻。
- 已有待复核或已批准的晚到成功时,旧终态取消入口拒绝,必须走对账补记;数据库延迟约束同样保护这条边界。取代已产生占用冲突的未入账事件时,同事务先转移冲突冻结再关闭旧原因;新事件入账或凭更正证据确认误报时关闭对应派生原因,不能留下不可处理的旧冻结。
- 已用于误报解冻的更正证据属于已消费的复核依据,服务及数据库均禁止再作废。更正记录、原始银行事件及关闭依据保留,不回写原结论。
- 终态界面支持一次关联多份同指令处理中回单。复核卡明确展示所选提交、终态类型、证据、了结回单;Q6 展示逐份导出及三类证据的准确绑定,失败归属展示覆盖指令及核验附件。历史作废回单仅可通过实际事实绑定、必填用途的对账读取查看;权限、隔离策略、物理摘要、审计及 no-store 保留,普通作废回单下载仍被拒绝,不恢复其付款效力。
- S8 沿用既有 React 对话框和样式,未引入新视觉方案。页面集中展示导出、提交、证据、人工声明、补证轮次、银行事件和冻结原因;原制单不得再次导入网银的提示不是技术保证。
- S0(存量、合格复核人数、银行编号关系及官方材料)、真实回单验收仍未完成;本轮资金与界面代理已完成修复后只读静态复核,运行时结果见 implement。该复核不替代异模型或业务人员验收。本地实现/合成验证不代表可以部署或真实还款。
## 2026-10-07 补证后恢复方案(SR,第 1 版,用户已批准本地实施)
本方案先完成设计,随后用户明确回复“批准”,授权 SR-A、SR-B 本地实施与验证;SR-C 随 S8,提交、推送与部署未授权。S3 已本地提交 `14aee82d`;下文历史设计及实施记录保留其原时点。本方案补充 3.2 的释放流程,不把普通补证归入 S6 的晚到成功。
@@ -1,3 +1,38 @@
## 2026-10-07 后续收口执行(用户同意执行)
按后续工作清单,先将已验证的 S4–S8 共 32 项改动本地提交,提交保留“真实回单待验、整体业务验收未通过”。随后补齐提交登记、清单复核、失败归属、晚到补记和追回的浏览器闭环,并准备发布前存量/迁移/回退检查材料。当前 inline 主会话直接实现和检查,不另派代理;此前两名代理的复核仅覆盖其当时差异。生产查询单独确认,人员与银行材料待外部答复;推送、部署和远端备份切换不在本次默认执行内。以下“32 项未提交”属于提交前验证时点。
- [ ] 本地提交已验证 S4–S8。
- [ ] 补齐其余银行对账表单的电脑/手机闭环并修复发现的问题。
- [ ] 在现有任务/恢复手册整理具体发布准备与未满足条件。
- [ ] S0 生产只读核实及外部人员、银行材料确认(分别记录)。
## 2026-10-07 后续执行接续(用户要求已确定工作直接执行)
沿既有设计与 S4–S8 清单推进本地实施、针对性验证与主会话检查,不再逐阶段等待通知。先 S4,再按依赖推进 S5、S6、S7、S8;提交、推送、生产操作仍遵守单独授权。SR-A/B 已本地提交 `2e00d30f`。前阶段 inline 下未派独立代理;本轮工具已可用,按 AGENTS 对资金流程的要求另派两名只读代理检查资金与界面,修复后静态复核通过(同模型,非业务独立验收)。
- [x] S4 本地实施与合成验证:Q6 三类证据独立分类、全量材料快照、两名独立复核、人工终态及最终取消重验;覆盖混合导出(已提交部分沿 S3,未提交部分逐份举证)。
- [x] S5–S8 本地实施、针对性回归及只读静态复核;整体业务验收仍受 S0 和真实样本限制。
- S4 技术边界:人工声明覆盖未关联提交的导出,不可覆盖任何已登记(含撤回)的提交;查询及对账单覆盖首次导出至登记日(公司时区),所有导出人的文件去向说明齐全。快照变更后重新登记、重新双审,原终态不改。附件分类不允许事后互换,不进入回单 OCR;真实材料及人员可用性仍待 S0。
### 本轮阶段结果(本地验证通过,尚未提交)
- S4:新增 `loan_not_submitted_proposals/reviews`、三类固定证据分类、完整空清单复核、双人决定、人工终态、材料变更取代及最终取消重验。增量迁移 `20261008030000_loan_not_submitted`。
- S5:新增逐原因冻结、付款前统一门禁;事实登记不冻结,没有通用管理员解冻接口。迁移 `20261008040000_loan_freeze_reasons`。
- S6/S7:新增银行事实、跨核销空间交易认领、逐借款补记、实际追回;本金容量同时包含补记结清。迁移 `20261008050000_loan_bank_result_events`。当前原件人工录入/独立核对,不声称 OCR 或银行真实性自动验证。待审的同一交易可用新证据取代,先产生新冻结再关闭旧冻结;已复核银行事实的原件不得作废,物理文件损坏仍拒绝入账。
- S8:详情页接入提交、清单、终态、失败归属、Q6、SR 恢复、晚到补记/追回;查询完整人工输入和原件要求用途与审计,电脑/手机完成 Q6、SR 恢复及多回单终态的完整弹窗流程;其他新增表单以 HTTP 与类型检查覆盖。沿用既有视觉组件。
- 有效变异共 13/13 被测试捕获(6 个首轮、2 个金额边界、2 个最终入账守卫、3 个复核修复守卫)。包括三证类别、物理摘要、快照、冻结、交易身份、部分追回、占用冲突、超额拆分、最终候选、冻结转移、更正依据和旧取消旁路。部分变异仍被下游/数据库拒绝,测试捕获的是错误响应或错误原因,不能写成全部造成了错误释放。环境路径错误的首轮未计入;变异只在临时源码副本中进行,后续固定源码轮次摘要未变。
- 最终隔离回归:81 个迁移、HTTP 95 组、浏览器 13 组、数据库约束 9 组通过,容器清理 PASS。包含整笔超额、逐原借款差额、跨流程交易复用、原审批人离职、审计回滚、候选变更重新复核及冻结/新申请/导出的确定性交错。固定前后端源码/构建副本的最后一轮再次得到相同通过结果,副本及自有容器已清理。浏览器覆盖原有 7 组及电脑/手机 Q6 双审、SR 补证、两份处理中回单终态释放(包括作废历史回单的复核下载)6 组。人工等待期在 HTTP 验证,浏览器合成配置设为 0,不等待现实三天。
- 服务端首跑 4472 通过、8 失败、1 原有跳过(4481 总);8 个失败为报销回单旧测试替身缺少新增跨台账认领查询,补齐后相关两文件 150/150 通过,最后共享下载路径调整后再次 150/150 通过。合并覆盖 4480 项通过、1 项原有跳过,未将其描述为完整套件重新全跑通过。
- 中间失败如实保留:浏览器精确标签、分页缓存等待、Q6 合成等待期设置及重新登录加载等待先后修正;运行器后来固定 client/dist 副本,避免与构建文件更换交错。失败轮次不计通过。首轮变异因临时 Python 路径错误停在制单生成,不计有效变异。
- Prisma 校验、前端类型检查/构建、共享回单定向测试、UI 规则、错误码合同、敏感扫描、任务治理/流程合同及 git diff --check 通过。文档注册检查退出 0,保留原有 22 个未登记 docs 告警。
- 本轮只读复核修复:取代银行事件遗留冲突冻结;误报解冻依据可作废;终态界面只能选一份处理中回单;各复核卡缺准确材料绑定;已作废处理中回单无法供复核查看。分别补齐服务/数据库保护、历史证据读取及桌面手机回归。两名代理对修复后源码静态复核通过,最终运行时结果见上方;不把同模型审查当作外部业务验收。
- 最终候选另外修正:晚到事实未处理时旧取消不能释放;归属候选在批准后变化时入账拒绝;唯一交易认领只在最终入账事务消费,允许未入账失效记录重新登记。
- 所有测试只用合成数据和本次拥有的隔离容器。未查询生产、未提交推送部署;S0、真实样本和外部业务验收仍待完成,整体借款验收未通过。
复现入口沿用上面的隔离回归命令(具体命令见下方 SR 记录);新增 3 个迁移必须列入将来经过批准的预期迁移。本轮 32 项未提交,HEAD 为 `2e00d30f`;未推送、未部署、未查生产。S0 仍须核实存量、两名额外合格复核人、建行官方无结果材料和回单/指令编号对应。真实银行材料、银行事实的业务真实性以及异模型/业务独立验收不由合成数据证明。保持任务进行中,不归档。
## 2026-10-07 SR-A / SR-B 收尾与提交授权
用户明确批准“先收尾 SR-A/B,本地提交;S4 另批”。本次将下方 15 项实现、测试及文档作为一个本地提交收口,沿用已完成的运行时验证,收尾只更新记录并重验任务治理及差异格式。未推送、未部署、未查询生产。当前 inline 模式下独立复核仍待完成;界面留在 S8,真实回单待验,不能单独部署启用。整体任务保持进行中,不归档;以下“未提交”和 HEAD 描述为实施验证时点的记录。
@@ -1,5 +1,9 @@
# 公司借款台账与本金归还
## 2026-10-07 本地阶段状态
S4–S8 与 SR 界面已完成本地实现及合成回归:81 迁移、HTTP 95、浏览器 13、数据库约束 9 组通过,修复后的资金与界面只读静态复核通过(同模型)。S0、真实建行材料和业务独立验收仍未完成;不据此勾选整体真实还款验收或声明已部署。完整证据与限制见 implement.md 顶部。
## 2026-09-17 实施接续
用户明确要求借款尽快完成,沿本PRD与design既有个人出借人/CNY本金范围推进本地T1–T4,取代此前暂缓实施的优先级;不扩大为利息、备用金或通用付款。真实资料、余额和账户仍须正式录入核实,本地只用合成样例。风险与独立复核在交付/上线前保持未完成,不通过读取生产密钥或重跑旧恢复为本地开发解阻。
@@ -45,6 +49,10 @@
付款成功与代账记账分开,记录凭证编号/记账确认及材料交接,不由OA自动生成会计分录。材料包括原借入凭证、协议/确认书、余额核对、审批及还款回单;本金不要求费用发票,不进入费用报销统计或费用预算。关键材料按适用访问权限留存,历史余额/分配不得无审计改写。
## 2026-10-07 S4–S8 本地接续
用户要求沿已确定工作直接执行。S4–S8 的本地实现和验证继续推进,阶段证据在 implement 顶部;AC9–AC19 不因后端或合成测试通过而自动勾为整体验收通过。新银行事件均标明人工核对,不伪称真实银行/OCR 已验;生产查询、推送、部署仍未执行。
## Acceptance Criteria
- [x] AC1:合成历史两笔借入可登记并确认余额;未确认/重复登记/无凭据不进入还款,历史录入不被统计成当天新增收款。