Skip to content

Commit 048171c

Browse files
authored
Merge pull request #582 from NteinPrecious/issue/567-event-taxonomy
Document the event taxonomy (naming convention for tracked events)
2 parents 0f47ae7 + 43d1813 commit 048171c

1 file changed

Lines changed: 163 additions & 0 deletions

File tree

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Analytics Event Taxonomy
2+
3+
This document defines the naming convention and schema for every `AnalyticsEvent.eventName` used across the project.
4+
5+
## Naming Convention
6+
7+
All event names MUST follow the pattern:
8+
9+
```
10+
noun_pastTenseVerb
11+
```
12+
13+
- `noun` — the object or domain being acted upon (e.g. `puzzle`, `streak`, `onboarding`)
14+
- `pastTenseVerb` — the action in past tense (e.g. `attempted`, `completed`, `viewed`, `broken`)
15+
16+
### Examples
17+
18+
| ✓ Good | ✗ Bad |
19+
|-------------------------|------------------------|
20+
| `puzzle_attempted` | `PuzzleAttempted` |
21+
| `streak_broken` | `streak-broken` |
22+
| `onboarding_completed` | `onboardingComplete` |
23+
| `tutorial_viewed` | `tutorial_view` |
24+
| `profile_created` | `createProfile` |
25+
26+
A consistent naming convention ensures that all events can be queried and aggregated reliably across the entire platform.
27+
28+
## Registered Events
29+
30+
### `onboarding_started`
31+
32+
Emitted when a user begins the onboarding flow.
33+
34+
| Field | Type | Description |
35+
|------------|--------|--------------------------------------|
36+
| `userId` | string | Identifies the starting user |
37+
| `metadata` | object | (empty) |
38+
39+
---
40+
41+
### `profile_created`
42+
43+
Emitted when a user completes their profile during onboarding.
44+
45+
| Field | Type | Description |
46+
|------------|--------|--------------------------------------|
47+
| `userId` | string | Identifies the user |
48+
| `metadata` | object | `{ profileFieldsCompleted: number }` |
49+
50+
---
51+
52+
### `tutorial_viewed`
53+
54+
Emitted when a user views the tutorial.
55+
56+
| Field | Type | Description |
57+
|------------|--------|--------------------------------------|
58+
| `userId` | string | Identifies the user |
59+
| `metadata` | object | `{ tutorialStep: string }` |
60+
61+
---
62+
63+
### `first_puzzle_attempted`
64+
65+
Emitted when a user attempts their first puzzle.
66+
67+
| Field | Type | Description |
68+
|------------|--------|--------------------------------------|
69+
| `userId` | string | Identifies the user |
70+
| `metadata` | object | `{ puzzleId: string, difficulty: string }` |
71+
72+
---
73+
74+
### `onboarding_completed`
75+
76+
Emitted when a user finishes the entire onboarding flow.
77+
78+
| Field | Type | Description |
79+
|------------|--------|--------------------------------------|
80+
| `userId` | string | Identifies the user |
81+
| `metadata` | object | `{ timeToCompleteSeconds: number }` |
82+
83+
---
84+
85+
### `puzzle_attempted`
86+
87+
Emitted each time a user submits an answer to a puzzle.
88+
89+
| Field | Type | Description |
90+
|------------|--------|--------------------------------------|
91+
| `userId` | string | Identifies the user |
92+
| `metadata` | object | `{ puzzleId: string, difficulty: string, isCorrect: boolean, timeSpent: number }` |
93+
94+
---
95+
96+
### `streak_broken`
97+
98+
Emitted when a user's daily streak is broken after inactivity.
99+
100+
| Field | Type | Description |
101+
|------------|--------|--------------------------------------|
102+
| `userId` | string | Identifies the user |
103+
| `metadata` | object | `{ previousStreakLength: number, lastActiveDate: string }` |
104+
105+
---
106+
107+
### `streak_updated`
108+
109+
Emitted when a user's daily streak is updated (incremented or maintained).
110+
111+
| Field | Type | Description |
112+
|------------|--------|--------------------------------------|
113+
| `userId` | string | Identifies the user |
114+
| `metadata` | object | `{ currentStreak: number, longestStreak: number }` |
115+
116+
---
117+
118+
### `daily_quest_completed`
119+
120+
Emitted when a user completes all puzzles in their daily quest.
121+
122+
| Field | Type | Description |
123+
|------------|--------|--------------------------------------|
124+
| `userId` | string | Identifies the user |
125+
| `metadata` | object | `{ questDate: string, totalQuestions: number, bonusXpEarned: number }` |
126+
127+
---
128+
129+
### `login_occurred`
130+
131+
Emitted when a user logs in.
132+
133+
| Field | Type | Description |
134+
|------------|--------|--------------------------------------|
135+
| `userId` | string | Identifies the user |
136+
| `metadata` | object | `{ method: string }` |
137+
138+
---
139+
140+
### `wallet_connected`
141+
142+
Emitted when a user connects a Stellar wallet.
143+
144+
| Field | Type | Description |
145+
|------------|--------|--------------------------------------|
146+
| `userId` | string | Identifies the user |
147+
| `metadata` | object | `{ walletAddress: string }` |
148+
149+
## Adding New Events
150+
151+
1. Choose a `noun_pastTenseVerb` name that fits the convention.
152+
2. Add the event to the table in this document with its expected metadata shape.
153+
3. Emit the event from the relevant provider using `TrackEventProvider.track()`:
154+
155+
```typescript
156+
await this.trackEventProvider.track({
157+
eventName: 'your_new_event',
158+
userId: user.id,
159+
metadata: { /* ... */ },
160+
});
161+
```
162+
163+
4. Include the change in the same PR that introduces the event emission so the taxonomy stays in sync with the code.

0 commit comments

Comments
 (0)