fix(T+): 补齐指导成本与读取服务保护

补充业务详情指导成本入口、来源版本和历史封存保护,接入月份锁并完善权限复核。
同步接入读取服务运行状态到页面,补充前端控制、回归测试和服务端只读连接授权校验。

定向隔离测试:89 项通过,1 条既有 Starlette 弃用警告。
这个提交包含在:
liuwenxin 于 2026-11-05 19:32:20 +08:00 提交
1 父节点 68e70fd6e2
当前提交 b8920c0d28
17 个文件已更改
+375 -47

没有与搜索条件相匹配的文件

+17 -2
查看文件
@@ -64,9 +64,21 @@ def save_fact(session, payload, actor_id):
try:
with sync_lock(session):
session.rollback()
current = latest_facts(session, source).get((payload.kind, payload.fact_key))
facts = latest_facts(session, source)
current = facts.get((payload.kind, payload.fact_key))
if payload.kind == "GUIDANCE" and current and current.data_json.get("is_finalized"):
raise BadRequestError("该发货月份指导成本已封存,后续回款不得修改原指导成本")
if payload.kind == "GUIDANCE":
if payload.data.get("is_finalized"):
raise BadRequestError("请在业务详情中核对来源并封存指导成本")
if any(
kind == "GUIDANCE"
and fact.data_json.get("is_finalized")
and fact.data_json.get("product_id") == payload.data.get("product_id")
and fact.data_json.get("month") == payload.data.get("month")
for (kind, _), fact in facts.items()
):
raise BadRequestError("该产品发货月份已有封存指导成本,请先核对")
if (current.version if current else 0) != payload.expected_version:
raise BadRequestError("补充资料已经变化,请刷新后再保存")
fact = TPlusFact(
@@ -452,11 +464,14 @@ def report_csv(session, run_no):
return rows()
def execute_next(session):
def execute_next(session, *, may_claim=None):
"""调用方持有原有全局锁;中断任务保留明细,禁止不明状态自动应用。"""
for old in session.scalars(select(TPlusWorkRun).where(TPlusWorkRun.status == "RUNNING")):
old.status, old.error_code, old.finished_at = "FAILED", "INTERRUPTED", datetime.now()
session.commit()
if may_claim is not None and not may_claim(session):
session.rollback()
return None
run = session.scalar(
select(TPlusWorkRun)
.where(TPlusWorkRun.status == "QUEUED")