From ca206bccb2cf47642015d34f0278cefa413882bf Mon Sep 17 00:00:00 2001 From: guke Date: Thu, 30 Jul 2026 16:36:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(sms):=20auth=20sms=5Fsend=20=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=20SendResult(=E4=BF=AE=20cooldown=5Fsec=20500)+=20?= =?UTF-8?q?=E8=AE=B0=20provider/fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 批次2 将 send_code 返回类型 int→SendResult 后,sms_send 仍把它整体塞进 SmsSendResponse.cooldown_sec:int → pydantic ValidationError → 500。改为取 send_result.cooldown_sec;成功侧 EVENT_SMS_SEND details 加 provider/fallback。 Co-Authored-By: Claude Opus 4.8 (1M context) --- app/api/v1/auth.py | 7 +++++-- tests/test_auth.py | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/api/v1/auth.py b/app/api/v1/auth.py index a8c3141..5627cdf 100644 --- a/app/api/v1/auth.py +++ b/app/api/v1/auth.py @@ -207,7 +207,8 @@ def sms_send(req: SmsSendRequest, request: Request, db: DbSession) -> SmsSendRes check_rate_limits(request, subject=req.device_id, rules=send_rules) try: - cooldown = send_code(req.phone) + send_result = send_code(req.phone) + cooldown = send_result.cooldown_sec except SmsError as e: risk_repo.record_behavior_event( db, @@ -238,7 +239,9 @@ def sms_send(req: SmsSendRequest, request: Request, db: DbSession) -> SmsSendRes phone=req.phone, client_ip=_client_ip(request), outcome="success", - details={"mock": settings.SMS_MOCK}, + details={"mock": settings.SMS_MOCK, + "provider": send_result.provider, + "fallback": send_result.fallback}, evaluate_rule=risk_repo.RULE_SMS_HOURLY, ) diff --git a/tests/test_auth.py b/tests/test_auth.py index 42d9add..bdf068c 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -68,6 +68,29 @@ def test_sms_login_and_me_flow(client) -> None: assert r.json()["ok"] is True +def test_sms_send_records_provider_and_fallback_in_details(client, monkeypatch) -> None: + """批次3(Task 6):sms_send 成功后风控流水 details 带 provider/fallback。 + mock 默认走极光主(SMS_FALLBACK_PROVIDER 空)→ provider=jiguang、fallback=False。 + (回归:修复前 send_code 返回 SendResult 被塞进 cooldown_sec:int → 500,此处 200 断言即挡住。)""" + from app.repositories import risk as risk_repo + + captured: dict = {} + orig = risk_repo.record_behavior_event + + def _spy(db, **kw): + if kw.get("event_type") == risk_repo.EVENT_SMS_SEND and kw.get("outcome") == "success": + captured.update(kw.get("details") or {}) + return orig(db, **kw) + + monkeypatch.setattr(risk_repo, "record_behavior_event", _spy) + + r = client.post("/api/v1/auth/sms/send", + json={"phone": "13800009999", "device_id": "dev-provider-test"}) + assert r.status_code == 200, r.text + assert captured.get("provider") == "jiguang" + assert captured.get("fallback") is False + + def test_sms_send_too_frequent(client) -> None: phone = "13900139000" assert client.post("/api/v1/auth/sms/send", json={"phone": phone}).status_code == 200