关联 SRS:
docs/superpowers/specs/2026-11-08-dx-health-bridge.md(GAP-A 契约,O-17 裁决,2026-11-08 合入 cfclub)。 能力键:health.dataSource.bridgeWrite;任务编号 S-cfc-129(契约/RED)→ S-cfc-130(实现,47d203981)。 实现基线:HealthDataSourceBridgeService(174 行)+HealthSyncServiceImpl/XiaomiHealthServiceImpl同事务接线 +schema.sqldata_source 注释扩DEVICE+DimensionScoreServiceImpl死注入解除。 派生自user-scenarios/的「家长绑定运动健康 → 同步 → 五维得分/档案可见」场景(D 域华为 / X 域小米)。 状态:实现已合入(2026-11-10 02:42),本文件由测试负责人在第 115 轮按 §3.1/§3.2/§4/§6 逐条落 TC 并绑定已执行用例。
| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
|---|---|---|---|---|---|---|---|---|---|---|
| TC-HB-01 | D/X-1 | 桥接宿主 | 系统 | P0 | 契约 | 后端 classpath | 1. Class.forName("com.etotem.cfc.service.HealthDataSourceBridgeService") |
宿主类存在且可实例化(§3.2-1 建议独立桥接服务) | §3.2-1 | HealthDataSourceBridgeContractTest#bridgeHost_classExists |
| TC-HB-02 | D/X-1 | 桥接宿主 | 系统 | P0 | 契约 | 同上 | 1. 反射查 bridge 方法签名 |
存在对外桥接方法,入参含 HealthDataSourceRecord(或批次 List) |
§3.2-1 | #bridgeHost_hasBridgeMethod |
| TC-HB-03 | D/X-2 | 华为同步 | 家长 | P0 | 功能 | mock step 数据点(body.exercise) |
1. 调 bridge 2. 校验落 health_dimension_scores |
member_id/dimension=exercise/score=normalized.score/percentile 直取;data_source=DEVICE;tier=2;raw_data=整条 parsedResult |
§3.1 全字段 | #bridge_huaweiStep_fieldMappingConformToSpec |
| TC-HB-04 | D/X-3 | 小米同步 | 家长 | P0 | 功能 | mock 小米同步行 | 1. 调 bridge 2. 校验映射 |
与华为同构:sourceType=xiaomi_health → 同一 DEVICE/tier=2 口径,映射表完全一致 |
§3.1 + §2.2 | #bridge_xiaomiStep_sameDeviceMapping |
| TC-HB-05 | D/X-2 | 体重双维展开 | 家长 | P0 | 功能 | mock body_weight 行 |
1. 调 bridge |
一条 source 产出 两行:nutrition + growth,两行 score 相同 |
§3.1 dimension 切分 | #bridge_bodyWeight_expandTwoDimensions |
| TC-HB-06 | D/X-2 | 未知维度丢弃 | 家长 | P1 | 异常 | mock dimension_codes="body.foo,body.sleep" |
1. 调 bridge |
非白名单码被丢弃,仅写 sleep,不抛异常、不写非法 dimension |
§3.1「未知码丢弃」 | #bridge_unknownDimensionCodes_dropped |
| TC-HB-07 | D/X-2 | 混合合法非法 | 家长 | P1 | 异常 | mock 合法 + 非法码混排 | 1. 调 bridge |
合法码全部写入、非法码一律不写(部分成功语义) | §3.1 | #bridge_mixedValidAndUnknown_writeOnlyValid |
| TC-HB-08 | D/X-2 | percentile 可空 | 家长 | P1 | 边界 | mock normalized.percentile=null |
1. 调 bridge |
仍写入得分行,percentile 落 NULL,不因空值中断整批 |
§3.1「percentile 可空」 | #bridge_percentileNull_stillWrites |
| TC-HB-09 | D/X-4 | 同日多源覆盖 | 家长 | P0 | 功能 | 同 member+dimension+assess_date 两条 source | 1. 先后桥接两条 | 读最新覆盖(created_at DESC LIMIT 1),最终得分=后一条 | §3.1 读最新覆盖 + §6 ④ 不加唯一索引 | #bridge_sameDayMultipleRows_latestWins |
| TC-HB-10 | D/X-5 | 不覆盖报告行 | 家长 | P0 | 回归 | 已存在 data_source=REPORT/tier=1 行 |
1. 桥接同维度 DEVICE 行 | 按 tier/data_source 分层保留:REPORT 行有效性不被降低/消灭(防负向回归) | §3.1 写入语义 | #bridge_mustNotOverwriteExistingReportRow |
| TC-HB-11 | D/X-2 | 华为同步接线 | 家长 | P0 | 集成 | HealthSyncServiceImpl |
1. 反射检查依赖与调用点 | 同步链路已注入桥接钩子(§6 ③ 触发点 A:同步内同事务) | §3.2-2 | #huaweiSyncEngine_injectBridgeHook |
| TC-HB-12 | D/X-3 | 小米同步接线 | 家长 | P0 | 集成 | XiaomiHealthServiceImpl |
1. 反射检查依赖与调用点 | 同 TC-HB-11(两引擎对称) | §3.2-2 | #xiaomiSyncEngine_injectBridgeHook |
| TC-HB-13 | D/X-1 | 死注入解除 | 系统 | P1 | 契约 | DimensionScoreServiceImpl |
1. 反射查 dataSourceRecordService 字段 |
字段已移除(死注入解除),不再是「注入但零调用」状态 | §3.2-1 | #dimensionScoreServiceImpl_deadInjectionResolved |
| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
|---|---|---|---|---|---|---|---|---|---|---|
| TC-HB-14 | D/X-6 | schema 枚举 | 系统 | P0 | 契约 | schema.sql |
1. 读 health_dimension_scores.data_source 注释 |
注释取值枚举含 DEVICE(§6 ① 已拍板) |
§4-1 + §6 ① | #schema_dimensionScores_dataSourceCommentContainsDevice |
| TC-HB-15 | D/X-6 | 不加唯一索引 | 系统 | P0 | 契约 | 同上 | 1. 检查 DDL 索引 | health_dimension_scores 无 (member_id,dimension,assess_date) 唯一索引(§6 ④ 已拍板) |
§4-2 + §6 ④ | #schema_dimensionScores_noUniqueIndex |
| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
|---|---|---|---|---|---|---|---|---|---|---|
| TC-HB-16 | D/X-7 | 鉴权归口 | 系统 | P1 | 权限 | 桥接为内部服务,无新增对外端点 | 1. 确认端点清单 | 本轮无新增 bridge/* 端点 → 权限维度「不适用」;D/X 既有端点鉴权由 TC-H-U01~U10 覆盖(线上 401 实测) |
§3.4 | #permissionFlow_notApplicable + e2e-live/health-contract.spec.js |
| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
|---|---|---|---|---|---|---|---|---|---|---|
| TC-HB-03-E | D/X-2 | 映射码全非法 | 家长 | P2 | 异常 | dimension_codes 全非法 |
1. 调 bridge |
零写入但不抛异常,同步主链路不回滚已成功的 source 落库 | §3.1 | #bridge_unknownDimensionCodes_dropped |
| TC-HB-08-E | D/X-2 | 归一化缺失 | 家长 | P2 | 异常 | parsed_result 无 normalized |
1. 调 bridge |
跳过该行(无得分不写),不产生 0 分脏行 | §3.1 | 未覆盖(缺口 G-115-1) |
| TC-HB-09-E | D/X-4 | 并发同秒写入 | 家长 | P2 | 并发 | 同秒两条 source | 1. 并发桥接 | 读最新覆盖语义仍成立(created_at 相同时按既有序稳定返回),不出现双行读歧义 | §3.1 | 未覆盖(缺口 G-115-1) |
| 缺口 | 规格条款 | 现状 | 建议补测 |
|---|---|---|---|
| G-115-1 | §5 E-1 的 E-2/E-3 | 桥接「同步 → /api/dimension/overview 读到新得分」(E-2)与「/api/health/indicators/current 可见 D/X 来源」(E-3)无 MockMvc 级用例;现有 16 例均为服务/反射/schema 级 |
补 2 个 MockMvc 契约:同步 mock → overview 新得分;indicators/current 含 source 字段 |
| G-115-2 | §3.3 B-1/B-2(小程序设备数据端点) | 端点未实现,E-4 无对象可测 | 实现后补「登录 401 / 有 token 正常 / 分页 + source_type 过滤」3 例 |
| G-115-3 | §3.3 B-3 + §5 E-5 | cfc-frontend 全仓仍 0 处 huawei-health/xiaomi-health 调用(2026-11-10 复验)→ 前端绑定/同步/状态卡链路零覆盖 |
前端落地后补 Playwright 3 条流(正常/异常/权限) |
口径声明:本文件只登记「已实现且已有用例」的 16 条 + 3 条异常流设计;G-115-1~3 属未实现/未覆盖,不得据本文件宣称 E-2/E-3/E-4/E-5 已通过。