跳到主要内容

手表采集能力 → 复盘页消费映射方案

本文档定义 BlinkLife 手表端应采集哪些数据、这些数据如何支撑复盘页、第一版复盘页的能力边界,以及数据缺失时的降级策略。


A. 产品结论与优先级判断

1. 为什么必须先明确手表采集能力,而不是直接堆复盘页 UI

结论:复盘页的价值上限 = 底层数据的可信度上限。

当前手表端仅支持打点事件(single_press/double_press/long_press → 高光/失误/撤销),没有心率、GPS、速度等任何传感器采集。如果直接画复盘页 UI,只能做出一个"打点统计面板",与现有回放页的 StatsCard 高度重复,无法体现复盘页的独立价值。

先定义采集能力,才能确定复盘页到底"有什么数据可以说话"。

2. 第一版复盘页为什么不能追求复杂报表化

结论:消费级运动产品的复盘不是教练报表,是"一眼看懂这场练了什么"。

三个硬约束:

  • 数据约束:手表传感器数据第一版必然有断点、异常、缺失,不足以支撑精细报表
  • 用户约束:目标用户是业余运动爱好者,不是专业教练,看不懂也不需要双 Y 轴曲线
  • 竞争约束:Strava/佳明已经在专业报表上做到极致,BlinkLife 的差异化是"事件时间轴 + 视频回放 + AI 摘要",不是报表

3. 当前最合理的推进顺序

Step 1: 手表端补齐 P0 传感器采集(心率 + 基础运动量)
Step 2: 定义统一数据模型 + 落库方案
Step 3: 复盘页 MVP(总览 + 事件分布 + 心率趋势 + AI 摘要)
Step 4: 补齐 P1 数据(GPS 轨迹 + 强度区段)→ 复盘页增强

4. 必须先做 vs 必须延后

必须先做必须延后
心率连续采集GPS 轨迹热图
Session 生命周期管理专业级冲刺分析
统一时间戳同步高级 AI 战术结论
数据质量标记多场次对比分析
传感器数据落库社交排行榜

B. 采集能力分层

P0:必须先做稳

1. Session(会话管理)

维度说明
采集内容录制开始/暂停/恢复/结束的精确时间戳、运动类型、设备来源
为什么 P0没有 Session,所有数据都是散点,无法形成"这场训练"的整体概念
不做的影响复盘页无法回答"这场练了多久"、时间轴无法对齐
支撑复盘页总览卡片(时长/运动类型)、时间轴骨架、AI 摘要的时间范围

2. Event Marker(事件打点)— 已实现

维度说明
采集内容时间戳、动作类型、输入源、置信度
为什么 P0已实现且是 BlinkLife 核心能力,需要增强字段(confidence/weight/is_revoked)
不做的影响无法区分高质量事件和误触事件
支撑复盘页事件分布图、AI 高光推荐、回放页联动锚点

3. Unified Timestamp(统一时间戳)

维度说明
采集内容手表与手机的时钟偏移量(在 Session 开始时交换一次 NTP 或本地时间差)
为什么 P0手表和手机的系统时间可能差几秒到几十秒,不同步就无法对齐
不做的影响手表打的点和视频时间轴偏移,复盘页结论和视频画面对不上
支撑复盘页所有时间轴对齐、所有"点击跳转回放"功能的基础

4. Heart Rate(心率)

维度说明
采集内容连续心率(建议 1Hz 采样)、静息心率、最大心率
为什么 P0心率是消费级运动产品用户最关心的指标,采集成本最低(手表内置),可信度最高
不做的影响复盘页缺少核心数据轴,只能展示打点统计,与回放页高度重复
支撑复盘页心率趋势曲线、平均/峰值心率、强度区段划分、AI "这段时间你很拼"

5. Quality State(数据质量状态)

维度说明
采集内容每种数据源的质量标记(good/degraded/unavailable)、断点区间、置信度
为什么 P0没有质量标记,页面不知道哪些数据可信、哪些该隐藏,AI 不知道哪些结论该保守
不做的影响展示错误数据 → 用户失去信任 → 功能报废
支撑复盘页降级显示策略、AI 输出约束、"数据不完整"提示

