@od-oneapp/analytics 2026.2.1501-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -0
- package/README.md +509 -0
- package/ai-Co8hBoEj.mjs +3347 -0
- package/ai-Co8hBoEj.mjs.map +1 -0
- package/chunk-DQk6qfdC.mjs +18 -0
- package/client-BOIcr_5V.mjs +281 -0
- package/client-BOIcr_5V.mjs.map +1 -0
- package/client-BiJJm6CH.mjs +267 -0
- package/client-BiJJm6CH.mjs.map +1 -0
- package/client-CTzJVFU5.mjs +9 -0
- package/client-CTzJVFU5.mjs.map +1 -0
- package/client-C_4MPbIp.mjs +54 -0
- package/client-C_4MPbIp.mjs.map +1 -0
- package/client-next.d.mts +62 -0
- package/client-next.d.mts.map +1 -0
- package/client-next.mjs +525 -0
- package/client-next.mjs.map +1 -0
- package/client.d.mts +30 -0
- package/client.d.mts.map +1 -0
- package/client.mjs +186 -0
- package/client.mjs.map +1 -0
- package/config-6Mwe7b2O.mjs +287 -0
- package/config-6Mwe7b2O.mjs.map +1 -0
- package/config-BUMHyePt.d.mts +34 -0
- package/config-BUMHyePt.d.mts.map +1 -0
- package/console-8bND3mMU.mjs +128 -0
- package/console-8bND3mMU.mjs.map +1 -0
- package/ecommerce-DGG1FbiH.mjs +993 -0
- package/ecommerce-DGG1FbiH.mjs.map +1 -0
- package/emitters-BAXagFjt.d.mts +12 -0
- package/emitters-BAXagFjt.d.mts.map +1 -0
- package/emitters-BvEelkxS.mjs +208 -0
- package/emitters-BvEelkxS.mjs.map +1 -0
- package/index-Cnz0VecZ.d.mts +953 -0
- package/index-Cnz0VecZ.d.mts.map +1 -0
- package/index-qlFPt3-1.d.mts +184 -0
- package/index-qlFPt3-1.d.mts.map +1 -0
- package/logs-B4zFs5kX.mjs +108 -0
- package/logs-B4zFs5kX.mjs.map +1 -0
- package/manager-B6kowr9x.d.mts +70 -0
- package/manager-B6kowr9x.d.mts.map +1 -0
- package/package.json +136 -0
- package/posthog-bootstrap-CRl1Pk_E.d.mts +81 -0
- package/posthog-bootstrap-CRl1Pk_E.d.mts.map +1 -0
- package/posthog-bootstrap-DDToYA4X.mjs +1768 -0
- package/posthog-bootstrap-DDToYA4X.mjs.map +1 -0
- package/providers-http-client.d.mts +37 -0
- package/providers-http-client.d.mts.map +1 -0
- package/providers-http-client.mjs +320 -0
- package/providers-http-client.mjs.map +1 -0
- package/providers-http-server.d.mts +31 -0
- package/providers-http-server.d.mts.map +1 -0
- package/providers-http-server.mjs +297 -0
- package/providers-http-server.mjs.map +1 -0
- package/providers-http.d.mts +46 -0
- package/providers-http.d.mts.map +1 -0
- package/providers-http.mjs +4 -0
- package/server-edge.d.mts +9 -0
- package/server-edge.d.mts.map +1 -0
- package/server-edge.mjs +373 -0
- package/server-edge.mjs.map +1 -0
- package/server-next.d.mts +66 -0
- package/server-next.d.mts.map +1 -0
- package/server-next.mjs +193 -0
- package/server-next.mjs.map +1 -0
- package/server.d.mts +10 -0
- package/server.mjs +7 -0
- package/shared.d.mts +16 -0
- package/shared.d.mts.map +1 -0
- package/shared.mjs +93 -0
- package/shared.mjs.map +1 -0
- package/types-Brm88i6e.d.mts +216 -0
- package/types-Brm88i6e.d.mts.map +1 -0
- package/types-DnfdguWa.d.mts +354 -0
- package/types-DnfdguWa.d.mts.map +1 -0
- package/types.d.mts +4 -0
- package/types.mjs +0 -0
- package/validation-DZc_nvoN.d.mts +24 -0
- package/validation-DZc_nvoN.d.mts.map +1 -0
- package/validation-Dll9R6h6.mjs +315 -0
- package/validation-Dll9R6h6.mjs.map +1 -0
- package/vercel-types-Crq8m8c1.d.mts +102 -0
- package/vercel-types-Crq8m8c1.d.mts.map +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @repo/analytics
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`b626058`](https://github.com/OneDigital-Product/monorepo/commit/b6260582c2d9b7aaee89e3fb8c11515fd02cdfcf) Thanks
|
|
8
|
+
[@m-torin](https://github.com/m-torin)! - **BREAKING CHANGE**: Redesign AI tracking for ChatGPT/Claude-style product
|
|
9
|
+
features
|
|
10
|
+
|
|
11
|
+
Completely redesigned the AI tracking system to focus on **AI product features** instead of business use cases:
|
|
12
|
+
|
|
13
|
+
**Philosophy Change**: Track the AI product itself (chat features, artifacts, code generation), not what users do with
|
|
14
|
+
it (business workflows).
|
|
15
|
+
|
|
16
|
+
**Key Changes**:
|
|
17
|
+
- Renamed `aiSdk.*` → `ai.*` namespace for cleaner API
|
|
18
|
+
- 90+ new events for ChatGPT/Claude/Copilot-style features
|
|
19
|
+
- Clear separation from e-commerce tracking (`ai.*` vs `ecommerce.*`)
|
|
20
|
+
- Comprehensive product feature coverage:
|
|
21
|
+
- Message regeneration, editing, branching
|
|
22
|
+
- Conversation management & organization
|
|
23
|
+
- Code generation with copy/execute tracking
|
|
24
|
+
- Interactive artifacts & canvas (Claude-style)
|
|
25
|
+
- File upload, processing, referencing
|
|
26
|
+
- Context & memory management
|
|
27
|
+
- Collaboration & sharing features
|
|
28
|
+
- User feedback & quality signals
|
|
29
|
+
- System operations & performance
|
|
30
|
+
|
|
31
|
+
**Migration Guide**:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// Before (AI SDK v6 technical operations)
|
|
35
|
+
import { aiSdk } from '@repo/analytics/shared';
|
|
36
|
+
aiSdk.agentExecutionCompleted({ ... });
|
|
37
|
+
aiSdk.chatMessageReceived({ ... });
|
|
38
|
+
|
|
39
|
+
// After (AI product features)
|
|
40
|
+
import { ai } from '@repo/analytics/shared';
|
|
41
|
+
ai.MESSAGE_RECEIVED({ ... });
|
|
42
|
+
ai.MESSAGE_REGENERATED({ ... });
|
|
43
|
+
ai.CODE_GENERATED({ ... });
|
|
44
|
+
ai.ARTIFACT_CREATED({ ... });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**New Features**:
|
|
48
|
+
- `ai.MESSAGE_REGENERATED()` - Track regeneration attempts
|
|
49
|
+
- `ai.BRANCH_CREATED()` - Track conversation branching
|
|
50
|
+
- `ai.CODE_GENERATED()` - Track code generation
|
|
51
|
+
- `ai.ARTIFACT_CREATED()` - Track Claude-style artifacts
|
|
52
|
+
- `ai.CONVERSATION_SHARED()` - Track sharing features
|
|
53
|
+
- `ai.CUSTOM_INSTRUCTIONS_UPDATED()` - Track user preferences
|
|
54
|
+
- ...and 84 more product-focused events
|
|
55
|
+
|
|
56
|
+
**Documentation**:
|
|
57
|
+
- New comprehensive README at `src/shared/emitters/ai/README.md`
|
|
58
|
+
- Clear examples for ChatGPT/Claude-style implementations
|
|
59
|
+
- Complete type definitions for all 90+ events
|
|
60
|
+
|
|
61
|
+
This is a major version bump because:
|
|
62
|
+
1. Renamed namespace (`aiSdk` → `ai`) breaks existing imports
|
|
63
|
+
2. Event structure completely redesigned for product features
|
|
64
|
+
3. Old e-commerce chatbot events deprecated (use `ecommerce.*` instead)
|
|
65
|
+
|
|
66
|
+
### Minor Changes
|
|
67
|
+
|
|
68
|
+
- [`b626058`](https://github.com/OneDigital-Product/monorepo/commit/b6260582c2d9b7aaee89e3fb8c11515fd02cdfcf) Thanks
|
|
69
|
+
[@m-torin](https://github.com/m-torin)! - feat(analytics): expand AI tracking to 100+ events covering complete chatbot
|
|
70
|
+
journey
|
|
71
|
+
|
|
72
|
+
Renamed from `aiSdk` to `ai` and dramatically expanded event coverage:
|
|
73
|
+
|
|
74
|
+
**100+ Comprehensive Events** organized by customer journey stage:
|
|
75
|
+
- **Conversation (7)**: Session lifecycle, messages
|
|
76
|
+
- **Intent & Understanding (8)**: Intent detection, context switching, clarifications, misunderstandings
|
|
77
|
+
- **Product Discovery (7)**: Search, browse, visual/voice search, comparisons
|
|
78
|
+
- **Size & Fit (5)**: Size charts, fit recommendations, virtual try-on
|
|
79
|
+
- **Style & Preferences (4)**: Style profiling, preference learning
|
|
80
|
+
- **Recommendations (11)**: Upsell, cross-sell, bundles, gifts, personalized
|
|
81
|
+
- **Cart & Purchase (8)**: Cart management, promo codes, checkout start
|
|
82
|
+
- **Checkout Assistance (7)**: Address, payment, shipping help
|
|
83
|
+
- **Post-Purchase (7)**: Order tracking, product support, warranty, reviews
|
|
84
|
+
- **Returns & Exchanges (5)**: Return policy, initiation, label requests
|
|
85
|
+
- **Proactive Engagement (8)**: Greetings, cart recovery, deal alerts, re-engagement
|
|
86
|
+
- **Support & Escalation (10)**: FAQ, complaints, handoffs, escalation
|
|
87
|
+
- **Sentiment & Satisfaction (6)**: Sentiment tracking, satisfaction surveys
|
|
88
|
+
- **Personalization (4)**: User profiling, segmentation
|
|
89
|
+
- **Technical (10)**: Agent execution, completions, tools, streaming
|
|
90
|
+
|
|
91
|
+
**Auto-Detection Utilities:**
|
|
92
|
+
- `detectIntent()` - Auto-detect user intent from message (11 intent types)
|
|
93
|
+
- `detectSentiment()` - Sentiment analysis (positive/negative/neutral/mixed)
|
|
94
|
+
- `needsClarification()` - Detect ambiguous messages
|
|
95
|
+
- `extractProductMentions()` - Extract product categories
|
|
96
|
+
- `calculateQualityScore()` - Conversation quality scoring
|
|
97
|
+
|
|
98
|
+
**Enhanced Event Properties:**
|
|
99
|
+
- Intent confidence scores & detected entities
|
|
100
|
+
- Sentiment triggers & confidence
|
|
101
|
+
- Recommendation sources & triggers
|
|
102
|
+
- Abandonment recovery metrics
|
|
103
|
+
- Handoff reasons & escalation paths
|
|
104
|
+
- User profile completeness
|
|
105
|
+
- Conversation quality metrics
|
|
106
|
+
|
|
107
|
+
**Complete Event Reference:**
|
|
108
|
+
- `AI_EVENTS_REFERENCE.md` - 100+ events with examples
|
|
109
|
+
- Organized by customer journey stage
|
|
110
|
+
- Quick reference for common events
|
|
111
|
+
- Integration examples for all scenarios
|
|
112
|
+
|
|
113
|
+
**Breaking Changes:**
|
|
114
|
+
- Renamed `aiSdk` namespace to `ai`
|
|
115
|
+
- Import: `import { ai } from '@repo/analytics/client/next'`
|
|
116
|
+
- All event names follow pattern: `AI_EVENTS.EVENT_NAME`
|
|
117
|
+
|
|
118
|
+
**Migration:**
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Before
|
|
122
|
+
import { aiSdk } from '@repo/analytics/client/next';
|
|
123
|
+
aiSdk.agentExecutionCompleted({ ... });
|
|
124
|
+
|
|
125
|
+
// After
|
|
126
|
+
import { ai } from '@repo/analytics/client/next';
|
|
127
|
+
ai.AGENT_EXECUTION_COMPLETED({ ... });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Now tracks complete e-commerce chatbot customer journey from first interaction to post-purchase support with sentiment
|
|
131
|
+
analysis, proactive engagement, and quality monitoring.
|
|
132
|
+
|
|
133
|
+
### Patch Changes
|
|
134
|
+
|
|
135
|
+
- Updated dependencies
|
|
136
|
+
[[`e6c009d`](https://github.com/OneDigital-Product/monorepo/commit/e6c009dbd60afb0824a9418b97da15f8b43a3ecf),
|
|
137
|
+
[`9b7ff31`](https://github.com/OneDigital-Product/monorepo/commit/9b7ff317f2ac6d2088b4f194bea16aa15915cb80),
|
|
138
|
+
[`be5007c`](https://github.com/OneDigital-Product/monorepo/commit/be5007cf21959d0e5b15f8b602868b7adc567287),
|
|
139
|
+
[`1bec7a6`](https://github.com/OneDigital-Product/monorepo/commit/1bec7a65f975f3ff4ce35d1adc56611de76c16a4)]:
|
|
140
|
+
- @repo/observability@2025.11.1202
|
|
141
|
+
- @repo/shared@2025.11.1201
|
package/README.md
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# @repo/analytics
|
|
2
|
+
|
|
3
|
+
> **Multi-provider analytics package with type-safe event tracking, comprehensive ecommerce support, and AI product
|
|
4
|
+
> analytics**
|
|
5
|
+
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
**Status:** Development (Tests passing: 634/655, TypeCheck: ✅)
|
|
12
|
+
|
|
13
|
+
**Requirements:**
|
|
14
|
+
|
|
15
|
+
- Node.js 22.0.0+ (uses Node 22+ features: `structuredClone`, `AbortSignal.timeout`, bigint timing)
|
|
16
|
+
- pnpm 10.0.0+
|
|
17
|
+
- Next.js 15.0.0+ (if using Next.js integration)
|
|
18
|
+
|
|
19
|
+
**Exports:**
|
|
20
|
+
|
|
21
|
+
- **Core**: `./client`, `./server`, `./shared`, `./types`
|
|
22
|
+
- **Next.js**: `./client/next`, `./server/next`, `./server/edge`
|
|
23
|
+
|
|
24
|
+
**Key Features:**
|
|
25
|
+
|
|
26
|
+
- ✅ Multi-Provider (PostHog, Vercel Analytics, Segment, Console)
|
|
27
|
+
- ✅ Type-Safe Emitters (Segment.io specification)
|
|
28
|
+
- ✅ Universal (client/server/edge environments)
|
|
29
|
+
- ✅ E-commerce (50+ standardized events)
|
|
30
|
+
- ✅ AI Product Tracking (90+ ChatGPT/Claude-style events)
|
|
31
|
+
- ✅ Feature Flags (PostHog integration)
|
|
32
|
+
- ✅ Next.js 15 (App Router, Server Components, hooks)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
### Prerequisites
|
|
39
|
+
|
|
40
|
+
⚠️ **Required:** Node.js 22+ (package uses `structuredClone`, `AbortSignal.timeout`, `process.hrtime.bigint`)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Check Node version
|
|
44
|
+
node --version # Must be v22.0.0 or higher
|
|
45
|
+
|
|
46
|
+
# Install package
|
|
47
|
+
pnpm add @repo/analytics --filter=your-app
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Install Providers (Peer Dependencies)
|
|
51
|
+
|
|
52
|
+
Install only the providers you need:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# PostHog (recommended - analytics + feature flags)
|
|
56
|
+
pnpm add posthog-js posthog-node --filter=your-app
|
|
57
|
+
|
|
58
|
+
# Vercel Analytics
|
|
59
|
+
pnpm add @vercel/analytics --filter=your-app
|
|
60
|
+
|
|
61
|
+
# Segment
|
|
62
|
+
pnpm add @segment/analytics-next --filter=your-app
|
|
63
|
+
|
|
64
|
+
# Console (built-in, no installation needed)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
### Environment Variables
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# .env.local
|
|
75
|
+
|
|
76
|
+
# PostHog (Primary)
|
|
77
|
+
NEXT_PUBLIC_POSTHOG_KEY=phc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
78
|
+
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
|
|
79
|
+
|
|
80
|
+
# Vercel Analytics (Optional)
|
|
81
|
+
VERCEL_ANALYTICS_ID=your-analytics-id
|
|
82
|
+
|
|
83
|
+
# Segment (Optional)
|
|
84
|
+
NEXT_PUBLIC_SEGMENT_WRITE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
85
|
+
|
|
86
|
+
# Development
|
|
87
|
+
NEXT_PUBLIC_CONSOLE_ANALYTICS=true
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Next.js Setup
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
// app/providers.tsx
|
|
94
|
+
"use client";
|
|
95
|
+
|
|
96
|
+
import { AnalyticsProvider } from "@repo/analytics/client/next";
|
|
97
|
+
|
|
98
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
99
|
+
return (
|
|
100
|
+
<AnalyticsProvider
|
|
101
|
+
config={{
|
|
102
|
+
providers: {
|
|
103
|
+
posthog: {
|
|
104
|
+
apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!,
|
|
105
|
+
options: {
|
|
106
|
+
debug: process.env.NODE_ENV === "development",
|
|
107
|
+
capture_pageview: false
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
console: {
|
|
111
|
+
enabled: process.env.NODE_ENV === "development"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
debug: process.env.NODE_ENV === "development"
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
{children}
|
|
118
|
+
</AnalyticsProvider>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Usage Examples
|
|
124
|
+
|
|
125
|
+
#### Client Component
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
"use client";
|
|
129
|
+
|
|
130
|
+
import { useAnalytics, track } from "@repo/analytics/client/next";
|
|
131
|
+
|
|
132
|
+
export function SignupButton() {
|
|
133
|
+
const analytics = useAnalytics();
|
|
134
|
+
|
|
135
|
+
const handleClick = async () => {
|
|
136
|
+
// Method 1: Direct tracking
|
|
137
|
+
await analytics.track("Button Clicked", { button_name: "signup" });
|
|
138
|
+
|
|
139
|
+
// Method 2: Emitter pattern (recommended)
|
|
140
|
+
const event = track("CTA Clicked", { cta_type: "signup" });
|
|
141
|
+
await analytics.emit(event);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return <button onClick={handleClick}>Sign Up</button>;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Server Component / API Route
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
// app/api/checkout/route.ts
|
|
152
|
+
import { createServerAnalytics, ecommerce } from "@repo/analytics/server/next";
|
|
153
|
+
|
|
154
|
+
export async function POST(request: Request) {
|
|
155
|
+
const analytics = await createServerAnalytics({
|
|
156
|
+
providers: {
|
|
157
|
+
posthog: { apiKey: process.env.POSTHOG_API_KEY! }
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await analytics.emit(
|
|
162
|
+
ecommerce.CHECKOUT_STARTED({
|
|
163
|
+
order_id: "order_123",
|
|
164
|
+
value: 299.99,
|
|
165
|
+
currency: "USD",
|
|
166
|
+
products: [{ product_id: "prod_abc", price: 299.99, quantity: 1 }]
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return Response.json({ success: true });
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### E-commerce Events
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { ecommerce } from "@repo/analytics/client/next";
|
|
178
|
+
|
|
179
|
+
// Product viewed
|
|
180
|
+
ecommerce.PRODUCT_VIEWED({
|
|
181
|
+
product_id: "prod_123",
|
|
182
|
+
name: "Premium Plan",
|
|
183
|
+
price: 299.99,
|
|
184
|
+
currency: "USD"
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Product added to cart
|
|
188
|
+
ecommerce.PRODUCT_ADDED({
|
|
189
|
+
cart_id: "cart_abc",
|
|
190
|
+
product_id: "prod_123",
|
|
191
|
+
quantity: 1,
|
|
192
|
+
price: 299.99
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Order completed
|
|
196
|
+
ecommerce.ORDER_COMPLETED({
|
|
197
|
+
order_id: "order_789",
|
|
198
|
+
revenue: 499.97,
|
|
199
|
+
currency: "USD",
|
|
200
|
+
products: [
|
|
201
|
+
/* ... */
|
|
202
|
+
],
|
|
203
|
+
payment_method: "card"
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### AI Product Events
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { ai } from "@repo/analytics/client/next";
|
|
211
|
+
|
|
212
|
+
// Chat message sent
|
|
213
|
+
ai.CHAT_MESSAGE_SENT({
|
|
214
|
+
conversation_id: "conv_123",
|
|
215
|
+
message_id: "msg_456",
|
|
216
|
+
model_id: "gpt-4",
|
|
217
|
+
message_length: 150
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Message regenerated
|
|
221
|
+
ai.MESSAGE_REGENERATED({
|
|
222
|
+
conversation_id: "conv_123",
|
|
223
|
+
model_id: "gpt-4",
|
|
224
|
+
original_message_id: "msg_456",
|
|
225
|
+
attempt_number: 2,
|
|
226
|
+
reason: "user-requested"
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Conversation branched
|
|
230
|
+
ai.CONVERSATION_BRANCHED({
|
|
231
|
+
conversation_id: "conv_123",
|
|
232
|
+
parent_conversation_id: "conv_122",
|
|
233
|
+
branch_point_message_id: "msg_450",
|
|
234
|
+
reason: "explore-alternative"
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Architecture
|
|
241
|
+
|
|
242
|
+
### Four-File Export Pattern
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
@repo/analytics
|
|
246
|
+
├── /client → Browser-only (posthog-js, @vercel/analytics client)
|
|
247
|
+
├── /server → Node.js server (posthog-node, segment server)
|
|
248
|
+
├── /client/next → Next.js client (hooks, provider, components)
|
|
249
|
+
├── /server/next → Next.js server (API routes, server components)
|
|
250
|
+
├── /server/edge → Edge runtime (middleware, edge API routes)
|
|
251
|
+
└── /shared → Environment-agnostic (emitters, types, utils)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Import Rules:**
|
|
255
|
+
|
|
256
|
+
- ✅ Client components: `@repo/analytics/client/next`
|
|
257
|
+
- ✅ Server components/API routes: `@repo/analytics/server/next`
|
|
258
|
+
- ✅ Edge runtime: `@repo/analytics/server/edge`
|
|
259
|
+
- ❌ Never mix: Client + server imports cause build errors
|
|
260
|
+
|
|
261
|
+
**Edge Runtime Limitations:**
|
|
262
|
+
|
|
263
|
+
The `/server/edge` export provides a simplified implementation compatible with edge runtime:
|
|
264
|
+
|
|
265
|
+
- ✅ Basic tracking (track, identify, page, group, alias)
|
|
266
|
+
- ✅ Console provider (console API)
|
|
267
|
+
- ✅ PostHog provider (HTTP API, no SDK dependency)
|
|
268
|
+
- ✅ Emitter pattern support (`emit()`)
|
|
269
|
+
- ❌ No event deduplication (no LRU cache)
|
|
270
|
+
- ❌ No rate limiting enforcement
|
|
271
|
+
- ❌ No feature flags (requires Node.js SDK)
|
|
272
|
+
- ❌ No batch processing optimization
|
|
273
|
+
|
|
274
|
+
For full features, use `/server` or `/server/next` in Node.js environments.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Core API
|
|
279
|
+
|
|
280
|
+
### Analytics Manager
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// Create analytics instance
|
|
284
|
+
const analytics = await createClientAnalytics(config);
|
|
285
|
+
|
|
286
|
+
// Track events
|
|
287
|
+
await analytics.track("Event Name", { property: "value" });
|
|
288
|
+
|
|
289
|
+
// Identify users
|
|
290
|
+
await analytics.identify("user_123", { email: "user@example.com" });
|
|
291
|
+
|
|
292
|
+
// Track page views
|
|
293
|
+
await analytics.page("/pricing", { title: "Pricing Page" });
|
|
294
|
+
|
|
295
|
+
// Group/organization
|
|
296
|
+
await analytics.group("org_456", { name: "Acme Corp" });
|
|
297
|
+
|
|
298
|
+
// Emit emitter payloads
|
|
299
|
+
const event = track("Event", { data: "value" });
|
|
300
|
+
await analytics.emit(event);
|
|
301
|
+
|
|
302
|
+
// Batch processing
|
|
303
|
+
await analytics.emitBatch([event1, event2, event3], {
|
|
304
|
+
concurrency: 5,
|
|
305
|
+
failFast: false
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### React Hooks
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Access analytics manager
|
|
313
|
+
const analytics = useAnalytics();
|
|
314
|
+
|
|
315
|
+
// Track on mount
|
|
316
|
+
useTrackEvent("Page Viewed", { page: "/dashboard" });
|
|
317
|
+
|
|
318
|
+
// Identify user on mount
|
|
319
|
+
useIdentifyUser(user.id, { email: user.email });
|
|
320
|
+
|
|
321
|
+
// Auto page tracking
|
|
322
|
+
usePageTracking();
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Feature Flags (PostHog)
|
|
328
|
+
|
|
329
|
+
### Client-Side
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { useAnalytics } from '@repo/analytics/client/next';
|
|
333
|
+
|
|
334
|
+
function FeatureFlag() {
|
|
335
|
+
const analytics = useAnalytics();
|
|
336
|
+
const provider = analytics.getProvider('posthog');
|
|
337
|
+
const [enabled, setEnabled] = useState(false);
|
|
338
|
+
|
|
339
|
+
useEffect(() => {
|
|
340
|
+
provider?.isFeatureEnabled('new-feature').then(setEnabled);
|
|
341
|
+
}, [provider]);
|
|
342
|
+
|
|
343
|
+
return enabled ? <NewFeature /> : <OldFeature />;
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Server-Side
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
// app/page.tsx
|
|
351
|
+
import { createServerAnalytics } from "@repo/analytics/server/next";
|
|
352
|
+
|
|
353
|
+
export default async function Page() {
|
|
354
|
+
const analytics = await createServerAnalytics({
|
|
355
|
+
providers: { posthog: { apiKey: process.env.POSTHOG_API_KEY! } }
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const provider = analytics.getProvider("posthog");
|
|
359
|
+
const showFeature = await provider?.getFeatureFlag("new-feature", "user_123");
|
|
360
|
+
|
|
361
|
+
return <div>{showFeature ? <New /> : <Old />}</div>;
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Troubleshooting
|
|
368
|
+
|
|
369
|
+
### Common Issues
|
|
370
|
+
|
|
371
|
+
**"Analytics not initialized"**
|
|
372
|
+
|
|
373
|
+
- Ensure you await `createClientAnalytics()` or `createServerAnalytics()`
|
|
374
|
+
|
|
375
|
+
**"Provider not available in this environment"**
|
|
376
|
+
|
|
377
|
+
- Check you're using correct import path (client vs server vs edge)
|
|
378
|
+
|
|
379
|
+
**Events not showing in PostHog**
|
|
380
|
+
|
|
381
|
+
- Verify API key is correct
|
|
382
|
+
- Enable debug mode: `options: { debug: true }`
|
|
383
|
+
- Check network tab for failed requests
|
|
384
|
+
|
|
385
|
+
**"structuredClone is not defined"**
|
|
386
|
+
|
|
387
|
+
- Upgrade to Node.js 22+ (required)
|
|
388
|
+
|
|
389
|
+
### Debug Mode
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const analytics = await createClientAnalytics({
|
|
393
|
+
providers: {
|
|
394
|
+
posthog: {
|
|
395
|
+
apiKey: "...",
|
|
396
|
+
options: { debug: true }
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
debug: true,
|
|
400
|
+
onInfo: (msg) => console.log("[Analytics]", msg),
|
|
401
|
+
onError: (err, ctx) => console.error("[Analytics Error]", err, ctx)
|
|
402
|
+
});
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Health Check
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
const health = await analytics.healthCheck(5000);
|
|
409
|
+
console.log("Healthy:", health.healthy);
|
|
410
|
+
console.log("Providers:", health.providers);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Security
|
|
416
|
+
|
|
417
|
+
⚠️ **Important Security Notes:**
|
|
418
|
+
|
|
419
|
+
1. **Never track PII** - Avoid email, phone, SSN, credit cards
|
|
420
|
+
2. **Sanitize input** - Validate all properties before tracking
|
|
421
|
+
3. **Use env variables** - Never hardcode API keys
|
|
422
|
+
4. **Rotate keys** - Update API keys periodically
|
|
423
|
+
|
|
424
|
+
**Security Features (Implemented):**
|
|
425
|
+
|
|
426
|
+
- ✅ Input sanitization (`sanitizeProperties()`)
|
|
427
|
+
- ✅ PII detection and redaction (`containsPII()`, `redactPII()`)
|
|
428
|
+
- ✅ XSS protection (`stripHTML()`)
|
|
429
|
+
- ✅ Payload size limits (default: 100KB max)
|
|
430
|
+
- ✅ Dangerous key blocking (prevents `__proto__`, `constructor`)
|
|
431
|
+
- ✅ Rate limiting (token bucket algorithm, 100 calls/second default)
|
|
432
|
+
|
|
433
|
+
**Usage:**
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
import { sanitizeProperties, containsPII } from "@repo/analytics/server";
|
|
437
|
+
|
|
438
|
+
// Sanitize before tracking
|
|
439
|
+
const sanitized = sanitizeProperties(userInput, {
|
|
440
|
+
stripPII: true,
|
|
441
|
+
stripHTML: true,
|
|
442
|
+
maxPayloadSize: 50_000 // 50KB
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// Check for PII
|
|
446
|
+
if (containsPII(JSON.stringify(properties))) {
|
|
447
|
+
console.warn("PII detected in analytics payload");
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Documentation
|
|
454
|
+
|
|
455
|
+
- **Full Documentation**: [Analytics Package Docs](../../apps/docs/packages/analytics.mdx)
|
|
456
|
+
- **Audit Findings**: [AUDIT_FINDINGS.md](./AUDIT_FINDINGS.md)
|
|
457
|
+
- **API Reference**: See source code JSDoc comments
|
|
458
|
+
- **Examples**: [`src/examples/`](./src/examples/)
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Development
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
# Install dependencies
|
|
466
|
+
pnpm install
|
|
467
|
+
|
|
468
|
+
# Run tests
|
|
469
|
+
pnpm --filter=@repo/analytics test
|
|
470
|
+
|
|
471
|
+
# Type check
|
|
472
|
+
pnpm --filter=@repo/analytics typecheck
|
|
473
|
+
|
|
474
|
+
# Lint
|
|
475
|
+
pnpm --filter=@repo/analytics lint
|
|
476
|
+
|
|
477
|
+
# Coverage
|
|
478
|
+
pnpm --filter=@repo/analytics test:coverage
|
|
479
|
+
|
|
480
|
+
# Check circular deps
|
|
481
|
+
pnpm --filter=@repo/analytics circular
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Support
|
|
487
|
+
|
|
488
|
+
- **Issues**: [GitHub Issues](https://github.com/your-org/monorepo/issues)
|
|
489
|
+
- **Discussions**: [GitHub Discussions](https://github.com/your-org/monorepo/discussions)
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## License
|
|
494
|
+
|
|
495
|
+
MIT License
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
**Built with ❤️ by the Platform Team**
|
|
500
|
+
|
|
501
|
+
## 📚 Comprehensive Documentation
|
|
502
|
+
|
|
503
|
+
For detailed documentation, see:
|
|
504
|
+
|
|
505
|
+
- **[Audit Reports](../../apps/docs/content/docs/audits/analytics/)** - Comprehensive audits, fixes, and security
|
|
506
|
+
reviews
|
|
507
|
+
- **[Technical Guides](../../apps/docs/content/docs/packages/analytics/)** - Implementation guides and best practices
|
|
508
|
+
|
|
509
|
+
All comprehensive documentation has been centralized in the docs app.
|