Commit Graph
2 Commits
Author SHA1 Message Date
GaoYiYuan_0626 318cb39a1f 基金转换 T-7:convert_service 八步编排(关键路径 · 幂等前置 + 三阶段)
- 新增 app/service/convert/convert_service.py:八步编排(①-④ 校验不落库 / ⑤ 占位 /
  ⑥ apply_convert / ⑦ 阶段 1.5 引擎不阻断 / ⑧ 回写 + 审计),幂等判定前置到校验之前
  以修复同键重试误报 InsufficientShares
- 新增 tests/test_convert_service.py(17 用例)
- 新增 scripts/dev/verify_convert_service.py(真 MySQL 验证 35/35)
- 改 app/repository/convert_repository.py:complete_convert 由纯 UPDATE 改三步法
  upsert(无占位直跑也能落完成行,R-a 口径)
- 改 app/repository/core_ro.py:新增 has_convert_trades / list_convert_trades /
  list_convert_lot_details 三个只读方法
- 改 app/config/settings.py:新增 6 个 convert 配置项
- 修 tests/test_convert_calc.py:TestPurity 排除编排层 convert_service.py

基线 639 → 656 passed / 3 skipped,零回归
2026-09-10 17:12:01 +08:00
GaoYiYuan_0626andWorkBuddy 4fd2ec05c8 基金转换 T-4+T-5(并行组 A):convert_repository 代理侧 + locks.try_lock 非阻塞抢锁
T-4(convert_repository · agent 库 risk_convert_detail):
- 新增 7 方法:insert_placeholder(占位 pending) / complete_convert(回写 completed+折算详情)
  / mark_failed / get_by_group_id / get_by_client_request_id(None 直接返回 None)
  / list_expired_candidates(hours) / mark_expired(S2 标记不硬删)
- 引擎走 agent 库 rw(D20);status 5 值枚举;不与 risk_repository 混职责
- Decimal 折算字段经 _to_bind 转 float 绑定(sqlite 不支持直接绑 Decimal,同 T-3)

T-5(locks.try_lock):
- 单次非阻塞抢锁:抢到返回 _Token(with 进入 True),抢不到立即 _NoLock(进入 False,不等不降级)
- Redis 不可用退回进程内 Lock.acquire(blocking=False);_NoLock.__enter__ 返回 False 避免 with None 报错
- 不改 run_locked(D4:其等 2s 后降级 fn(False),语义相反;3 处调用点零改动)

测试:test_convert_repository.py 6 用例 + test_locks_redis.py +4 用例(既有 6 例零改动)
pytest 全量 634 passed / 3 skipped(基线 624 + 10,零回归)

Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
2026-09-10 15:53:31 +08:00