P1:建议尽快补齐

6. Speed(速度)

维度说明
采集内容瞬时速度(m/s),来源于 GPS 或加速度计推算
为什么 P1速度数据在室内场景(篮球馆/羽毛球馆)GPS 信号差时极不可信,需要 P0 心率先稳
不做的影响复盘页无法展示冲刺片段,AI 无法判断"高强度跑动"
支撑复盘页速度趋势、冲刺区段识别、AI "第 25 分钟你冲了一次全速"

7. Distance(距离)

维度说明
采集内容累计距离(米),基于 GPS 轨迹积分或步频估算
为什么 P1依赖 GPS 或计步器,室内精度低,需和 Speed 一起做
不做的影响无法显示"跑了多少公里",对跑步/足球场景影响大
支撑复盘页总览数据(总跑动距离)、每节距离对比

8. Intensity Segment(强度区段)

维度说明
采集内容基于心率 + 速度的强度分段(热身/有氧/无氧/极限),客户端或服务端计算
为什么 P1依赖 P0 心率数据稳定后才能计算,不是原始采集项
不做的影响复盘页只有原始心率曲线,缺少"这段时间是高强度"的语义
支撑复盘页强度分布饼图、时间轴色带、AI "上半场 60% 时间处于有氧区"

P2:后续增强

9. Route / Position(轨迹 / 活动区域)

维度说明
采集内容GPS 经纬度序列(1-5Hz),室内需 UWB/蓝牙定位替代
为什么 P2GPS 功耗高、室内不可用、轨迹渲染复杂度高,MVP 不需要
不做的影响无热力图、无活动区域分析,对足球场景有影响但不阻塞 MVP
支撑复盘页轨迹回放、热力图、活动区域分析、AI "你主要活动在左路"

10. Sprint Segment(冲刺区段)

维度说明
采集内容基于速度阈值(如 20km/h 以上)的冲刺检测 + 加速度峰值
为什么 P2依赖 P1 速度数据可信后才能做,且阈值需按运动类型调参
不做的影响无法自动标记冲刺片段,AI 无法分析爆发力表现
支撑复盘页冲刺列表、冲刺速度排行、AI "全场最快冲刺出现在第 38 分钟"

C. 采集能力 → 复盘页消费映射表

采集项手表侧采集内容复盘页用途复盘页模块回放页联动优先级主要风险降级建议
Session开始/暂停/恢复/结束时间总览时长、节次划分总览卡片无直接联动(提供时间范围)P0暂停/恢复漏报缺失时用首尾打点时间估算
Event Marker时间戳+动作+来源+置信度事件分布、高光推荐事件分布图、AI 推荐点击事件→回放页 seek 到对应时间P0误触/重复打点confidence 低于 0.5 的事件灰显
Timestamp Sync手表-手机时钟偏移所有时间对齐的基础不直接展示保证跳转精度P0运动中时钟漂移首尾各同步一次取平均
Heart Rate1Hz 连续心率心率趋势、平均/峰值、强度判断心率趋势卡片、总览数据点击心率峰值→回放页 seekP0信号断点、异常跳变断点超过 30s 显示虚线,异常值过滤
Quality State各数据源质量标记控制展示/隐藏/降级全局影响低质量区间禁止跳转P0漏报质量问题缺省为 degraded 而非 good
Speed瞬时速度 m/s速度趋势、冲刺标记速度趋势卡片点击冲刺区段→回放页播放区间P1室内 GPS 漂移质量差时隐藏速度模块
Distance累计距离总跑动距离总览数据无直接联动P1室内不准质量差时标注"估算"
Intensity Segment心率+速度→强度分段强度分布、时间轴色带强度分布卡片点击区段→回放页播放区间P1心率阈值因人而异用通用公式,标注"参考值"
Route / PositionGPS 经纬度序列轨迹回放、热力图轨迹卡片点击热区→过滤该区域事件P2室内不可用、功耗高无轨迹时完全隐藏该模块
Sprint Segment速度阈值冲刺检测冲刺列表和排行冲刺分析卡片点击冲刺→回放页 seekP2依赖速度可信速度质量差时不生成冲刺

