feat(coupon): /coupon/step 每帧响应顶层回显 trace_id,补齐领券链路
对齐 compare 链路(_forward 的 setdefault 注入,每步响应都带 trace_id):coupon_step 透传响应在 resp.json() 后 setdefault 注入本次任务 trace_id,客户端任一帧都能从响应 拿到全链 id。**只回显请求里带的、不 mint**——step 是循环接口,每帧签新 id 会把一次 任务打散;领券 trace_id 的唯一签发点保持在 /coupon/session (status=started)。带 isinstance dict + 非空 trace_id 双防御(pricebot 响应顶层本无 trace_id 字段,setdefault 不会覆盖任何上游值)。 顺手修复 test_coupon_proxy.py 一个 pre-existing 红测试:coupon_step 转发早已改为 content=raw 原始字节透传,但 fake_post 仍只捕获 json= 参数 → captured["json"] 恒 None、body 转发断言一直失败(git stash 验证不带本轮改动同样红)。fake 改捕 content、 断言按字节 json.loads 后对比;transparently-passes-through 断言更新为"透传 + 顶层 回显 trace_id"新契约。 领券相关测试 22 passed。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -177,6 +177,12 @@ async def coupon_step(
|
||||
)
|
||||
|
||||
resp_json = resp.json()
|
||||
# 每帧响应顶层回传本次任务 trace_id(对齐 compare _forward 的 setdefault):客户端任一帧
|
||||
# 都能从响应拿到全链 id。**只回显请求里带的、不 mint**——step 是循环接口,每帧签新 id
|
||||
# 会把一次任务打散;领券 trace_id 的唯一签发点在 /coupon/session (status=started)。
|
||||
# pricebot 响应顶层本无 trace_id(只有 trace_url),setdefault 不会覆盖任何上游值。
|
||||
if isinstance(resp_json, dict) and trace_id:
|
||||
resp_json.setdefault("trace_id", trace_id)
|
||||
|
||||
# 领券结果沉淀:每日资产 + 逐次事件;中间帧和 done 全量帧均幂等写库。
|
||||
# 当前只记录、不参与"要不要领"判断(MVP 先不去重)。写库失败不影响返回。
|
||||
|
||||
@@ -8,6 +8,7 @@ mock 掉对 pricebot 的 httpx 调用,验证:
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import time
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -62,7 +63,8 @@ def test_coupon_step_no_auth_required(client) -> None:
|
||||
|
||||
|
||||
def test_coupon_step_passes_body_through(client, access_token) -> None:
|
||||
"""带 token + pricebot 200 → 响应原样透传,请求 body 原样转发到 /api/coupon/step。"""
|
||||
"""带 token + pricebot 200 → 请求 body 原样转发到 /api/coupon/step;
|
||||
响应在透传基础上顶层回显本次任务 trace_id(setdefault 注入,其余字段原样)。"""
|
||||
fake_pricebot_resp = {
|
||||
"success": True,
|
||||
"action": {
|
||||
@@ -83,9 +85,12 @@ def test_coupon_step_passes_body_through(client, access_token) -> None:
|
||||
|
||||
captured: dict = {}
|
||||
|
||||
async def fake_post(self, url, json=None, **kw):
|
||||
# ⚠️ coupon_step 转发用 content=raw(原始字节透传,不重新 dumps),不是 json= ——
|
||||
# fake 必须捕 content。旧 fake 只捕 json= 导致 captured["json"] 恒 None,本测试
|
||||
# 自 content=raw 优化后一直红着(pre-existing),本次顺手修正。
|
||||
async def fake_post(self, url, content=None, **kw):
|
||||
captured["url"] = url
|
||||
captured["json"] = json
|
||||
captured["content"] = content
|
||||
mock_resp = MagicMock()
|
||||
mock_resp.status_code = 200
|
||||
mock_resp.json = lambda: fake_pricebot_resp
|
||||
@@ -99,9 +104,10 @@ def test_coupon_step_passes_body_through(client, access_token) -> None:
|
||||
)
|
||||
|
||||
assert r.status_code == 200, r.text
|
||||
assert r.json() == fake_pricebot_resp
|
||||
# 验证请求被原样转发(body 不动 + URL 指向 pricebot)
|
||||
assert captured["json"] == _stub_request_body()
|
||||
# 顶层多出 trace_id 回显(值=请求带的;不 mint,签发点唯一在 /coupon/session started)
|
||||
assert r.json() == {**fake_pricebot_resp, "trace_id": "test-trace-1"}
|
||||
# 验证请求被原样转发(body 字节不动 + URL 指向 pricebot)
|
||||
assert json.loads(captured["content"]) == _stub_request_body()
|
||||
assert captured["url"].endswith("/api/coupon/step")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user