refactor: 前端全面替换 any 为 unknown 并统一错误处理,后端用量记录补写请求头/体

- 前端 API 层、stores、conversation 解析器、组件全面替换 any 为 unknown/具体类型
- 错误处理统一使用 parseApiError/getErrorStatus 替代 err.response?.data?.detail 模式
- 后端 handler/TaskService/UsageLifecycle/StreamTracker 链路传递 request_headers/request_body
- streaming/pending 状态更新时可补写客户端和提供商的请求头及请求体
- 新增 TaskService 和 UsageService 相关测试
This commit is contained in:
fawney19
2026-02-22 00:43:41 +08:00
parent 98e60e8f74
commit cf2eee222e
121 changed files with 1652 additions and 1179 deletions

View File

@@ -299,3 +299,68 @@ class TestHelperMethods:
assert rate_multiplier == 0.8
assert is_free_tier is False
class TestUsageStatusUpdate:
"""测试进行中状态更新对请求头/体的补写能力"""
def test_update_usage_status_can_persist_request_and_provider_payloads(self) -> None:
usage = MagicMock()
usage.status = "pending"
usage.provider_name = "pending"
usage.billing_status = "pending"
usage.finalized_at = None
usage.request_headers = None
usage.request_body = None
usage.provider_request_headers = None
usage.provider_request_body = None
mock_db = MagicMock()
mock_db.query.return_value.filter.return_value.first.return_value = usage
client_headers = {"authorization": "Bearer abc", "x-trace-id": "trace-1"}
provider_headers = {"authorization": "Bearer upstream", "x-provider": "demo"}
client_body = {"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "hello"}]}
provider_body = {
"model": "upstream-model",
"messages": [{"role": "user", "content": "hello"}],
}
with (
patch(
"src.services.system.config.SystemConfigService.should_log_headers",
return_value=True,
),
patch(
"src.services.system.config.SystemConfigService.should_log_body",
return_value=True,
),
patch(
"src.services.system.config.SystemConfigService.mask_sensitive_headers",
side_effect=lambda _db, h: {"masked": h},
),
patch(
"src.services.system.config.SystemConfigService.truncate_body",
side_effect=lambda _db, b, is_request=True: {
"truncated": b,
"is_request": is_request,
},
),
):
updated = UsageService.update_usage_status(
db=mock_db,
request_id="req-streaming-1",
status="streaming",
provider="demo-provider",
request_headers=client_headers,
request_body=client_body,
provider_request_headers=provider_headers,
provider_request_body=provider_body,
)
assert updated is usage
assert usage.request_headers == {"masked": client_headers}
assert usage.provider_request_headers == {"masked": provider_headers}
assert usage.request_body == {"truncated": client_body, "is_request": True}
assert usage.provider_request_body == {"truncated": provider_body, "is_request": True}
mock_db.commit.assert_called_once()