D. 统一数据模型

1. Session(训练会话)

Session {
id: string [必填] UUID
start_time: DateTime [必填] UTC 录制开始时间
end_time: DateTime? [必填] UTC 录制结束时间(进行中为 null)
pauses: List[TimePair] [增强] 暂停-恢复时间对列表
sport_type: string [必填] 运动类型
device_sources: List[str] [必填] 使用的设备 ['phone','watch','ble_ring']
status: enum [必填] active | paused | completed | interrupted
clock_offset_ms: int? [必填] 手表与手机的时钟偏移(毫秒)
recording_id: int? [增强] 关联的 RecordingRecord ID
video_path: string? [增强] 关联的视频路径
}

用途:复盘页的顶层容器,定义"这场训练"的时间范围和元数据。所有数据必须归属于一个 Session。

2. EventMarker(事件标记)

EventMarker {
id: int [必填] 稳定 ID(= timestamp 毫秒值)
session_id: string [必填] 所属 Session
timestamp: DateTime [必填] UTC 绝对时间
recording_time: Duration [必填] 相对 Session 开始的偏移
event_type: string [必填] 动作类型('射门','犯规'等)
event_subtype: string? [增强] 动作子类型('左脚射门')
source_device: string [必填] 'ble_ring' | 'gesture' | 'watch' | 'manual'
confidence: double [必填] 0.0-1.0,默认 1.0(手动=1.0, 手表单击=0.9, AI推断=0.6)
weight: int [AI预留] 重要性权重(AI 排序用)
is_revoked: bool [必填] 是否已撤销(长按撤销)
note: string? [增强] 用户备注
tags: List[string]? [AI预留] AI 标签('关键进攻','防守失误')
}

用途:复盘页事件分布图的数据源,AI 高光推荐的输入。与现有 DotRecord 兼容,增加 confidence/weight/is_revoked 字段。

与现有 DotRecord 的关系:EventMarker 是 DotRecord 的超集。迁移策略:DotRecord 保持不变用于回放页,EventMarker 用于复盘页消费,两者通过 id + timestamp 关联。

3. SensorSample(传感器采样)

SensorSample {
session_id: string [必填] 所属 Session
timestamp: DateTime [必填] UTC 采样时间
heart_rate: int? [P0] 心率(bpm),null 表示该采样无心率
speed: double? [P1] 瞬时速度(m/s)
distance_increment: double? [P1] 距离增量(m),累计求和得总距离
latitude: double? [P2] GPS 纬度
longitude: double? [P2] GPS 经度
altitude: double? [P2] 海拔(m)
quality_flag: enum [必填] good | degraded | interpolated | unavailable
}

用途:复盘页心率趋势、速度趋势的数据源。1Hz 采样,一场 90 分钟训练约 5400 条记录。

存储策略:本地 SQLite 独立表 sensor_samples(按 session_id 索引)。数据量可控,不需要时序数据库。

4. Segment(语义区段)

Segment {
id: string [必填] UUID
session_id: string [必填] 所属 Session
start_time: DateTime [必填] 区段开始
end_time: DateTime [必填] 区段结束
segment_type: enum [必填] intensity | sprint | rest | warmup | custom
intensity_level: enum? [P1] light | moderate | vigorous | max(心率区间)
avg_heart_rate: int? [P1] 区段平均心率
peak_speed: double? [P1] 区段最高速度
avg_speed: double? [P1] 区段平均速度
distance: double? [P1] 区段距离
linked_events: List[int] [增强] 区段内的 EventMarker ID 列表
source: enum [必填] auto_detected | user_defined | ai_suggested
confidence: double [必填] 0.0-1.0
}

用途:复盘页强度分布图、冲刺列表的数据源。由客户端或服务端根据 SensorSample 计算生成,不是原始采集。

5. ReplayAnchor(回放锚点)

