fix(m3): code-review 15 项修复(13 项落地,2 项依赖分摊语义记待办)

- 审批:删 _flush_order 撞键内部重试(rollback 会回掉同事务业务行造成
  静默丢数据,异常改由 create 外层重试整体重来/update 路径审计收敛);
  act() 出参固化前置到 commit 之前(commit 后查询失败会把已通过的审批
  记成失败审计);驳回/撤回清空方案生效行(防被否决方案进 M3 快照);
  keyword 改 contains(autoescape=True) 对齐全库转义口径;撤单抽
  withdraw_pending_orders 供编辑清空方案时显式调用
- 业务:删业务遇在途审批单禁删 400、终态审批单随 _hard_delete 清理;
  编辑清空方案同步撤回在途单;历史离职参与人编辑放行(冗余姓名固化
  语义,仅新增参与人做在职校验)
- 迁移:business_secondary_allocations 补 uk(business_id, personnel_id)
  (模型/迁移 py/导出 SQL/init-dev 四方同步,开发库往返重放验证)
- 设置:upload_logo 改同步 def(阻塞操作不卡事件循环)+ file.size 先拦;
  company_name schema 剥空白防全空白入库;logo 旧文件清理移到 commit
  成功后(防库指旧路径而文件已删断链);uploadLogo 走 request() 解包
  (原直发 service.post 不解包信封,logoUrl 会被置 undefined)
- 备份:restore_drill --drop-exec 先清全部历史 drill 库再演练并即删本轮
  (原语义永远删错对象,每轮净增一份整库拷贝)
- 测试:conftest 清理补 system_settings 种子行与 uploads/logo 文件;
  新增 5 例(驳回清方案/清空撤单/在途禁删终态随删/离职放行/BOOL 边界);
  全量回归 701 passed
- 遗留 2 项记 AI_CONTEXT(方案版本承载、审批单快照,依赖 ④ 分摊语义)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxinandClaude Code committed 2026-10-16 14:23:53 +08:00
1 parent fc8a42bcd9
commit 1c93ea0a4b
14 files changed
+338 -79

No files matched your search

@@ -126,17 +126,18 @@ def save_logo(
setting = get_setting(session)
old_path = setting.logo_path
# 旧扩展名清理必须在写新文件**之前**:同扩展名覆盖时先写后删会把
# 刚落盘的新文件一并删掉(回读 404)
old_ext = Path(old_path).suffix.lstrip(".") if old_path else None
if old_ext and old_ext != ext:
_cleanup_old_logo(old_ext)
# 先写新文件、commit 成功后再清旧扩展名(若把清理放在 commit 之前,
# commit 失败会让库指旧路径而旧文件已删——断链无补偿);同扩展名
# 由写入覆盖,无需也不会误删新文件
target = _logo_dir() / f"logo.{ext}"
target.write_bytes(content)
setting.logo_path = f"logo/logo.{ext}"
session.commit()
old_ext = Path(old_path).suffix.lstrip(".") if old_path else None
if old_ext and old_ext != ext:
_cleanup_old_logo(old_ext)
logger.info("更新公司 logo | size=%s ext=%s", len(content), ext)
return to_out(setting)