12 KiB
后端用户行为埋点覆盖方案
更新时间:2026-05-09
1. 范围
本方案用于补齐后端可直接观测的用户行为埋点入口,统一写入 SpacetimeDB 的 tracking_event 与 tracking_daily_stat,为任务系统、运营看板与后续漏斗分析提供事实数据。
本轮明确不纳入以下范围:
- 后台管理入口:
/admin/... - RPG 相关入口
- 大鱼吃小鱼相关入口
- Visual Novel 相关入口
- Story 相关入口
- Combat 相关入口
上述范围后续若需要埋点,应单独定义事件口径,避免把后台运营审计或特定玩法内行为混入本轮通用用户行为埋点。
2. 写入链路
2.1 SpacetimeDB 通用 procedure
新增通用 procedure:
record_tracking_event_and_return(input: RuntimeTrackingEventInput)
该入口复用既有运行态埋点写入能力:
- 按
occurred_at_micros计算北京时间业务日day_key。 - 按同一
day_key幂等补齐analytics_date_dimension,保证周/月/季/年聚合查询有日期 bucket 映射。 - 写入原始事实
tracking_event。 - 更新聚合投影
tracking_daily_stat。 - 触发依赖事件进度的个人任务刷新。
每日登录 daily_login 也必须走该通用 procedure:认证链路仍保留 record_daily_login_tracking_event_after_auth_success(...) 作为业务语义 helper,但 helper 内部构造 TrackingEventDraft 后调用 record_tracking_event_after_success(...),不再绕到每日登录专用 SpacetimeDB procedure。
2.2 spacetime-client 封装
spacetime-client 提供薄封装:
SpacetimeRuntimeClient::record_tracking_event(...)
API Server 只依赖该 facade,不在 handler 中直接拼接 SpacetimeDB procedure 调用。
2.3 api-server helper 与中间件
API Server 新增统一 helper:
tracking::TrackingEventDrafttracking::record_tracking_event_after_success(...)tracking::record_route_tracking_event_after_success(...)
路由级中间件 record_api_tracking_after_success 挂在最终响应链路上,只在最终 HTTP status 为 2xx 时写入埋点。埋点失败只写 warn 日志,不阻断认证、充值、发布、任务领取等主业务流程。
3. metadata 口径
当前通用路由埋点仅记录低敏字段:
| 字段 | 含义 |
|---|---|
route |
请求路径,不包含 query string |
method |
HTTP Method |
status |
最终成功响应状态码 |
operation |
RequestContext 中的操作名 |
asset |
仅资产类事件写入的低敏资产/操作信息,包含 operation、operationFamily、assetObjectId、assetKind、objectKey、bucket、contentType、contentLength、version、bindingId、entityKind、entityId、slot、ownerUserId、profileId 等可用于定位资产事实的字段;不写签名 URL、表单签名、OSS policy、token 或完整请求体。 |
assetOperation |
资产类路由兜底事件的操作 key,用于不读取请求体时仍能按操作族聚合。 |
禁止在通用埋点 metadata 中写入手机号、token、cookie、邀请码、请求体、密钥、连接串、外部凭证、OSS 签名 URL、PostObject policy 或签名表单字段。
3.1 作品级游玩埋点
所有已接入后端正式试玩/播放入口的作品类型统一写 work_play_start:
scope_kind = work。scope_id = 稳定作品 ID,优先使用profile_id;大鱼吃小鱼沿用session_id作为作品 ID。user_id = 当前认证用户。owner_user_id = 作品作者/拥有者,无法从入口直接确认作者时可为空,但metadata.userId仍保留当前玩家。profile_id = 作品 profile_id,大鱼吃小鱼这类 session 型作品可为空。module_key = play_type,例如puzzle、match3d、square-hole、custom-world、big-fish、visual-novel。metadata固定包含operation = work_play_start、playType、workId、sourceRoute,并按入口补充runId、ownerUserId、profileId、levelId、mode等低敏字段。
该事件用于“某个作品被多少不同用户玩过”等作品级分析;权威去重统计仍建议优先使用业务投影(如 profile_played_world),埋点侧用于分析与漏斗联动。
4. 事件清单
4.1 认证与会话
| 事件 | 入口 |
|---|---|
auth_login_options_view |
GET /api/auth/login-options |
auth_phone_code_send |
POST /api/auth/phone/send-code |
daily_login |
认证成功与 refresh 续期后由 record_daily_login_tracking_event_after_auth_success(...) 主动写入,事件 ID 按 daily-login:{user_id}:{day_key} 幂等 |
auth_phone_login_success |
POST /api/auth/phone/login |
auth_me_view |
GET /api/auth/me |
auth_sessions_view |
GET /api/auth/sessions |
auth_revoke_session |
POST /api/auth/sessions/{session_id}/revoke |
auth_refresh_success |
POST /api/auth/refresh |
auth_logout |
POST /api/auth/logout |
auth_logout_all |
POST /api/auth/logout-all |
auth_wechat_bind_phone_success |
POST /api/auth/wechat/bind-phone |
4.2 个人中心、账户运营与任务
| 事件 | 入口 |
|---|---|
profile_identity_update |
PATCH /api/profile/me |
profile_dashboard_view |
GET /api/profile/dashboard |
wallet_ledger_view |
GET /api/profile/wallet-ledger |
recharge_center_view |
GET /api/profile/recharge-center |
recharge_order_create |
POST /api/profile/recharge/orders |
feedback_submit |
POST /api/profile/feedback |
invite_center_view |
GET /api/profile/referrals/invite-center |
referral_invite_code_redeem |
POST /api/profile/referrals/redeem-code |
redeem_code_submit |
POST /api/profile/redeem-codes/redeem |
task_center_view |
GET /api/profile/tasks |
task_reward_claim |
POST /api/profile/tasks/{task_id}/claim |
save_archive_list_view |
GET /api/profile/save-archives |
save_archive_detail_view |
GET /api/profile/save-archives/{archive_id} |
browse_history_view |
GET /api/profile/browse-history |
browse_history_record |
POST /api/profile/browse-history |
browse_history_clear |
DELETE /api/profile/browse-history |
play_stats_view |
GET /api/profile/play-stats |
profile_analytics_metric_view |
GET /api/profile/analytics/metric |
4.3 AI、资产、LLM 与语音
资产操作统一按用户级事件写入:scope_kind = user、scope_id = 当前认证 user_id、user_id/owner_user_id = 当前认证 user_id。其中 asset_upload_ticket_create、asset_upload_confirm、asset_bind 在 handler 成功后主动记录资产 metadata,避免只依赖路由兜底;其余资产工坊入口通过路由级兜底保留用户级操作事实。
| 事件 | 入口 |
|---|---|
ai_task_create |
POST /api/ai/tasks |
ai_task_start |
POST /api/ai/tasks/{task_id}/start |
ai_task_stage_start |
POST /api/ai/tasks/{task_id}/stages/{stage_id}/start |
ai_task_chunk_append |
POST /api/ai/tasks/{task_id}/chunks |
ai_task_stage_complete |
POST /api/ai/tasks/{task_id}/stages/{stage_id}/complete |
ai_task_reference_attach |
POST /api/ai/tasks/{task_id}/references |
ai_task_complete |
POST /api/ai/tasks/{task_id}/complete |
ai_task_fail |
POST /api/ai/tasks/{task_id}/fail |
ai_task_cancel |
POST /api/ai/tasks/{task_id}/cancel |
asset_upload_ticket_create |
POST /api/assets/direct-upload-tickets |
asset_sts_credentials_create |
POST /api/assets/sts-upload-credentials |
asset_upload_confirm |
POST /api/assets/objects/confirm |
asset_bind |
POST /api/assets/objects/bind |
asset_character_visual_generate |
POST /api/assets/character-visual/generate |
asset_character_visual_publish |
POST /api/assets/character-visual/publish |
asset_character_animation_generate |
POST /api/assets/character-animation/generate |
asset_character_animation_publish |
POST /api/assets/character-animation/publish |
asset_character_animation_import |
POST /api/assets/character-animation/import-video |
asset_character_workflow_cache_save |
POST /api/assets/character-workflow-cache |
asset_history_view |
GET /api/assets/history |
llm_request |
POST /api/llm/chat/completions |
speech_config_view |
GET /api/speech/volcengine/config |
asr_stream_start |
GET /api/speech/volcengine/asr/stream |
tts_bidirection_start |
GET /api/speech/volcengine/tts/bidirection |
tts_sse_start |
POST /api/speech/volcengine/tts/sse |
4.4 运行态与创作入口
| 事件 | 入口 |
|---|---|
runtime_settings_view |
GET /api/runtime/settings |
runtime_settings_update |
PUT /api/runtime/settings |
runtime_snapshot_view |
GET /api/runtime/save/snapshot |
runtime_snapshot_save |
PUT /api/runtime/save/snapshot |
runtime_snapshot_delete |
DELETE /api/runtime/save/snapshot |
puzzle_route_success |
/api/runtime/puzzle/... 成功响应兜底 |
match3d_route_success |
/api/creation/match3d/... 与 /api/runtime/match3d/... 成功响应兜底 |
square_hole_route_success |
/api/creation/square-hole/... 与 /api/runtime/square-hole/... 成功响应兜底 |
custom_world_route_success |
/api/runtime/custom-world... 成功响应兜底 |
creative_agent_route_success |
/api/runtime/creative-agent... 成功响应兜底 |
work_play_start |
拼图、抓大鹅、方洞挑战、自定义世界、大鱼吃小鱼、Visual Novel 的正式开始游玩/播放入口;写 scope_kind = work、scope_id = 作品 ID |
2048、Survivor、Moku 等未被排除的模板/玩法,如果经由上述 runtime、creative、custom-world、puzzle、match3d 或 square-hole 后端入口,会被路由级兜底事件覆盖。
5. 查询与验收建议
按每日登录核查原始事实:
SELECT event_id, event_key, scope_kind, scope_id, user_id, module_key, metadata_json, occurred_at
FROM tracking_event
WHERE event_key = 'daily_login'
ORDER BY occurred_at DESC
LIMIT 20;
按作品级游玩核查原始事实:
SELECT event_key, scope_kind, scope_id, user_id, owner_user_id, profile_id, module_key, metadata_json, occurred_at
FROM tracking_event
WHERE event_key = 'work_play_start'
ORDER BY occurred_at DESC
LIMIT 20;
按某个作品统计不同游玩用户:
SELECT scope_id, COUNT(DISTINCT user_id) AS player_count
FROM tracking_event
WHERE event_key = 'work_play_start'
AND scope_kind = 'work'
AND scope_id = '<profile_id_or_work_id>'
GROUP BY scope_id;
按资产操作核查原始事实:
SELECT event_key, scope_kind, scope_id, user_id, owner_user_id, module_key, metadata_json, occurred_at
FROM tracking_event
WHERE module_key = 'asset'
ORDER BY occurred_at DESC
LIMIT 20;
按事件核查原始事实:
SELECT event_key, scope_kind, scope_id, user_id, module_key, metadata_json, occurred_at
FROM tracking_event
WHERE event_key = 'task_center_view'
ORDER BY occurred_at DESC
LIMIT 20;
按日聚合核查:
SELECT day_key, event_key, scope_kind, scope_id, count
FROM tracking_daily_stat
WHERE event_key = 'task_center_view'
ORDER BY day_key DESC
LIMIT 20;
验收重点:
- 成功请求写入
tracking_event并刷新tracking_daily_stat。 daily_login由认证成功/refresh 续期链路主动写入,且走record_tracking_event_and_return通用 procedure。- 非 2xx 响应不记录通用成功事件。
- 后台、RPG、大鱼吃小鱼、Visual Novel、Story、Combat 路由不写入本轮通用埋点。
- 埋点写入失败时主接口仍返回原业务结果,只记录后端 warning。
- metadata 不包含凭证、请求体或敏感业务字段。