|
| 1 | +# Analytics Tracking Plan |
| 2 | + |
| 3 | +This document outlines all analytics events tracked in Hyprnote, including their purpose, properties, and implementation status. |
| 4 | + |
| 5 | +## Event Naming Convention |
| 6 | + |
| 7 | +All events follow the pattern: `{object}_{past_tense_verb}` or `{action}_{object}` |
| 8 | +- Use snake_case for event names |
| 9 | +- Use past tense verbs (e.g., `created`, `deleted`, `started`) |
| 10 | +- Keep names concise but descriptive |
| 11 | +- Properties use snake_case |
| 12 | + |
| 13 | +## Currently Implemented Events |
| 14 | + |
| 15 | +### Authentication & Account Management |
| 16 | + |
| 17 | +#### `user_signed_in` |
| 18 | +**When**: User successfully signs in to their account |
| 19 | +**Location**: `apps/desktop/src/auth.tsx:244` |
| 20 | +**Properties**: None |
| 21 | +**Purpose**: Track successful authentication events |
| 22 | + |
| 23 | +#### `user_signed_out` |
| 24 | +**When**: User clicks sign out button |
| 25 | +**Location**: `apps/desktop/src/components/settings/general/account.tsx:46` |
| 26 | +**Properties**: None |
| 27 | +**Purpose**: Track when users end their session |
| 28 | + |
| 29 | +#### `account_skipped` |
| 30 | +**When**: User chooses "Proceed without account" on Apple Silicon |
| 31 | +**Location**: `apps/desktop/src/components/onboarding/welcome.tsx:55` |
| 32 | +**Properties**: None |
| 33 | +**Purpose**: Track users who opt for local-only mode |
| 34 | + |
| 35 | +### Monetization |
| 36 | + |
| 37 | +#### `trial_started` |
| 38 | +**When**: User successfully starts a Pro trial |
| 39 | +**Location**: `apps/desktop/src/components/settings/general/account.tsx:204` |
| 40 | +**Properties**: |
| 41 | +- `plan`: string - Always "pro" |
| 42 | + |
| 43 | +**Purpose**: Track trial conversions |
| 44 | + |
| 45 | +#### `upgrade_clicked` |
| 46 | +**When**: User clicks the upgrade to Pro button |
| 47 | +**Location**: `apps/desktop/src/components/settings/general/account.tsx:213` |
| 48 | +**Properties**: |
| 49 | +- `plan`: string - Always "pro" |
| 50 | + |
| 51 | +**Purpose**: Track upgrade funnel entry point |
| 52 | + |
| 53 | +### Session Management |
| 54 | + |
| 55 | +#### `session_started` |
| 56 | +**When**: User starts recording a new session |
| 57 | +**Location**: `apps/desktop/src/hooks/useStartListening.ts:42` |
| 58 | +**Properties**: |
| 59 | +- `has_calendar_event`: boolean - Whether session is linked to calendar event |
| 60 | + |
| 61 | +**Purpose**: Track recording usage patterns |
| 62 | + |
| 63 | +#### `session_deleted` |
| 64 | +**When**: User deletes a session (note + recording) |
| 65 | +**Location**: `apps/desktop/src/components/main/body/sessions/outer-header/overflow/delete.tsx:20` |
| 66 | +**Properties**: |
| 67 | +- `includes_recording`: boolean - Whether recording was also deleted |
| 68 | + |
| 69 | +**Purpose**: Track data retention patterns |
| 70 | + |
| 71 | +#### `recording_deleted` |
| 72 | +**When**: User deletes only the recording (keeps transcript/notes) |
| 73 | +**Location**: `apps/desktop/src/components/main/body/sessions/outer-header/overflow/delete.tsx:55` |
| 74 | +**Properties**: None |
| 75 | +**Purpose**: Track selective data management |
| 76 | + |
| 77 | +### Content Creation & Editing |
| 78 | + |
| 79 | +#### `note_created` |
| 80 | +**When**: User creates a new note |
| 81 | +**Location**: |
| 82 | +- `apps/desktop/src/components/main/shared.ts:35` |
| 83 | +- `apps/desktop/src/components/main/sidebar/timeline/item.tsx:187` |
| 84 | + |
| 85 | +**Properties**: |
| 86 | +- `has_event_id`: boolean - Whether note is linked to calendar event |
| 87 | + |
| 88 | +**Purpose**: Track content creation |
| 89 | + |
| 90 | +#### `note_edited` |
| 91 | +**When**: User writes content in a note (first edit only) |
| 92 | +**Location**: `apps/desktop/src/components/main/body/sessions/note-input/raw.tsx:81` |
| 93 | +**Properties**: |
| 94 | +- `has_content`: boolean - Always true |
| 95 | + |
| 96 | +**Purpose**: Track active note editing |
| 97 | + |
| 98 | +#### `note_enhanced` |
| 99 | +**When**: AI enhances/summarizes a note (auto or manual) |
| 100 | +**Location**: |
| 101 | +- `apps/desktop/src/hooks/useAutoEnhance.ts:81` (auto) |
| 102 | +- `apps/desktop/src/components/main/body/sessions/note-input/header.tsx:254` (template) |
| 103 | +- `apps/desktop/src/components/main/body/sessions/note-input/header.tsx:476` (manual) |
| 104 | + |
| 105 | +**Properties**: |
| 106 | +- `is_auto`: boolean - Whether enhancement was automatic |
| 107 | +- `template_id`: string (optional) - If using a template |
| 108 | + |
| 109 | +**Purpose**: Track AI feature usage |
| 110 | + |
| 111 | +### Data Operations |
| 112 | + |
| 113 | +#### `data_imported` |
| 114 | +**When**: User successfully imports data from external source |
| 115 | +**Location**: `apps/desktop/src/components/settings/data/import.tsx:38` |
| 116 | +**Properties**: |
| 117 | +- `source`: string - Source type (e.g., "notion", "roam") |
| 118 | + |
| 119 | +**Purpose**: Track data migration patterns |
| 120 | + |
| 121 | +#### `session_exported` |
| 122 | +**When**: User exports a session to file |
| 123 | +**Location**: |
| 124 | +- `apps/desktop/src/components/main/body/sessions/outer-header/overflow/export-pdf.tsx:106` (PDF) |
| 125 | +- `apps/desktop/src/components/main/body/sessions/outer-header/overflow/export-transcript.tsx:62` (VTT) |
| 126 | + |
| 127 | +**Properties**: |
| 128 | +- `format`: string - "pdf" or "vtt" |
| 129 | +- `has_transcript`: boolean (PDF only) - Whether transcript was included |
| 130 | +- `has_enhanced`: boolean (PDF only) - Whether enhanced notes were included |
| 131 | +- `word_count`: number (VTT only) - Number of words in transcript |
| 132 | + |
| 133 | +**Purpose**: Track export feature usage and format preferences |
| 134 | + |
| 135 | +#### `file_uploaded` |
| 136 | +**When**: User uploads audio or transcript file |
| 137 | +**Location**: `apps/desktop/src/components/main/body/sessions/floating/listen.tsx:256,278` |
| 138 | +**Properties**: |
| 139 | +- `file_type`: string - "audio" or "transcript" |
| 140 | +- `token_count`: number (transcript only) - Number of tokens imported |
| 141 | + |
| 142 | +**Purpose**: Track file import feature usage |
| 143 | + |
| 144 | +### Settings & Configuration |
| 145 | + |
| 146 | +#### `settings_changed` |
| 147 | +**When**: User modifies app settings |
| 148 | +**Location**: `apps/desktop/src/components/settings/general/index.tsx:74` |
| 149 | +**Properties**: |
| 150 | +- `autostart`: boolean - Start at login setting |
| 151 | +- `notification_detect`: boolean - Auto-detect meetings setting |
| 152 | +- `save_recordings`: boolean - Save recordings setting |
| 153 | +- `telemetry_consent`: boolean - Analytics consent setting |
| 154 | + |
| 155 | +**Purpose**: Track settings preferences and privacy choices |
| 156 | + |
| 157 | +#### `ai_provider_configured` |
| 158 | +**When**: User configures an AI provider (API key, base URL) |
| 159 | +**Location**: `apps/desktop/src/components/settings/ai/shared/index.tsx:105` |
| 160 | +**Properties**: |
| 161 | +- `provider`: string - Provider type (e.g., "openai", "anthropic", "local") |
| 162 | + |
| 163 | +**Purpose**: Track AI provider adoption |
| 164 | + |
| 165 | +### Search & Discovery |
| 166 | + |
| 167 | +#### `search_performed` |
| 168 | +**When**: User performs a search |
| 169 | +**Location**: `apps/desktop/src/contexts/search/ui.tsx:208` |
| 170 | +**Properties**: None |
| 171 | +**Purpose**: Track search feature usage |
| 172 | + |
| 173 | +#### `tab_opened` |
| 174 | +**When**: User opens a new tab |
| 175 | +**Location**: `apps/desktop/src/store/zustand/tabs/basic.ts:39,47` |
| 176 | +**Properties**: |
| 177 | +- `view`: string - Tab type (e.g., "sessions", "templates", "contacts") |
| 178 | + |
| 179 | +**Purpose**: Track feature discovery and navigation patterns |
| 180 | + |
| 181 | +### Communication |
| 182 | + |
| 183 | +#### `message_sent` |
| 184 | +**When**: User sends a chat message |
| 185 | +**Location**: `apps/desktop/src/components/chat/input.tsx:47` |
| 186 | +**Properties**: None |
| 187 | +**Purpose**: Track chat feature usage |
| 188 | + |
| 189 | +## Not Yet Implemented (Future Tracking) |
| 190 | + |
| 191 | +### High Priority |
| 192 | + |
| 193 | +#### Collaboration |
| 194 | +- `share_link_copied` - When user copies share link |
| 195 | +- `person_invited` - When user invites someone to share |
| 196 | +- `access_revoked` - When user removes someone's access |
| 197 | +- `role_changed` - When user changes viewer/editor role |
| 198 | + |
| 199 | +#### Integrations |
| 200 | +- `integration_connected` - When user connects an integration |
| 201 | + - Properties: `integration_name`, `integration_type` |
| 202 | +- `integration_disconnected` - When user disconnects |
| 203 | + - Properties: `integration_name` |
| 204 | +- `sync_triggered` - When user manually syncs |
| 205 | + - Properties: `integration_name` |
| 206 | + |
| 207 | +#### Templates |
| 208 | +- `template_created` - When user creates a custom template |
| 209 | +- `template_edited` - When user modifies a template |
| 210 | +- `template_deleted` - When user deletes a template |
| 211 | +- `template_cloned` - When user duplicates a template |
| 212 | + |
| 213 | +### Medium Priority |
| 214 | + |
| 215 | +#### Onboarding |
| 216 | +- `onboarding_step_completed` - Track onboarding progress |
| 217 | + - Properties: `step_name`, `step_number` |
| 218 | +- `onboarding_skipped` - When user skips onboarding |
| 219 | + - Properties: `at_step` |
| 220 | + |
| 221 | +#### Error Tracking |
| 222 | +- `config_error_encountered` - When user hits config error |
| 223 | + - Properties: `error_type`, `component` |
| 224 | +- `import_failed` - When import operation fails |
| 225 | + - Properties: `source`, `error_message` |
| 226 | +- `export_failed` - When export operation fails |
| 227 | + - Properties: `format`, `error_message` |
| 228 | + |
| 229 | +#### Feature Discovery |
| 230 | +- `keyboard_shortcut_used` - Track shortcut usage |
| 231 | + - Properties: `shortcut_name`, `shortcut_key` |
| 232 | +- `feature_tooltip_viewed` - Track help tooltip views |
| 233 | + - Properties: `feature_name` |
| 234 | + |
| 235 | +### Low Priority |
| 236 | + |
| 237 | +#### Sort & Filter |
| 238 | +- `results_sorted` - When user changes sort order |
| 239 | + - Properties: `sort_by`, `view_type` |
| 240 | +- `results_filtered` - When user applies filters |
| 241 | + - Properties: `filter_type`, `filter_value` |
| 242 | + |
| 243 | +#### Calendar Integration |
| 244 | +- `calendar_synced` - When calendar sync completes |
| 245 | + - Properties: `event_count`, `integration_name` |
| 246 | +- `calendar_event_selected` - When user selects event for note |
| 247 | + - Properties: `has_existing_note` |
| 248 | + |
| 249 | +## Implementation Guidelines |
| 250 | + |
| 251 | +### Adding New Events |
| 252 | + |
| 253 | +1. **Follow naming convention**: Use `{object}_{past_tense_verb}` format |
| 254 | +2. **Import the analytics commands**: |
| 255 | + ```typescript |
| 256 | + import { commands as analyticsCommands } from "@hypr/plugin-analytics"; |
| 257 | + ``` |
| 258 | + |
| 259 | +3. **Call the event at the right time**: |
| 260 | + ```typescript |
| 261 | + void analyticsCommands.event({ |
| 262 | + event: "event_name", |
| 263 | + property_key: property_value, |
| 264 | + }); |
| 265 | + ``` |
| 266 | + |
| 267 | +4. **Best practices**: |
| 268 | + - Track events in `onSuccess` callbacks when possible |
| 269 | + - Don't add complexity to code for tracking |
| 270 | + - Track the action, not the intent |
| 271 | + - Keep property names consistent across events |
| 272 | + - Use boolean properties for binary choices |
| 273 | + - Use string enums for categorical data |
| 274 | + - Use numbers for counts/amounts |
| 275 | + |
| 276 | +### Privacy Considerations |
| 277 | + |
| 278 | +- Never track PII (names, emails, content) |
| 279 | +- Track metadata and usage patterns only |
| 280 | +- Respect `telemetry_consent` setting |
| 281 | +- Use device fingerprint as `distinct_id`, not user emails |
| 282 | +- Anonymous by design |
| 283 | + |
| 284 | +### Testing Events |
| 285 | + |
| 286 | +1. Enable analytics in development mode |
| 287 | +2. Trigger the action that should fire the event |
| 288 | +3. Check PostHog dashboard for event arrival |
| 289 | +4. Verify all properties are correctly set |
| 290 | +5. Test edge cases (errors, empty states, etc.) |
| 291 | + |
| 292 | +## Event Properties Reference |
| 293 | + |
| 294 | +### Common Properties |
| 295 | + |
| 296 | +- `plan`: "pro" | "free" - User's current plan |
| 297 | +- `provider`: string - AI provider name |
| 298 | +- `format`: "pdf" | "vtt" | "json" - Export format |
| 299 | +- `source`: string - Import source type |
| 300 | +- `is_auto`: boolean - Whether action was automatic |
| 301 | +- `has_*`: boolean - Presence indicators |
| 302 | + |
| 303 | +### Property Naming |
| 304 | + |
| 305 | +- Use snake_case |
| 306 | +- Use descriptive names |
| 307 | +- Prefix existence checks with `has_` |
| 308 | +- Use counts with `_count` suffix |
| 309 | +- Use timestamps with `_at` suffix |
| 310 | + |
| 311 | +## Metrics & KPIs |
| 312 | + |
| 313 | +### Activation Metrics |
| 314 | +- Users who start their first session |
| 315 | +- Users who create their first note |
| 316 | +- Users who configure AI provider |
| 317 | +- Users who perform first search |
| 318 | + |
| 319 | +### Engagement Metrics |
| 320 | +- Sessions started per user per week |
| 321 | +- Notes created per user per week |
| 322 | +- AI enhancements triggered |
| 323 | +- Exports performed |
| 324 | + |
| 325 | +### Retention Metrics |
| 326 | +- Weekly active users (perform any tracked action) |
| 327 | +- Session creation rate over time |
| 328 | +- Feature usage diversity (unique events per user) |
| 329 | + |
| 330 | +### Conversion Metrics |
| 331 | +- Trial start rate |
| 332 | +- Upgrade click-through rate |
| 333 | +- Sign-up vs. local-only split |
| 334 | + |
| 335 | +### Feature Adoption |
| 336 | +- AI provider configuration rate |
| 337 | +- Integration connection rate |
| 338 | +- Template creation rate |
| 339 | +- Search usage rate |
| 340 | + |
| 341 | +## Related Documentation |
| 342 | + |
| 343 | +- PostHog: https://posthog.com/docs/product-analytics |
| 344 | +- Plugin bindings: `plugins/analytics/js/bindings.gen.ts` |
| 345 | +- Command reference: `.cursor/commands/add-analytics.md` |
0 commit comments