ReplayAnchor {
id: string [必填] UUID
session_id: string [必填] 所属 Session
source_type: enum [必填] event | segment | ai_highlight | peak_hr | sprint
anchor_time: DateTime [必填] 锚定到的绝对时间
display_time: Duration [必填] 在视频中的显示时间(经过对齐)
linked_video_path: string? [必填] 关联的视频文件
offset_ms: int [必填] 跳转偏移(如事件前移 5 秒)
linked_event_ids: List[int] [增强] 关联的事件 ID 列表
title: string [必填] 显示标题("第 12 分钟 射门")
description: string? [AI预留] AI 生成的描述
}

用途:复盘页中所有"点击跳转到回放页"的载体。复盘页不直接操作视频,而是生成 ReplayAnchor,传递给回放页执行跳转。

6. QualityState(数据质量状态)

QualityState {
session_id: string [必填] 所属 Session
data_type: enum [必填] heart_rate | speed | gps | event | session
quality_level: enum [必填] good | degraded | unavailable
reason: string? [增强] 'signal_lost' | 'indoor_no_gps' | 'sensor_off'
missing_ranges: List[TimePair] [增强] 缺失的时间区间列表
confidence_score: double [必填] 0.0-1.0 综合可信度
sample_count: int [增强] 有效采样数
expected_count: int [增强] 应有采样数(sample_count/expected_count = 覆盖率)
}

用途:复盘页的全局降级控制器。页面渲染前先查 QualityState,决定哪些模块展示、哪些隐藏、哪些标注"数据不完整"。AI 生成前先查 QualityState,决定哪些结论可以给、哪些必须保守。


E. 第一版复盘页 MVP 边界

必须上线的模块

1. 本场总览卡片

维度说明
展示内容运动类型、总时长、总打点数、平均心率、峰值心率、总距离(如有)
依赖数据Session + EventMarker 统计 + SensorSample 聚合
可信度高(Session 和打点是 P0,心率采集稳定后可信)
与回放页联动无直接联动,点击时长可展开节次明细
为什么现在做用户进入复盘页的第一眼,必须回答"这场练了什么"

2. 事件分布图

维度说明
展示内容时间轴上的事件分布(按动作类型着色),支持按类型筛选
依赖数据EventMarker 列表
可信度高(基于已有打点数据)
与回放页联动点击任意事件 → 生成 ReplayAnchor → 跳转回放页
为什么现在做复盘页的核心差异化:全局视角看事件分布,回放页只能线性浏览

3. 心率趋势曲线(简版)

维度说明
展示内容时间轴上的心率折线图,叠加事件 marker,标注峰值点
依赖数据SensorSample.heart_rate + EventMarker
可信度中(心率断点用虚线表示,覆盖率低于 60% 时降级为仅数值)
与回放页联动点击心率峰值 → 生成 ReplayAnchor → 跳转回放页
为什么现在做心率是用户最关心的运动指标,且手表采集成本最低

4. AI 摘要(保守版)

维度说明
展示内容2-4 句话的训练摘要(训练概况 + 强度评价 + 高光推荐 + 建议)
依赖数据Session + EventMarker + SensorSample 聚合统计
可信度中(基于统计数据生成,不做因果推断)
与回放页联动摘要中的"高光时刻"可点击 → 跳转回放页
为什么现在做AI 摘要是 BlinkLife 相对 Strava/佳明的核心差异化

5. 推荐片段列表

维度说明
展示内容AI 推荐的 3-5 个值得回看的片段(缩略图 + 时间 + 原因)
依赖数据EventMarker(按 confidence × weight 排序)+ 心率峰值
可信度高(基于已有数据排序,不做复杂推理)
与回放页联动点击片段 → 跳转回放页播放,可一键剪辑
为什么现在做帮用户快速找到"最值得看的几个瞬间",是复盘页到回放页的核心桥梁

建议延后的模块

模块为什么延后依赖条件
GPS 轨迹热力图室内不可用、GPS 数据 P2 优先级、渲染复杂P2 Route 数据
双 Y 轴心率+速度曲线速度数据 P1、两轴对齐复杂、用户理解成本高P1 Speed 稳定
冲刺详细分析依赖速度+加速度、阈值需调参P2 Sprint Segment
节次对比雷达图需要暂停/恢复机制稳定、数据量足够Session.pauses 稳定
高级 AI 洞察需要足够数据积累和模型训练多场次数据沉淀
多场次趋势对比需要至少 5+ 场数据、后端存储云端数据积累

