FinBuddy_Web 错误统一处理与功能计费
· FinBuddy_Web
今日进展
- 错误统一处理架构落地:ErrorCode 枚举集中管理、AppException 体系、全局异常处理器三件套
- 新增功能计费服务 feature_billing_service:按功能扣费,与客户端 FC 拦截层对齐
- 新增权限仓库 permission_repo:RBAC 权限查询下沉到 Repository 层
- 新增认证查询服务 auth_query_service:认证读写分离,查询走从库
- 前端引入 vitest 测试框架,补充 http 服务和类型测试
- 接口文档补全:认证/积分/LLM代理/数据研究/会员设备/管理后台/支付 7 个模块
关键代码/伪代码
错误统一处理 — 三件套
# 之前错误处理最头疼的问题:
# 1. 错误码散落在各个文件里,重复定义
# 2. 有的路由返回 {error: "xxx"},有的返回 {message: "xxx"}
# 3. 前端不知道该判断 code 还是 message 还是 error
# 解决方案:三件套统一
# 第一件:ErrorCode 枚举 — 集中管理所有错误码
CLASS ErrorCode(IntEnum):
UNAUTHORIZED = 401
FORBIDDEN = 403
NOT_FOUND = 404
RATE_LIMITED = 429
# 业务域 1001-1999:积分相关
INSUFFICIENT_CREDITS = 1001
CREDIT_FROZEN = 1002
# 业务域 2001-2999:LLM 相关
LLM_PROVIDER_ERROR = 2001
LLM_RATE_LIMITED = 2002
# 通用业务 4001-4099
VALIDATION_ERROR = 4001
# 第二件:AppException 体系 — 业务异常基类
CLASS AppException(HTTPException):
def __init__(self, code: ErrorCode, message: str):
self.code = code
self.message = message
super().__init__(status_code=code // 100 * 100, detail=message)
# 第三件:全局异常处理器 — 统一响应格式
@app.exception_handler(AppException)
ASYNC def app_exception_handler(request, exc):
RETURN JSONResponse(
status_code=exc.status_code,
content={"code": exc.code, "message": exc.message, "data": None}
)
功能计费服务 — 按功能扣费
# 之前计费逻辑和 LLM 代理耦合在一起
# 现在拆出来,任何功能都可以独立计费
CLASS FeatureBillingService:
"""功能计费 — 按功能扣费,与客户端 FC 拦截层对齐"""
ASYNC DEF charge(self, user_id: str, feature: str, tokens: int = 0):
# 1. 查询功能定价
pricing = AWAIT self.get_pricing(feature)
# LLM 类功能:按 token 计费
IF pricing.billing_type == "token":
cost = pricing.unit_price * tokens / 1000
# 固定计费功能:按次计费
ELIF pricing.billing_type == "fixed":
cost = pricing.unit_price
# 2. 扣费(冻结 → 结算 → 退款 三步事务)
AWAIT self.credit_service.deduct(user_id, cost, feature)
RETURN BillingResult(cost=cost, balance=AWAIT self.get_balance(user_id))
遇到的问题
- 错误码范围划分争议:积分和 LLM 的错误码边界模糊。最终决定按业务域分段:1001-1999 积分、2001-2999 LLM、4001-4099 通用
- 功能计费和 LLM 代理的 token 计费有重叠:LLM 代理本身也要扣费,但功能计费也要扣。解决方案:LLM 代理走 token 计费,功能走固定计费,互不干扰
- 前端 vitest 配置和 Vue 3 的兼容问题:需要额外配置 @vitejs/plugin-vue
明日计划
- 错误统一处理在所有 Service 层落地,替换裸 raise HTTPException
- 支付模块微信支付对接
- 调度器引擎生命周期测试