07-five-dimension.md 18 KB

用户使用场景 · 五维指标变化(本轮新增专项)

来源:EnergyController(/api/energy/*)、EnergyRuleEngine、EnergyService、DimensionDailyLimit、EnergyBalance/EnergyLog、AttributionWeights、ManualDimensionScoreController、FiveDimensionSelfCheckController、HealthReportController、AssessmentAppointmentService、DailyCheckinService、GameRecordService、GrowthTaskService、ArticleService/ActivityService。 关联用例:test-cases/*.md 的 SC-P-87~93 / SC-C-24~25 / SC-T-30~32 / SC-A-25~26 / SC-X-19~21。 设计原则:本文件补齐「五维指标变化」专项——即指标如何随行为触发、如何按规则归因/限流/刷新/重算、如何溯源与隔离,与 应用场景总览.md 中仅"查看/流水/配置查看"的 SC-P-17/18/19 形成闭环。

异常流口径:下列每条场景均给出「具体故障注入 + 可判定断言」,不再使用"系统给出明确错误提示而非 500"等模板文案。


场景 ED-1(家长):任务完成触发五维能量按规则归因增长

用户故事:作为家长,我希望孩子每完成一项任务,对应维度的五维能量能按规则准确增加,并能追溯到来源,以便激励可视化、可核对。

  • 角色:家长(触发侧)/ 孩子(受益侧 memberId)
  • 前置条件:测试家庭1 含孩子 B;EnergyRuleEngine 已配置任务→维度归因规则;B 当前各维度 EnergyBalance.balance 已知。
  • 主流程
    1. 孩子 B 完成任务 → 家长在 POST /api/task/approve 通过审批(TaskController/PointsController)。
    2. 系统按 EnergyRuleEngine 将任务类型映射到的维度(身/心/智/行/富之一或多)增加 amount。
    3. 写 EnergyLog:memberId=B、dimensionId、正 amount、balanceAfter、 sourceType=task、sourceId=任务实例ID。
    4. 对应维度 EnergyBalance.balance 与 totalEarned 同步 +amount;概览/沙盘随新值刷新。
  • 异常/边界
    • 重复审批(同一条任务实例二次通过):幂等,不重复加能量;EnergyLog 不产生第二条。
    • 任务类型未配置归因维度:落到兜底维度或记 sourceType=task 但不加(按规则),不得 500。
    • 审批接口参数非法(空 taskId/非本家庭成员任务):统一 400,不改动任何能量。
    • amount 计算异常(规则返回 null/负):拒绝执行并告警,不写脏流水。
  • 关联用例:TC-P-87(正常)/ TC-P-87-E(异常)/ TC-P-87-P(权限)

场景 ED-2(家长):心愿兑换扣减五维能量,余额不为负

用户故事:作为家长,我希望孩子用能量兑换心愿时,对应维度能量被正确扣减且永不为负,以便账目可信。

  • 角色:家长(审批兑换)/ 孩子(发起心愿)
  • 前置条件:孩子 B 已提心愿且积满所需能量;B 某维度 balance ≥ 兑换额,另造一条 balance 不足的对照用例。
  • 主流程
    1. 家长通过心愿兑换 → POST /api/energy/deduct-for-wish。
    2. 系统校验 balance ≥ 兑换额 后扣减,EnergyLog 记负 amount、balanceAfter = balance - 兑换额。
    3. 对应维度 balance 与 totalSpent 同步更新;心愿置为"已兑换"。
  • 异常/边界
    • 余额不足:扣减被拒,返回明确"能量不足",心愿保持待审批,不出现负余额。
    • 并发兑换同一心愿:仅一次成功,第二次因"已兑换"幂等拒绝,不重复扣。
    • 已兑换心愿再提交驳回/兑换:拒绝,不产生负流水。
    • deduct-for-wish 参数非法(空 wishId/非本家庭心愿):400,不扣减。
  • 关联用例:TC-P-88 / TC-P-88-E / TC-P-88-P

场景 ED-3(家长/运营):手动发放能量 grant

用户故事:作为家长或运营,我希望能手动给家庭成员某个维度加能量(奖励/补偿),并留痕可查。

  • 角色:家长(限本家庭)/ 运营(全平台)
  • 前置条件:目标成员 B 存在;POST /api/energy/grant 可用。
  • 主流程
    1. 调用 POST /api/energy/grant 指定 memberId、维度、amount、备注。
    2. 写 EnergyLog:sourceType=manual,balanceAfter 更新;EnergyBalance 同步 +amount。
  • 异常/边界
    • 负额/超大额(超过业务上限):拦截 400,不发放。
    • 非本家庭成员(家长给别的家庭发):403 拒绝(权限流)。
    • 重复发放同一工单号:按幂等/业务规则处理,不重复加。
    • 维度编码非法(dimensionCode 不存在):400,不写脏数据。
  • 关联用例:TC-P-89 / TC-P-89-E / TC-P-89-P

场景 ED-4(家长):五维每日获取上限 DailyLimit

用户故事:作为家长,我希望每个维度每天获取的能量有上限,避免刷分,次日自动重置。

  • 角色:孩子(触发)/ 家长(查看与配置生效观察)
  • 前置条件:DimensionDailyLimit 已配置某维度 dailyLimit=N;B 当日该维度已累计接近 N。
  • 主流程
    1. 当日多次触发该维度能量(任务/打卡/活动/手动)。
    2. 累计达 dailyLimit 后,新增触发不再累加(或按规则截断到上限)。
    3. 跨日 00:00 后累计清零,可重新获取。
  • 异常/边界
    • 多来源(任务+打卡+活动)共享同一日上限:任一来源达成后其余来源同维度均受限。
    • 手动 grant 是否计入日上限:按规则(一般手动不计入或单独口径),需断言一致。
    • 时钟/跨时区边界:以服务端日期为准,不因客户端时间绕过。
    • 日上限配置为 0 或负数:拒绝配置或按 0 处理,不得崩溃。
  • 关联用例:TC-P-90 / TC-P-90-E / TC-P-90-P

场景 ED-5(家长/规划师):健康报告入库刷新五维评分

用户故事:作为家长/规划师,我希望菌群/健康报告确认入库后,五维(及七维/六维健康维度)评分被刷新,并能看到前后变化与趋势。

  • 角色:家长(自身家庭)/ 规划师(绑定家庭)
  • 前置条件:持有募极生物菌群 PDF;报告预览已完成(SC-P-22/SC-T-03)。
  • 主流程
    1. 报告确认入库(SC-P-23/SC-T-03)→ HealthReportController 解析结果写入 HealthDimensionScore(七维/六维)。
    2. 五维概览/沙盘/score-history 按新评分重算。
    3. POST /api/energy/score-history、/family-score-history 可拉取时间序列,趋势图反映改善。
  • 异常/边界
    • 入库前取消:不刷新任何维度,原评分保留。
    • 报告类型不一致(如两次非同类报告):对比/趋势被拒或提示"类型不一致",不串维度。
    • 解析结果缺某维度字段:该维度保持上一值或空态,不 500。
    • 重复入库同一报告:幂等,不重复刷新。
  • 关联用例:TC-P-91 / TC-P-91-E / TC-P-91-P(e2e: tests/e2e/flora-microbiome-flow.spec.js、health-report-audit.spec.js)

场景 ED-6(家长/运营):五维权重与来源比例配置变更后重算

用户故事:作为家长/运营,我希望调整维度权重或能量来源比例后,概览/沙盘/家庭天盘按新权重重算,且存量数据有提示。

  • 角色:家长(查看生效)/ 运营(配置 configureSourceRatios、权重 CRUD)
  • 前置条件:POST /api/energy/configure 与维度权重配置可用;存量能量数据存在。
  • 主流程
    1. 运营调整来源比例/权重 → 配置生效。
    2. 概览/沙盘/家庭天盘按新口径重算并展示。
    3. 存量数据的重算影响给出提示("配置变更影响存量")。
  • 异常/边界
    • 权重之和 ≠ 100%:报警并拒绝或按归一化处理,不得静默错算。
    • 配置未同步到前端/缓存:展示兜底旧值并提示"配置同步中",不显示错乱比例。
    • 非 admin 改全局权重:403(权限流)。
    • 比例参数非法(负/超 1):400 拦截。
  • 关联用例:TC-P-92 / TC-P-92-E / TC-P-92-P(e2e: tests/e2e/energy-rules-config.spec.js)

场景 ED-7(家长/孩子):文章互动与活动参与触发五维能量

用户故事:作为家长/孩子,我希望发表/评论文章、参与平台活动也能获得能量,但受每日上限约束。

  • 角色:家长 / 孩子
  • 前置条件:ArticleService/ActivityService 能量发放规则已配置;当日维度未触顶。
  • 主流程
    1. 发布/评论文章或报名参与活动 → 触发 EnergyRuleEngine 对应维度 +amount。
    2. 写 EnergyLog(sourceType=article/activity);balanceAfter 更新。
  • 异常/边界
    • 刷量/机器行为(高频评论):风控拦截,不计能量。
    • 当日已触顶 DailyLimit:不再累加。
    • 内容含敏感词被下架:已发放能量按规则回收或保留(需断言),不双发。
    • 活动名额满/已结束:参与被拒,不发放。
  • 关联用例:TC-P-93 / TC-P-93-E / TC-P-93-P

场景 ED-8(孩子):小游戏/任务得分触发五维增长(仅自身可见)

用户故事:作为孩子,我希望玩游戏/完成任务获得的能量只加在我自己身上,且我只能看到自己的变化。

  • 角色:孩子
  • 前置条件:孩子 B 登录;小游戏/任务完成上报接口可用。
  • 主流程
    1. 完成小游戏/任务 → GameRecordService/TaskController 上报成绩 → 对应维度 +amount。
    2. B 在"能量与报告(只读)"页看到自身增长与流水。
  • 异常/边界
    • 异常分数(超评分上限/负分):拦截,不写能量。
    • 重复上报同一成绩:幂等,不重复加。
    • 越权查看他人能量:403(权限流)。
    • 孩子端无编辑/扣减入口:仅展示,不提供 grant/deduct。
  • 关联用例:TC-C-24 / TC-C-24-E / TC-C-24-P(e2e: tests/e2e/mini-games.spec.js、points-system.spec.js)

场景 ED-9(孩子):方案任务打卡触发五维增长

用户故事:作为孩子,我希望按成长方案打卡后获得对应维度能量,进度与能量同步。

  • 角色:孩子
  • 前置条件:方案已激活并生成启动任务(SC-C-05);打卡接口可用。
  • 主流程
    1. 打开方案启动任务 → 打卡提交(GrowthTaskService)。
    2. 对应维度 +amount,EnergyLog 记录;任务进度与能量同步刷新。
  • 异常/边界
    • 逾期限打卡:按业务允许或拒绝,断言一致(不静默加)。
    • 重复打卡同一任务:幂等,不重复加。
    • 非本人方案任务打卡:403(权限流)。
    • 打卡并发:不重复计分。
  • 关联用例:TC-C-25 / TC-C-25-E / TC-C-25-P(e2e: tests/e2e/daily-checkin-streak.spec.js、growth-record-sync.spec.js)

场景 ED-10(规划师):测评录入触发五维维度变化

用户故事:作为规划师,我希望录入孩子测评各维度分后,五维评分按规则引擎更新并生成方案。

  • 角色:规划师(绑定家庭)
  • 前置条件:测评订单已创建;AssessmentAppointmentService 规则引擎已配置 DAN 八类→五维映射。
  • 主流程
    1. 规划师录入各维度分(SC-T-07)→ 保存。
    2. 规则引擎将八类(mind/wisdom/cognition/learning/behavior/career/campus/adolescent)映射刷新五维评分。
    3. 触发生成 generated 方案;五维概览/沙盘刷新。
  • 异常/边界
    • 必填维度缺失:拦截 400,不生成半成品方案。
    • 重复录入:覆盖非新增,不产生重复评分记录。
    • 非绑定家庭录入:403(权限流)。
    • 录入分值越界(>量纲上限):拦截,不写脏分。
  • 关联用例:TC-T-30 / TC-T-30-E / TC-T-30-P(e2e: tests/e2e/dan-report-flow.spec.js、dan-assessment-vendor-flow.spec.js)

场景 ED-11(规划师):手动维度打分覆盖/调整

用户故事:作为规划师,我希望能手动调整某成员某维度分(覆盖当前值),并保留调整痕迹。

  • 角色:规划师(绑定家庭)
  • 前置条件:ManualDimensionScoreController 可用;目标成员 B 当前维度分已知。
  • 主流程
    1. 规划师提交某维度新分 → 覆盖/调整当前值并写调整记录。
    2. 五维概览/沙盘随新值刷新;调整留痕可审计。
  • 异常/边界
    • 越界分值(>上限):400 拦截。
    • 调整不影响其他维度:断言仅目标维度变化。
    • 非绑定家庭成员:403(权限流)。
    • 重复提交同值:幂等,不产生重复痕迹。
  • 关联用例:TC-T-31 / TC-T-31-E / TC-T-31-P

场景 ED-12(孩子/规划师):五维自评录入与变化

用户故事:作为孩子(或规划师代填),我希望通过五维自评微调自身维度,并仅本人/绑定家庭可见。

  • 角色:孩子(自评)/ 规划师(代录)
  • 前置条件:FiveDimensionSelfCheckController 可用。
  • 主流程
    1. 提交五维自评 → 维度微调,写 FiveDimensionSelfCheck 记录。
    2. 五维评分叠加自评结果;历史可查。
  • 异常/边界
    • 非本人/非绑定家庭自评:403(权限流)。
    • 自评分值越界:400 拦截。
    • 自评与测评/报告冲突:以规则优先级覆盖,断言确定。
  • 关联用例:TC-T-32 / TC-T-32-E / TC-T-32-P

场景 ED-13(运营):维度/权重/每日上限配置 CRUD 与生效

用户故事:作为运营,我希望能增删改维度、权重、每日上限配置,并让变更安全生效、影响后续计算。

  • 角色:运营(admin)
  • 前置条件:维度/权重/DimensionDailyLimit 配置管理接口可用。
  • 主流程
    1. 运营对维度、权重、每日上限做 CRUD。
    2. 变更生效,后续能量计算按新配置;存量影响给出提示。
  • 异常/边界
    • 删除被引用维度:需确认/拒绝,不得级联破坏存量数据。
    • 权重/上限非法(负/超界/和≠100%):400 拦截。
    • 非 admin 操作:403(权限流)。
    • 并发改同一配置:乐观锁/版本控制,不互相覆盖。
  • 关联用例:TC-A-25 / TC-A-25-E / TC-A-25-P(e2e: tests/e2e/energy-rules-config.spec.js)

场景 ED-14(运营):能量来源比例与归因权重治理

用户故事:作为运营,我希望治理能量来源比例与归因权重这一全局配置,变更有审计、影响可观测。

  • 角色:运营(admin)
  • 前置条件:AttributionWeights / configureSourceRatios 全局配置可用。
  • 主流程
    1. 调整来源比例/归因权重 → 全局生效。
    2. 变更写入审计;对概览/沙盘/家庭天盘的影响可观测。
  • 异常/边界
    • 非 admin 改全局:403(权限流)。
    • 比例非法(负/超 1/和≠1):400 拦截。
    • 配置未同步到计算节点:展示兜底并提示,不静默错算。
  • 关联用例:TC-A-26 / TC-A-26-E / TC-A-26-P

场景 ED-15(跨角色):五维能量跨角色数据隔离

用户故事:作为任一方,我只能访问本家庭/绑定家庭成员的能量与流水;任何横向越权都被拒。

  • 角色:跨角色(孩子/家长/规划师/运营)
  • 前置条件:家庭1(A+B+C)、绑定家庭 F2(规划师 T)、无关家庭 F9。
  • 主流程
    1. 各方查询自身/归属成员的能量概览、流水、评分历史。
    2. 越权查询他人/非绑定家庭能量接口。
  • 异常/边界
    • 孩子 token 查家长/规划师/运营接口:401/403。
    • 家长查其他家庭成员能量:403。
    • 规划师查非绑定家庭 F9 能量:403。
    • 运营查用户能量需工单授权,越权导出被拒。
  • 关联用例:TC-X-19 / TC-X-19-E / TC-X-19-P(e2e: tests/e2e/api/nonfunc-security.spec.js)

场景 ED-16(跨角色):五维能量流水溯源一致性(对账)

用户故事:作为对账方,我希望每条能量流水的 balanceAfter 都等于上一笔 balanceAfter + amount,且 totalEarned - totalSpent = balance,不一致即报警。

  • 角色:跨角色(运营/家长对账)
  • 前置条件:成员 B 有混合来源流水(任务/打卡/心愿扣减/手动)。
  • 主流程
    1. 拉取 EnergyLog 按时间排序,逐条校验 balanceAfter == prevBalanceAfter + amount。
    2. 校验 EnergyBalance.totalEarned - totalSpent == balance。
  • 异常/边界
    • 任一条不一致:报警并定位断点(不静默通过)。
    • 删除/回退产生的负流水:必须有对应负 amount 流水,余额不为负。
    • 并发写入导致顺序错乱:以服务端事务/版本保证顺序一致。
  • 关联用例:TC-X-20 / TC-X-20-E / TC-X-20-P

场景 ED-17(跨角色):多来源并发同成员能量变动

用户故事:作为系统,我希望同一成员同一维度被任务/打卡/小游戏/活动并发触发时,不超日上限、不重复加、余额一致。

  • 角色:跨角色(系统级并发)
  • 前置条件:成员 B 某维度当日未触顶;多个触发同时到达。
  • 主流程
    1. 并发提交多种触发(任务审批+打卡+小游戏+活动)。
    2. 校验:每笔原子加、总额不超过 DailyLimit、无重复加、最终 balance 与流水合计一致。
  • 异常/边界
    • 并发触顶:最后到达的被拒或截断,总额不超上限。
    • 部分失败:已成功的流水保留,失败的回滚不残半笔。
    • 重复请求(网络重试):幂等,不因重试多加。
  • 关联用例:TC-X-21 / TC-X-21-E / TC-X-21-P(e2e: tests/e2e/api/nonfunc-perf-compat.spec.js、energy-system.spec.js)