F. 回放页与复盘页的联动规则

核心原则

复盘页 = 理解页(看全局、看数据、看结论)
回放页 = 操作页(看视频、做剪辑、细操作)

联动方向:复盘页 → 回放页(复盘页发出意图,回放页执行操作)
反向联动:回放页 → 复盘页(仅"查看复盘"入口,不传递操作状态)

1. 单点时间锚点联动

场景:点击复盘页上的某个事件/心率峰值/AI 推荐片段

跳转规则

复盘页点击
→ 构造 ReplayAnchor {
anchor_time: 事件绝对时间,
offset_ms: -5000, // 前移 5 秒
linked_event_ids: [事件ID],
title: "第 12 分钟 射门"
}
→ Navigator.push(ReviewDetailPage, args: {
record: RecordingRecord,
replayAnchor: ReplayAnchor, // 新参数
})
→ 回放页 initState 检测 replayAnchor
→ session.seek(anchor.display_time, source: seekExternal, dotId: anchor.linked_event_ids[0])
→ EventsCard 自动滚动到对应事件并高亮

2. 区间联动

场景:点击复盘页的"第 20-30 分钟高强度区间"或某个 Segment

跳转规则

复盘页点击区间
→ 构造 ReplayAnchor {
anchor_time: 区间开始时间,
offset_ms: 0,
linked_event_ids: segment.linked_events, // 区间内的所有事件
}
→ 跳转回放页
→ 回放页:
1. seek 到区间开始时间
2. TimelineToolbar 不自动筛选(保持全部可见)
3. EventsCard 高亮区间内的事件(通过 linked_event_ids)
4. 时间轴上显示区间高亮色带

3. 片段集合联动

场景:点击"AI 推荐高光 Top 5"或"全部射门事件"

跳转规则

复盘页点击集合
→ 构造 ReplayAnchor 列表(多个锚点)
→ 跳转回放页,args: replayAnchors 列表
→ 回放页进入"集合浏览模式":
1. seek 到第一个锚点
2. 操作栏的"上一条/下一条"在锚点集合内导航(而非全部打点)
3. EventsCard 仅显示集合内的事件(临时筛选)
4. AppBar 标题显示"AI 推荐 · 1/5"
5. 右上角退出集合模式按钮

4. 剪辑联动

场景:复盘页推荐的片段直接进入剪辑

跳转规则

复盘页长按推荐片段 → 弹出操作菜单
→ "剪辑此片段"
→ 跳转回放页,args: { replayAnchor, autoClip: true }
→ 回放页 initState 检测 autoClip=true
→ 自动调用 _clipSingleDot(anchor.linked_event_ids[0])

→ "剪辑全部推荐"
→ 跳转回放页,args: { replayAnchors, autoClipAll: true }
→ 回放页提交批量剪辑任务

页面间状态传递方式

// 新增路由参数
class ReviewDetailPageArgs {
final RecordingRecord record;
final bool fromRecording;
final ReplayAnchor? replayAnchor; // 单点跳转
final replayAnchors: List of ReplayAnchor?; // 集合浏览
final bool autoClip; // 自动剪辑
}

G. 复盘页降级策略

场景 1:没有轨迹 / GPS 不可信

维度策略
QualityStategps: unavailable 或 confidence 低于 0.3
页面展示完全隐藏轨迹/热力图模块,不显示占位符
总览卡片隐藏"总距离"字段,或标注"距离数据不可用"
AI 表达不提及跑动距离、活动区域,不生成"你主要在左路活动"类结论

场景 2:心率数据断点较多

覆盖率策略
≥80%正常显示曲线,断点用虚线连接
60%-80%显示曲线但标注"部分时段数据缺失",AI 仅使用有数据区间
40%-60%不显示趋势曲线,仅显示平均心率和峰值心率数值
低于 40%隐藏心率模块,AI 不引用心率数据

