"""统一响应格式:{code, message, data, trace_id},错误码与需求文档 §6.1 对齐。""" from typing import Any from pydantic import BaseModel from utils.request_id import get_request_id class Code: OK = 200 PARAM_ERROR = 400 UNAUTHORIZED = 401 FORBIDDEN = 403 NOT_FOUND = 404 SERVER_ERROR = 500 LLM_FAIL = 1001 # LLM 调用失败 KB_NO_RESULT = 1002 # 知识库检索无结果 SQL_GEN_FAIL = 1003 # nl2sql 生成失败 RISK_TRIGGERED = 1004 # 风控规则触发 / 交易被拦截 NOT_SUITABLE = 1005 # 适当性不匹配 class ApiResponse(BaseModel): code: int = Code.OK message: str = "success" data: Any = None trace_id: str | None = None def success(data: Any = None, message: str = "success") -> ApiResponse: """成功响应。""" return ApiResponse(code=Code.OK, message=message, data=data, trace_id=get_request_id()) def fail(code: int, message: str, data: Any = None) -> ApiResponse: """失败响应(业务错误码见 Code)。""" return ApiResponse(code=code, message=message, data=data, trace_id=get_request_id())