3.4 KiB
3.4 KiB
零录入票据归集跨租户隔离与失败回滚
日期:2026-07-16 文档路径:document/development/2026-07-16/dev-logs/bugs/zero-entry-receipt-tenant-and-rollback.md
修复记录
- 09:35:记录 bug 修复:零录入票据归集跨租户隔离与失败回滚。(bug-log:54754b55)
- Git 提交检查:2026-07-16 09:35 CST 执行
git fetch --all --prune成功;origin/main没有远端新提交;本地 ahead 11 条,依次是54754b55个人费用申请记忆、211f85d9统一核验申请工作流、5b246307申请预览决策、a662cfe6申请反馈账本、5ed34c2b历史费用单回填、11275e4b迁移所有权安全、1347366b费用时间线与草稿事件安全、22669a90统一费用事件时间线、a616b30cAI 申请提交事务、653eda05Bearer 会话、661990b2事务化费用事件;这些提交均为本轮开始前已有的本地检查点,本次未合并或改写历史。 - 修改:
receipt_folder.py把票据命名空间从仅用户名收口为租户与用户联合边界,并用稳定摘要消除有损清洗碰撞;attachment_association_jobs.py同时校验任务租户和 owner,平台管理员也不能跨租户读取。expense_receipt_matcher.py改用纯只读本人 Claim 查询并要求每份票据独立满足证据门槛。expense_receipt_association.py将 Claim、Case、Link、业务事件、票据元数据和新旧附件目录纳入统一失败补偿,避免事件或文件中途异常留下半关联状态。 - 操作:新增持久化
attachment_association_jobs模型、仓储和20260716_0006迁移;任务按租户、owner、票据集合和 generation 去重,运行态使用租约、attempt_count + running栅栏、进程锁和 PostgreSQL advisory lock。同票据与同 Claim 分别串行化,Claim 锁内清理旧事务并重新匹配;待确认或失败任务保留原代审计历史,以新 generation 重新评估,自动关联成功代继续幂等复用。低置信、相近候选、混入无关票据、无草稿和仅有申请统一返回需要确认的零写入结果;同步扩展前端任务协议、会话恢复、候选卡片、幂等重放和成功风险复核提示,并更新功能 CONCEPT/TODO。 - 验证:所有后端验证均在项目主容器内执行并设置 60 秒超时。后端归集专项 20 项、归集与相邻服务及迁移所有权组合回归 71 项通过,覆盖纯只读确认、逐票据证据、事件失败、文件元数据失败、既有申请 Case 保留、同票据并发、不同票据并发同 Claim、租约过期恢复、旧 worker/迟到回调栅栏、待确认重评估、失败代际历史保留、普通用户及管理员跨租户隔离;前端关联链路组合回归 29 项通过;相关 Python 文件
ruff --select F,I,UP通过;Vite 生产构建通过。一次性 tmpfs PostgreSQL 17 中完整迁移循环 4 项通过,临时数据库已清理,持久开发库未修改。 - 影响:同用户名在不同租户的票据、任务和候选 Claim 不再互相可见;自动归集中途失败不会留下已改 Claim、孤立 Case/Link/Event、错误票据状态或被覆盖的旧附件目录;低证据和混合票据批次只提示确认,不扩大自动化权限;任务重启或多 worker 后仍可查询和恢复。非默认租户原先落在旧用户名目录中的历史票据改为 fail-closed,不做未经确认的跨目录迁移。
- Git 提交检查:2026-07-16 09:35 CST 执行