场景 3:速度数据异常跳变

维度策略
检测规则相邻采样速度差超过 15 km/h 视为异常
数据处理异常点标记 quality_flag=degraded,不参与计算
页面展示过滤异常点后显示,最高速度取过滤后的 P95 而非最大值
AI 表达使用"约"前缀("最高速度约 22km/h"),不给精确值

场景 4:Session 不完整 / 会话中断

维度策略
Session.status = interrupted总览卡片标注"本次训练记录不完整"
时长计算使用实际有数据的时间范围,不使用 start_time 到 end_time
复盘页允许查看,但 AI 摘要开头声明"本次记录不完整,以下分析仅基于已采集数据"
跳转回放正常允许,但无数据区间的锚点不生成

场景 5:外部视频时间未准确对齐

维度策略
检测条件RecordingRecord.recordType == 2 或 3 且 alignOffsetMs 为 null
复盘页展示数据分析(不依赖视频对齐),但所有"查看片段"按钮灰显
提示文案"视频尚未对齐,请在回放页完成对齐后再查看相关片段"
AI 表达正常生成摘要(基于打点数据),但不推荐"查看片段"

H. AI 复盘的边界与约束

第一版 AI 可以做什么

能力输入数据输出示例可信度
训练摘要Session + EventMarker 统计"本场足球训练 87 分钟,共标记 23 个事件,其中射门 8 次、犯规 3 次"
强度评价平均心率 + 心率区间分布"整体强度中等偏上,72% 时间处于有氧区"中(依赖心率可信)
高光推荐EventMarker.confidence × 心率峰值关联"推荐查看第 12 分钟和第 38 分钟的射门,当时心率达到峰值"
节奏总结事件密度 + 心率趋势"上半场事件密集,下半场节奏放缓"
保守型提示心率异常高/事件密度异常"第 25-30 分钟心率持续偏高,建议关注该时段表现"低(仅提示)

第一版 AI 不应该做什么

禁止行为原因替代方案
"你的射门质量下降了"无动作质量数据,纯臆测"下半场射门次数减少"
"你应该加强左脚训练"无左右脚区分数据不输出
"你的防守位置不对"无轨迹数据,无法判断位置不输出
"你的体能不如上周"无多场次对比(MVP 阶段)不输出
"这次犯规是因为注意力不集中"因果推断无数据依据"第 40 分钟出现犯规"

AI 生成的数据依赖矩阵

AI 结论类型必须有的数据缺失时行为
训练时长摘要Session不生成 AI 摘要
事件统计EventMarker ≥ 1 条"本场未记录到事件"
强度评价心率覆盖率 ≥ 60%跳过强度评价段落
高光推荐EventMarker ≥ 3 条"事件较少,建议下次更频繁标记"
节奏分析Session 时长 ≥ 15 分钟 + EventMarker ≥ 5 条跳过节奏段落

避免"AI 看起来很懂但没依据"的规则

  1. 每个 AI 结论必须标注数据来源:摘要末尾注明"基于 23 个打点事件和 87 分钟心率数据"
  2. 使用模糊量词而非精确数值:心率覆盖率低于 80% 时用"约"、"大致"
  3. 不使用因果连接词:禁止"因为...所以..."、"导致...",只用"同时..."、"期间..."
  4. 置信度低的结论用疑问句:不说"你累了",说"第 70 分钟后事件频率下降,是否感到疲劳?"

I. 推进顺序

Step 1:手表端 P0 数据采集(2-3 周)

维度说明
目标手表端能稳定采集心率 + 管理 Session 生命周期 + 时间戳同步
产出WearOS/watchOS 心率采集模块、Session 管理协议、时钟同步方案
为什么先做没有数据就没有复盘页,心率是 ROI 最高的传感器
不做什么不做 GPS、不做速度、不做复盘页 UI、不做 AI

Step 2:统一数据模型 + 落库(1-2 周,与 Step 1 并行)

