Skip to content

集合:用户事件(events)

字数
1066 字
阅读时间
5 分钟

1. 目的与使用场景

  • 存储前端埋点与关键行为流水,支撑实时看板、画像更新、A/B 实验。事件定义参考《埋点与数据分析.md》。由前端 wx.reportAnalytics、事件收集云函数写入,数据团队读取。

2. Schema 定义

字段类型必填默认值约束/校验说明隐私分级
_idstring-TCB 自动主键P2
user_id指针id-指向 users._id用户P2
openid_hashstring-长度 32openid 哈希P2
event_namestring-参考事件枚举事件名称P1
event_timedate-ISO 字符串事件时间P1
page_pathstring-小程序路径触发页面P1
event_paramsobject--事件参数P2
deviceobject-{model, system}设备信息P1
app_versionstring-semver客户端版本P1
envstringprod枚举(prod,staging,test)环境P1
network_typestring-枚举(wifi,4g,5g,unknown)网络P1
session_idstring-长度 ≤ 64会话 IDP1
trace_idstring-长度 ≤ 64链路追踪P1
source_typestringclient枚举(client,server)上报来源P1
exp_groupstring-长度 ≤ 32实验分组P1
createdAtdate-服务端时间写入时间P1

3. 索引与唯一约束

  • 单字段索引:event_nameevent_time
  • 复合索引:[user_id, event_time desc][event_name, event_time desc]
  • 唯一性约束:[openid_hash, event_time, event_name, trace_id](可选)
  • 设计理由:画像更新需按用户最近事件;报表按事件名聚合;trace 防止重复写入。

4. 访问控制(TCB 权限)

json
{
  "read": "auth.role in ['data','ops']",
  "write": "auth.role in ['event_ingestor']"
}

数据团队和运维可读取;写入仅限事件采集服务。

  1. 关系与级联
  • user_idusers
  • suggestionstasksreports 通过事件参数关联
  • 删除策略:保留原始事件,不进行级联删除;用户注销时可脱敏 openid_hash。
  • 反范式:event_params 保留原样 JSON 方便上游解析。
  1. 数据生命周期与合规
  • 留存:原始事件保留 1 年;超过时段转存至对象存储并删除集合中的详情。
  • 匿名化:使用 openid 哈希,必要时移除 user_id
  • 审计:createdAtsource_type;对高敏事件(如 risk_signal_escalate)加密存储参数。
  1. API/云函数契约映射 | 接口/函数 | 读/写 | 使用字段 | 过滤条件 | 排序/分页 | 备注 | | 事件收集云函数 ingestEvent | 写 | openid_hash, user_id, event_name, event_time, event_params, session_id, trace_id | - | - | 前端上报入口 | | 行为画像任务 updateProfile | 读 | user_id, event_name, event_params | event_time >= now-7d | - | 调整建议权重 | | 数据看板导出 exportEvents | 读 | event_name, event_time, event_params | 时间范围 | event_time asc | 统计分析 |

  2. 示例文档(≥3条)

json
{
  "_id": "evt_9001",
  "user_id": "usr_001",
  "openid_hash": "a1b2c3d4",
  "event_name": "mood_checkin_submit",
  "event_time": "2024-04-06T09:00:02Z",
  "page_path": "miniprogram/pages/today/index",
  "event_params": {"mood_score": 72, "primary_emotion": "calm", "mood_tags": ["校园", "自习室"], "input_type": "mood_card"},
  "device": {"model": "iPhone 14", "system": "iOS 17"},
  "app_version": "1.3.0",
  "env": "prod",
  "network_type": "wifi",
  "session_id": "sess_abcd",
  "trace_id": "trace_1001",
  "createdAt": "2024-04-06T09:00:03Z"
}
{
  "_id": "evt_9050",
  "user_id": "usr_001",
  "openid_hash": "a1b2c3d4",
  "event_name": "suggestion_task_create",
  "event_time": "2024-04-06T09:01:00Z",
  "page_path": "miniprogram/pages/today/index",
  "event_params": {"suggestion_id": "sg_001", "task_id": "task_305", "category": "relationship", "source": "model"},
  "app_version": "1.3.0",
  "env": "prod",
  "session_id": "sess_abcd",
  "trace_id": "trace_1001",
  "createdAt": "2024-04-06T09:01:01Z"
}
{
  "_id": "evt_9500",
  "user_id": "usr_002",
  "openid_hash": "z9y8x7w6",
  "event_name": "risk_signal_escalate",
  "event_time": "2024-04-06T14:04:05Z",
  "event_params": {"risk_signal_id": "sos_20240406_01", "source": "treehole", "severity_level": "R3", "handler_role": "counselor"},
  "env": "prod",
  "network_type": "4g",
  "trace_id": "trace_sos_01",
  "createdAt": "2024-04-06T14:04:05Z"
}
  1. 常用查询样例(≥3条)
javascript
// 近 7 天情绪打卡次数
const checkinCount = await db.collection('events').where({
  user_id: auth.uid,
  event_name: 'mood_checkin_submit',
  event_time: db.command.gte(new Date(Date.now() - 7 * 86400000).toISOString())
}).count();

// 统计建议接受率
const acceptedEvents = await db.collection('events').where({
  event_name: 'suggestion_task_create',
  event_time: db.command.gte(new Date(Date.now() - 30 * 86400000).toISOString())
}).get();

// 风险监控查询
const riskEvents = await db.collection('events').where({
  event_name: 'risk_signal_escalate',
  event_time: db.command.gte(new Date(Date.now() - 24 * 3600 * 1000).toISOString())
}).orderBy('event_time', 'desc').get();
  1. 边界与错误码
  • 重复上报:命中唯一约束返回 E_EVENT_DUPLICATE
  • 参数缺失:缺少必填字段返回 E_EVENT_INVALID_PAYLOAD
  • 越权读取:非数据/运维角色返回 E_FORBIDDEN
  1. 变更影响评估
  • 新事件需同步《埋点与数据分析.md》、数据仓库 schema、画像服务逻辑。
  • 索引变更影响实时看板延迟与批处理成本。
  1. 假设与待确认
  • 假设 openid 哈希由前端计算;待确认是否改为云函数统一脱敏。
  • 待确认事件是否需要 geo 信息字段。

贡献者

The avatar of contributor named as Cai Hongyu Cai Hongyu

文件历史

撰写