Files
Genarrative/docs/technical/ADMIN_TRACKING_EVENT_DETAIL_EXPORT_2026-05-07.md
kdletters 643161a168
Some checks failed
CI / verify (push) Has been cancelled
fix(admin): populate tracking event key options
2026-05-10 14:48:10 +08:00

5.6 KiB
Raw Blame History

后台埋点数据明细与 Excel 导出方案

For Hermes: Use subagent-driven-development skill to implement this plan task-by-task.

Goal: 在百梦后台新增“埋点数据”页,展示每条埋点原始事件的详细字段,并支持导出为 Excel 可直接打开的表格文件。

Architecture: 后端继续由 api-server 作为后台 BFF经 SpacetimeDB HTTP SQL 只读查询 tracking_event,不改变表结构和 reducer。前端在 apps/admin-web 中新增独立路由与页面,页面渲染后端返回的原始明细,并在浏览器侧导出 Excel 兼容的 .xls HTML 表格,避免新增依赖。

Tech Stack: Rust Axum、SpacetimeDB HTTP SQL、shared-contracts、React 19、TypeScript、Vite。


范围

本次只做后台只读能力:

  • 展示 tracking_event 原始事件明细。
  • 每条埋点展示:事件 ID、Event Key、事件名称、Scope、Scope ID、Day Key、用户 ID、作品拥有者、Profile ID、模块、metadata、发生时间。
  • 支持按 Event Key、用户 ID、Scope Kind、Scope ID 筛选。
  • 支持导出当前筛选结果为 Excel 可打开文件。

不做:

  • 不新增或修改 SpacetimeDB 表结构。
  • 不在后台写入或删除埋点。
  • 不把埋点聚合口径下沉到前端计算。

后端契约

新增接口:

GET /admin/api/tracking/events?eventKey=&userId=&scopeKind=&scopeId=&limit=

鉴权:复用后台 require_admin_auth

返回:

{
  "entries": [
    {
      "eventId": "daily-login:user:xxx:123",
      "eventKey": "daily_login",
      "eventTitle": "每日登录",
      "scopeKind": "user",
      "scopeId": "xxx",
      "dayKey": 20580,
      "userId": "xxx",
      "ownerUserId": null,
      "profileId": null,
      "moduleKey": "profile",
      "metadataJson": "{}",
      "occurredAt": "2026-05-07T00:00:00Z"
    }
  ]
}

后端实现要点:

  1. DTO 放在 shared-contracts/src/admin.rs,避免 Rust 与前端口径分叉。
  2. Handler 放在 api-server/src/admin.rs,使用当前已有 SpacetimeDB HTTP SQL helper 思路。
  3. SQL 只读 tracking_event,固定白名单列;由于 SpacetimeDB 2.2 HTTP SQL 不支持 ORDER BY,后端取回默认 200 / 最大 1000 条后在 API 层按 occurred_at 倒序排序。
  4. 查询条件只通过字符串转义函数拼接,禁止直接拼接未转义用户输入。
  5. eventTitle 由后端根据已知事件 key 映射,未知事件返回 eventKey

前端页面

新增路由:#tracking,导航标题为“埋点数据”。

页面能力:

  1. 顶部筛选区Event Key、用户 ID、Scope Kind、Scope ID、刷新、导出 Excel。Event Key 候选来自后台前端的埋点定义注册表,需覆盖 BACKEND_TRACKING_EVENT_COVERAGE_2026-05-09.md 中已接入的通用埋点事件,不能只保留 daily_login
  2. 列表区:移动端可横向滚动,桌面端表格展示。
  3. 详情区:每行有“详情”按钮,弹出独立面板展示完整字段与格式化后的 metadata JSON。
  4. 导出:导出当前页面已加载结果,文件名形如 tracking-events-2026-05-07.xls

导出实现:

  • 使用 HTML table + Excel MIMEapplication/vnd.ms-excel;charset=utf-8
  • 文件扩展名使用 .xlsExcel/WPS 可直接打开。
  • 所有单元格做 HTML 转义。
  • metadata 保留原始 JSON 文本,便于运营继续筛选。

验收命令

npm run check:encoding
npm run admin-web:typecheck
cargo test -p shared-contracts -p api-server admin_tracking -- --nocapture

如后端接口改动较大,再补充:

npm run api-server
curl http://127.0.0.1:<port>/healthz

实施任务

Task 1: 补充 shared-contracts 后台埋点 DTO

Files:

  • Modify: server-rs/crates/shared-contracts/src/admin.rs

Steps:

  1. 新增 AdminTrackingEventListQuery
  2. 新增 AdminTrackingEventEntryPayload
  3. 新增 AdminTrackingEventListResponse
  4. 为 DTO 添加中文注释。

Task 2: 增加后端后台埋点查询接口

Files:

  • Modify: server-rs/crates/api-server/src/admin.rs
  • Modify: server-rs/crates/api-server/src/app.rs

Steps:

  1. admin.rs 新增 query 解析与 SQL 构造。
  2. 复用 SpacetimeDB HTTP SQL 调用风格读取 rows。
  3. 新增 admin_list_tracking_events handler。
  4. app.rs 挂载 /admin/api/tracking/events
  5. 添加单元测试覆盖 SQL 字符串转义、limit clamp、SQL 响应解析。

Task 3: 增加前端 API 类型与客户端方法

Files:

  • Modify: apps/admin-web/src/api/adminApiTypes.ts
  • Modify: apps/admin-web/src/api/adminApiClient.ts

Steps:

  1. 新增埋点 entry/list/query 类型。
  2. 新增 listAdminTrackingEvents(token, query)
  3. 使用 URLSearchParams 拼接非空查询字段。

Task 4: 新增后台埋点数据页面

Files:

  • Create: apps/admin-web/src/pages/AdminTrackingEventsPage.tsx
  • Modify: apps/admin-web/src/styles/admin.css

Steps:

  1. 实现筛选、刷新、错误状态。
  2. 实现明细表格。
  3. 实现独立详情面板。
  4. 实现 Excel .xls 导出。
  5. 保持 UI 简洁,不添加说明类大段文案。

Task 5: 接入后台路由与导航

Files:

  • Modify: apps/admin-web/src/app/adminRoutes.ts
  • Modify: apps/admin-web/src/app/AdminShell.tsx
  • Modify: apps/admin-web/src/app/AdminApp.tsx

Steps:

  1. 增加 tracking 路由。
  2. 导航增加图标。
  3. AdminApp 渲染新页面。

Task 6: 验证并提交

Steps:

  1. 运行 npm run check:encoding
  2. 运行 npm run admin-web:typecheck
  3. 运行后端相关 cargo test。
  4. 修复问题后提交并推送当前分支。