维度说明
目标定义 Session/EventMarker/SensorSample/QualityState 的 Dart 模型和 DB 表
产出数据模型代码、DB v14 迁移、数据写入/查询 Service
为什么先做Step 1 采集的数据需要有地方存,复盘页需要有数据源可读
不做什么不做 Segment 自动计算、不做 ReplayAnchor 生成

Step 3:复盘页 MVP(2-3 周)

维度说明
目标上线 5 个模块:总览 + 事件分布 + 心率趋势 + AI 摘要 + 推荐片段
产出复盘页 UI + ReplayAnchor 联动 + 降级策略实现
为什么先做P0 数据稳定后立即可验证复盘页的用户价值
不做什么不做速度/轨迹相关模块、不做冲刺分析、不做多场次对比

Step 4:P1 数据 + 复盘页增强(持续迭代)

维度说明
目标补齐速度/距离采集、自动 Segment 计算、强度分布模块
产出速度传感器模块、Segment 计算引擎、复盘页强度卡片
为什么后做速度数据可信度依赖场景(室内 vs 室外),需要积累真实数据调参
不做什么不做 GPS 轨迹热图(P2)、不做高级 AI 战术分析

J. 给研发团队的建议

1. 必须先抽象成统一层的模块

模块原因
SensorDataService统一管理所有传感器数据的写入/查询/聚合,不要让各页面直接操作 DB
QualityStateService统一计算和缓存数据质量状态,复盘页和 AI 共用同一个质量判断
ReplayAnchorBuilder统一生成回放锚点,封装时间对齐逻辑,不要在复盘页到处拼参数
TimeSync手表-手机时钟同步必须有独立模块,Session 开始时自动执行

2. 必须支持优雅降级的位置

  • 复盘页的每个模块都必须检查 QualityState 再决定渲染
  • AI 摘要生成必须接收 QualityState 作为输入,不是"生成完再过滤"
  • 回放页的集合浏览模式必须处理"锚点指向无数据区间"的情况

3. 不要过度设计的地方

不要做原因
不要做通用时序数据库SQLite 够用,5400 条/场足够
不要做实时流处理管线1Hz 采样,定时批量写入即可
不要做传感器插件抽象层WearOS 和 watchOS API 差异大,各自实现更清晰
不要做复杂的 Segment 算法第一版用心率区间简单分段,不要引入 ML

4. 为未来 AI 留接口但现在不做重实现

留什么怎么留不做什么
EventMarker.weight字段定义好,默认值 1不做 AI 自动赋权
EventMarker.tags字段定义好,默认空不做 AI 自动打标
Segment.source = ai_suggested枚举值预留不做 AI 自动分段
SensorSample 完整字段模型定义全字段P2 字段暂不采集,值为 null

最值得优先验证的 5 个关键假设

#假设验证方式
1手表心率 1Hz 采集在运动中能稳定工作 60 分钟以上WearOS/watchOS 真机测试,记录断点率
2手表-手机时钟偏移在一场训练中小于 2 秒Session 首尾各同步一次,对比偏移量
3用户对"AI 摘要 + 推荐片段"的价值感知高于纯数据报表A/B 测试或用户访谈
41Hz 心率数据 5400 条/场在 SQLite 中查询聚合性能可接受本地 benchmark,目标 200ms 以内
5复盘页→回放页的跳转联动体验流畅,不会让用户迷失原型测试,观察用户是否能顺利返回复盘页

当前阶段最容易做坏的 5 个风险点

#风险后果缓解
1心率数据不做质量标记就直接展示异常值导致用户不信任 → 功能报废QualityState 必须与采集同步实现
2复盘页做成回放页的复制品两个页面高度重复,用户困惑复盘页禁止放视频播放器,只通过锚点跳转
3AI 输出超出数据支撑的结论"这 AI 瞎说" → 信任崩塌每条结论必须标注数据来源,可信度低时用疑问句
4手表-手机时间不同步直接上线点击"第 12 分钟射门"跳到视频第 15 分钟 → 体验崩溃Step 1 必须包含时钟同步,不是可选项
5SensorSample 表设计不预留 P1/P2 字段后续加 GPS/速度需要再次迁移 DB一次定义全字段,P1/P2 字段 nullable