新增:健康事件时间线接入真实数据(T2-14 时间线半边)

- 时间线页:occurred_at DESC cursor 分页 + 月分组组头,四态齐备;
  六类事件经 RecordTypeDot 映射(增补喂养/洗护/测量三型,色族复用
  已审计色对),类型 TagPill 双通道
- 事件录入表单:六类类型选择器、金额以元录入/整数分传输(money.dart
  换算)、UTC 时间戳约定与体重表单一致
- 事件编辑页:顶层 PATCH 差量提交(title/notes/amountCents + version),
  40902 照 T2-12 模式自动经时间线检索取新 version 重提(保留输入)
- 档案页:月度花费卡接 summary.monthlyExpense(分→元展示)、tz 透传
  设备时区固定偏移(T2-13 遗留③)、健康时间线导航入口
- 埋点:health_record 域 create 三事件 + viewed(recordType=health_event)
  挂通;新增 edit_succeeded/failed 封装(failureReason 含 conflict)
- 测试 224 → 250 全绿(+26);analyze 0 问题;format 无 diff

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-08 13:49:48 +08:00
parent c91f18a845
commit e186ba3da9
15 changed files with 2274 additions and 23 deletions
+37 -4
View File
@@ -4,8 +4,9 @@ import 'package:patbond_flutter/analytics/page_view_tracker.dart';
/// 已扩充就绪,24 号报告 §2.2)。沿用 13 号规范 §3.1 惯例:枚举编译期
/// 锁死,业务代码禁止手拼事件名与属性。
///
/// T2-13 挂接创建漏斗三事件 + viewed;edit/deleted 事件的挂接随
/// 编辑/删除交互落地(「标记完成」等)另行接线,见 25 号报告遗留。
/// T2-13 挂接创建漏斗三事件 + viewed;T2-14 补挂 edit_succeeded/failed
/// (健康事件编辑、疫苗标记完成/取消)。`health_record_deleted` 因 M2
/// 契约无删除端点暂无挂接点,留待删除交互落地。
/// 记录类型(06 §1.4 recordType 枚举,四类记录接口对应)。
enum HealthRecordType {
@@ -30,7 +31,8 @@ enum HealthRecordEntryPoint {
final String value;
}
/// 创建失败原因(06 §1.4 基底 + M2 验收新增三值)。与 pet 域同款
/// 创建/编辑失败原因(06 §1.4 基底 + M2 验收新增三值`conflict`
/// 仅编辑链路会出现——40902 乐观锁/条件更新守卫落空)。与 pet 域同款
/// 网络归并口径:断网/超时/5xx 均并入 network_errorserver_error
/// 保留给无法归类的兜底。
enum HealthRecordFailureReason {
@@ -39,7 +41,8 @@ enum HealthRecordFailureReason {
notFound('not_found'),
rateLimited('rate_limited'),
networkError('network_error'),
serverError('server_error');
serverError('server_error'),
conflict('conflict');
const HealthRecordFailureReason(this.value);
@@ -122,4 +125,34 @@ class HealthRecordAnalytics {
'source': source.value,
});
}
/// 编辑保存成功响应(06 §1.4:编辑不设 started)。
///
/// [fieldCount] 为本次变更字段数(差量 PATCH 的键数,不含 version)。
void editSucceeded({
required HealthRecordType recordType,
required int fieldCount,
}) {
_track('health_record_edit_succeeded', {
'recordType': recordType.value,
'fieldCount': fieldCount,
});
}
/// 编辑保存失败(失败原因含 `conflict`——40902 版本/状态守卫冲突,
/// M2 验收「并发冲突明确」场景的数据面)。属性集无 attemptSeq
/// (白名单对齐 06 §1.5)。
void editFailed({
required HealthRecordType recordType,
required HealthRecordFailureReason reason,
int? errorCode,
}) {
_track('health_record_edit_failed', {
'recordType': recordType.value,
'failureReason': reason.value,
'errorCode': ?errorCode,
if (errorCode != null && errorCode >= 10000)
'httpStatus': errorCode ~/ 100,
});
}
}