You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digital-rmb-backend/docs/superpowers/specs/2026-09-23-module-2-4-5-inp...

3.4 KiB

模块 2、4、5 用户输入错误记录与评分设计

目标

让发行货币(模块 2)、数字货币兑换(模块 4)和数字货币支付(模块 5)沿用模块一的评分口径:用户提交的业务输入不正确时,后端持久化一次错误并扣分;越级操作、重复点击、缺少前置数据和系统异常不计入错误。

依据与现状

  • 模块一通过错误记录器在事务外记录错误次数,并同步成绩明细的完成进度、错误数和得分。
  • 模块 2、4、5 使用可恢复实验动作链。动作失败时动作事务会回滚,因此错误计分必须使用 REQUIRES_NEW,不能依赖动作主事务。
  • 模块 2 的用户输入集中在发行申请金额、币种、机构标识、面额明细和签名密钥;模块 4 集中在钱包、银行卡和兑换金额;模块 5 集中在付款/收款钱包、支付金额和备注。

设计

评分服务

在后端为三个模块各提供独立的成绩服务,复用统一成绩明细表 stu_module_score_details:

  • 模块 2:模块名“发行数字货币”,序号 2,7 个步骤。
  • 模块 4:模块名“数字货币兑换”,序号 5,5 个步骤。
  • 模块 5:模块名“用户支付数字货币”,序号 6,6 个步骤。

每个服务提供 recordError(userId)、markStepCompleted(userId, step) 和 detail(userId)。错误扣分规则与模块一一致,默认每次错误扣 0.50 分,并以当前完成进度折算项目得分。

错误分类

动作服务只在下列用户输入校验路径调用 recordError:

  • 模块 2:发行申请字段/面额明细非法、机构标识或银行代码不匹配、签名密钥不正确。
  • 模块 4:兑换钱包或银行账户不属于当前用户、兑换金额非法、用户签名或摘要输入校验失败。
  • 模块 5:付款钱包不属于当前用户、收款钱包无效、支付金额非法、备注超过限制。

顺序门禁(“请先完成动作”)、重复动作、动作状态冲突、找不到实验、业务前置数据缺失和内部异常不计分。

事务边界

动作服务在识别为“用户输入错误”的 BusinessException 时调用对应成绩服务的 recordError。成绩服务使用新事务,确保即使动作主事务回滚,错误记录和成绩更新仍然保留。错误响应继续返回原有业务提示,并追加错误序号,便于用户确认本次错误已计分。

前端行为

模块 2、4、5 不在前端本地重复计算分数。按钮请求沿用后端动作链,错误提示直接展示后端返回的业务消息;步骤回显继续读取动作历史和本地步骤记录。这样可避免前后端对“哪些错误计分”的判断不一致。

测试策略

后端为三个评分服务补单元测试,覆盖:

  1. 首次错误创建成绩明细、错误数为 1、得分按进度折算。
  2. 重复错误累计错误数并继续扣分。
  3. 完成步骤后再记录错误,完成进度保留且得分下降。
  4. 空用户标识不写入成绩。

为三个动作服务补行为测试,分别验证一个用户输入错误会增加一次错误,而顺序门禁异常不会增加错误。已有动作成功流程和前端构建测试保持通过。

不在本次范围

  • 不修改模块一既有评分口径。
  • 不把所有 HTTP 400 或所有 VALIDATION_ERROR 自动视为计分错误。
  • 不新增前端独立成绩缓存或视觉评分组件。