入门统计架构逻辑

这套统计不是在识别“真实姓名用户”,而是在理解一个匿名 App 安装从首次打开、活跃、训练使用到指标生成的完整路径。目标是看懂新增、活跃和核心功能使用,而不是收集敏感个人信息。

iOS 前端 匿名 ID 离线队列 后端校验 PostgreSQL 生产指标过滤
1.4 (6)匿名统计 ON
APP EVENTS
首次打开生成匿名安装 ID,发送 app_first_open,用于新增统计。
今日活跃打开 App 或进入训练页,发送 app_open / workout_view。
训练行为开始、完成、提前结束训练,形成训练转化与流失分析。
隐私控制用户关闭匿名统计后,本地待上传队列清空并停止采集。

一条事件怎样变成指标

用户做了一个动作,前端先把它记录成一条标准事件。网络好就上传,网络不好就先放进本地队列。后端只接收合法事件,数据库保存原始记录,最后再汇总成每天能看的新增、活跃和功能使用指标。

1

用户动作

打开 App、进入训练、完成训练、查看统计。

2

iOS 采集

生成 event_id,带上匿名 ID、版本、渠道和事件时间。

3

本地队列

断网时先保存,恢复网络后批量补发,避免丢事件。

4

后端入口

校验事件名、字段白名单、重复 event_id 和异常时间。

5

数据库指标

原始事件入库,再按天汇总新增、活跃和训练使用。

当前 1.4 的统计边界

我们统计什么

首次打开、每日打开、训练页曝光、训练开始/完成/提前结束、身体记录添加、统计页查看。

我们怎样定义用户

当前 App 没有注册概念,所以用户按匿名安装 ID 计算。它适合看产品趋势,不等同于真实自然人。

我们不统计什么

不上传手机号、姓名、照片、媒体内容、密码、精确位置或其它可直接识别个人身份的信息。

新增和活跃怎么来

指标 事件来源 计算口径 适合回答的问题
新增 app_first_open 某天第一次出现的匿名安装 ID 数量。 今天有多少新设备第一次打开了 App。
活跃 app_open、workout_view、workout_start 等 某天有任意有效活动事件的匿名安装 ID 去重数。 今天有多少匿名用户真正使用了 App。
训练使用 workout_start、workout_complete、workout_abort 按事件次数、用户数和完成率聚合。 用户是否进入训练、是否完成、在哪里流失。
生产过滤 channel、build_type、is_test_mode debug、UI test、内部测试数据默认不进入正式指标。 避免我们自己测试把新增和活跃冲高。

前端、后端、数据库各管什么

iOS 前端

知道用户做了什么动作,负责生成事件、匿名 ID、本地缓存、断网补发和隐私开关。

后端服务

负责接收事件、判断是否合法、去重、过滤无关字段、标记测试数据和异常时间。

PostgreSQL

保存原始事件和汇总指标。原始事件用于追查问题,汇总指标用于看业务趋势。

为什么要先存原始事件

统计一定会遇到口径调整。先存原始事件,后面才可以重新计算,不用因为今天的指标逻辑写错就永久丢数据。

原始事件入库

每条合法事件都保留 event_id、匿名 ID、时间、版本、渠道和白名单属性。

标记能否聚合

未来时间、过旧时间、测试渠道、非法字段不会进入正式指标。

按天汇总

每天计算新增、活跃、训练曝光、训练完成、提前结束等指标。

排查时回看

如果某天数据异常,可以回到原始事件检查是不是重复、测试包、时间错误或网络补发导致。

常见统计漏洞和防护

容易出问题

  • 启动事件被前后台切换重复触发。
  • 断网重试导致同一事件重复入库。
  • debug 或 TestFlight 数据混进正式指标。
  • 客户端时间不准,把事件算到未来或很久以前。
  • 隐私开关关闭后,本地队列仍然继续上传。

当前防护思路

  • 每条事件都有 event_id,后端按 event_id 去重。
  • 后端只接受白名单事件和白名单字段。
  • debug/test 数据可入原始表,但不进生产指标。
  • 异常时间标记为不可聚合。
  • 匿名统计关闭时清空本地待上传队列。

上线前最小验收清单

检查项 通过标准
真机首次启动能在原始表看到 app_first_open 和 app_open。
训练流程进入训练、完成或提前结束后能看到对应 workout 事件。
正式指标过滤debug/test 事件不会出现在生产 metrics 里。
隐私开关开关可操作,关闭后停止采集并清空待上传队列。
断网补发离线产生的事件在恢复网络后上传,且不会重复计数。
版本渠道App Store 包应被识别为正式渠道,TestFlight 包应能单独区分。