165 lines
7.2 KiB
Markdown
165 lines
7.2 KiB
Markdown
# Implementation Plan: 声明式埋点上报系统
|
|
|
|
**Branch**: `005-declarative-tracking` | **Date**: 2025-12-05 | **Spec**: [spec.md](./spec.md)
|
|
**Input**: Feature specification from `/specs/005-declarative-tracking/spec.md`
|
|
|
|
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.
|
|
|
|
## Summary
|
|
|
|
实现一个声明式埋点上报系统,允许开发者通过 HTML 属性(如 `track="event_name"`)为元素添加埋点,系统自动捕获用户交互并上报到 Umami 分析服务。支持事件批量上报、失败重试、自动埋点模式,以及扩展的元数据(项目版本号、页面地址)。技术方案基于插件架构(withTracking),使用事件委托和 MutationObserver 监听动态元素,集成现有 Umami SDK 并扩展参数上报能力。
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: TypeScript 5.x (strict mode)
|
|
**Primary Dependencies**:
|
|
- React 18+
|
|
- Umami Analytics SDK (现有集成)
|
|
- RxJS (状态管理,参考现有 services 模式)
|
|
- localforage (事件缓存)
|
|
**Storage**: IndexedDB (via localforage) - 用于缓存失败的上报事件(最多 100 个,保留 1 小时)
|
|
**Testing**: Jest + React Testing Library (单元/组件测试), Playwright (E2E 测试)
|
|
**Target Platform**: Modern browsers (支持 MutationObserver, navigator.sendBeacon, IndexedDB)
|
|
**Project Type**: Monorepo (Nx) - 代码放置在 packages/drawnix/src/plugins/ 和 packages/drawnix/src/services/
|
|
**Performance Goals**:
|
|
- 事件上报延迟 <100ms (批量上报前)
|
|
- 防抖 500ms
|
|
- 批量上报减少网络请求 60%+
|
|
- 性能开销 <2% 页面加载时间
|
|
**Constraints**:
|
|
- 单文件 <500 行(宪章硬性约束)
|
|
- 缓存上限 100 个事件, 1 小时 TTL
|
|
- 批量上报:10 个事件或 5 秒
|
|
- 排除导航/工具栏/页脚区域的自动埋点
|
|
**Scale/Scope**:
|
|
- 支持 1000+ 可点击元素的页面
|
|
- 自动埋点覆盖率 95%+
|
|
- 适配现有 Drawnix 组件生态
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
### ✅ I. 插件优先架构
|
|
- **合规**: 实现为 `withTracking` 插件,遵循现有 `withFreehand`, `withMind` 等模式
|
|
- **自包含**: 埋点逻辑独立,不侵入其他插件
|
|
- **可组合**: 与其他插件无冲突,通过配置启用/禁用
|
|
- **框架无关**: 核心逻辑(事件监听、批量上报、缓存)可独立于 React 使用
|
|
|
|
### ✅ II. 文件大小约束
|
|
- **合规策略**:
|
|
- 插件入口: `withTracking.ts` (<200 行,仅组合逻辑)
|
|
- 服务层: `tracking-service.ts` (<500 行,核心上报逻辑)
|
|
- 工具类: `tracking-utils.ts` (<300 行,事件名生成、选择器匹配)
|
|
- 配置: `tracking-config.types.ts` (<150 行,类型定义)
|
|
- 存储: `tracking-storage-service.ts` (<250 行,缓存管理,复用 localforage 模式)
|
|
- 批处理: `tracking-batch-service.ts` (<300 行,批量上报逻辑)
|
|
- **验证**: 每个文件独立功能,可独立测试,总共 6 个文件,均 <500 行
|
|
|
|
### ✅ III. 类型安全优先
|
|
- **合规**:
|
|
- 所有配置使用 `interface TrackConfig`
|
|
- 事件对象使用 `interface TrackEvent`
|
|
- 严格类型化的事件参数(JSON 解析后验证)
|
|
- 避免 `any`,使用泛型和联合类型
|
|
|
|
### ✅ IV. 设计系统一致性
|
|
- **N/A**: 本功能无 UI 组件,纯逻辑层服务
|
|
- **日志输出**: 开发环境使用 console.warn,生产环境使用错误日志服务
|
|
|
|
### ✅ V. 性能与优化
|
|
- **合规**:
|
|
- 使用防抖(500ms)避免重复上报
|
|
- 事件委托减少监听器数量
|
|
- MutationObserver 仅监听必要的 DOM 变更
|
|
- 批量上报减少网络开销
|
|
- 使用 WeakMap 存储元素引用,避免内存泄漏
|
|
|
|
### ✅ VI. 安全与验证
|
|
- **合规**:
|
|
- 验证 `track-params` JSON 格式,捕获解析错误
|
|
- 过滤敏感信息(密码输入框的值不上报)
|
|
- API 密钥从配置读取,不硬编码
|
|
- navigator.sendBeacon 确保页面卸载时的安全上报
|
|
|
|
### ✅ VII. Monorepo 结构
|
|
- **合规**:
|
|
- 插件代码: `packages/drawnix/src/plugins/tracking/`
|
|
- 服务代码: `packages/drawnix/src/services/tracking/`
|
|
- 类型定义: `packages/drawnix/src/types/tracking.types.ts`
|
|
- 测试: `packages/drawnix/src/plugins/tracking/__tests__/`
|
|
|
|
### ⚠️ VIII. 测试要求
|
|
- **计划**:
|
|
- 单元测试: 事件捕获、批量逻辑、缓存管理
|
|
- 组件测试: 插件集成测试(模拟 DOM 交互)
|
|
- 集成测试: 与 Umami SDK 的集成
|
|
- E2E 测试: 完整用户交互流程(点击 → 批量上报 → 验证上报数据)
|
|
- **目标覆盖率**: >80%
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/005-declarative-tracking/
|
|
├── spec.md # 功能规范
|
|
├── plan.md # 本文件(实现计划)
|
|
├── research.md # Phase 0: 技术调研(Umami API、事件监听模式)
|
|
├── data-model.md # Phase 1: 数据模型(TrackEvent、TrackConfig、缓存结构)
|
|
├── quickstart.md # Phase 1: 快速开始指南
|
|
├── contracts/ # Phase 1: Umami API 集成契约
|
|
│ └── umami-api.md # Umami 事件上报接口定义
|
|
├── checklists/ # 质量检查清单
|
|
│ └── requirements.md # 需求完整性检查
|
|
└── tasks.md # Phase 2: 任务分解(待生成)
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
|
|
```text
|
|
packages/drawnix/src/
|
|
├── plugins/
|
|
│ └── tracking/
|
|
│ ├── index.ts # 插件导出
|
|
│ ├── withTracking.ts # 主插件入口(<200 行)
|
|
│ ├── hooks/
|
|
│ │ └── useTracking.ts # React Hook 封装(<150 行)
|
|
│ └── __tests__/
|
|
│ ├── withTracking.test.ts
|
|
│ └── useTracking.test.ts
|
|
│
|
|
├── services/
|
|
│ └── tracking/
|
|
│ ├── tracking-service.ts # 核心上报服务(<500 行)
|
|
│ ├── tracking-batch-service.ts # 批量上报逻辑(<300 行)
|
|
│ ├── tracking-storage-service.ts # 缓存管理(<250 行)
|
|
│ ├── tracking-utils.ts # 工具函数(<300 行)
|
|
│ └── __tests__/
|
|
│ ├── tracking-service.test.ts
|
|
│ ├── tracking-batch-service.test.ts
|
|
│ ├── tracking-storage-service.test.ts
|
|
│ └── tracking-utils.test.ts
|
|
│
|
|
├── types/
|
|
│ └── tracking.types.ts # 类型定义(<150 行)
|
|
│
|
|
└── drawnix.tsx # 集成 withTracking 插件
|
|
|
|
apps/web/src/
|
|
└── (可选)配置文件,用于初始化埋点系统配置
|
|
|
|
tests/e2e/
|
|
└── tracking/
|
|
├── declarative-tracking.spec.ts # 声明式埋点 E2E 测试
|
|
└── auto-tracking.spec.ts # 自动埋点 E2E 测试
|
|
```
|
|
|
|
**Structure Decision**: 采用 Monorepo (Option 3 变体),遵循现有 Drawnix 架构。核心逻辑在 `packages/drawnix/src/services/tracking/`,插件接口在 `packages/drawnix/src/plugins/tracking/`,类型定义在 `packages/drawnix/src/types/`。这种结构与现有的 `generation-api-service.ts`、`video-api-service.ts`、`chat-service.ts` 等服务保持一致,易于维护和测试。
|
|
|
|
## Complexity Tracking
|
|
|
|
> **Fill ONLY if Constitution Check has violations that must be justified**
|
|
|
|
*本功能无宪章违规,所有设计符合项目约束。*
|