kanmi-perf-revenue 1.0.0 → 1.1.0
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/README.md +196 -186
- package/dist/empirical/ab-testing.d.ts +83 -0
- package/dist/empirical/ab-testing.d.ts.map +1 -0
- package/dist/empirical/ab-testing.js +281 -0
- package/dist/empirical/ab-testing.js.map +1 -0
- package/dist/empirical/alerting.d.ts +85 -0
- package/dist/empirical/alerting.d.ts.map +1 -0
- package/dist/empirical/alerting.js +358 -0
- package/dist/empirical/alerting.js.map +1 -0
- package/dist/empirical/attribution.d.ts +80 -0
- package/dist/empirical/attribution.d.ts.map +1 -0
- package/dist/empirical/attribution.js +305 -0
- package/dist/empirical/attribution.js.map +1 -0
- package/dist/empirical/cohort.d.ts +75 -0
- package/dist/empirical/cohort.d.ts.map +1 -0
- package/dist/empirical/cohort.js +305 -0
- package/dist/empirical/cohort.js.map +1 -0
- package/dist/empirical/conversion-curve.d.ts +7 -10
- package/dist/empirical/conversion-curve.d.ts.map +1 -1
- package/dist/empirical/conversion-curve.js +37 -4
- package/dist/empirical/conversion-curve.js.map +1 -1
- package/dist/empirical/correlation.d.ts +91 -0
- package/dist/empirical/correlation.d.ts.map +1 -0
- package/dist/empirical/correlation.js +461 -0
- package/dist/empirical/correlation.js.map +1 -0
- package/dist/empirical/data-import.d.ts +22 -0
- package/dist/empirical/data-import.d.ts.map +1 -1
- package/dist/empirical/data-import.js +44 -0
- package/dist/empirical/data-import.js.map +1 -1
- package/dist/empirical/datadog-session-query.d.ts +32 -0
- package/dist/empirical/datadog-session-query.d.ts.map +1 -1
- package/dist/empirical/datadog-session-query.js +238 -17
- package/dist/empirical/datadog-session-query.js.map +1 -1
- package/dist/empirical/engagement-analysis.d.ts +112 -0
- package/dist/empirical/engagement-analysis.d.ts.map +1 -0
- package/dist/empirical/engagement-analysis.js +354 -0
- package/dist/empirical/engagement-analysis.js.map +1 -0
- package/dist/empirical/export.d.ts +75 -0
- package/dist/empirical/export.d.ts.map +1 -0
- package/dist/empirical/export.js +392 -0
- package/dist/empirical/export.js.map +1 -0
- package/dist/empirical/forecasting.d.ts +80 -0
- package/dist/empirical/forecasting.d.ts.map +1 -0
- package/dist/empirical/forecasting.js +287 -0
- package/dist/empirical/forecasting.js.map +1 -0
- package/dist/empirical/funnel.d.ts +66 -0
- package/dist/empirical/funnel.d.ts.map +1 -0
- package/dist/empirical/funnel.js +293 -0
- package/dist/empirical/funnel.js.map +1 -0
- package/dist/empirical/history.d.ts +198 -0
- package/dist/empirical/history.d.ts.map +1 -0
- package/dist/empirical/history.js +396 -0
- package/dist/empirical/history.js.map +1 -0
- package/dist/empirical/index.d.ts +39 -16
- package/dist/empirical/index.d.ts.map +1 -1
- package/dist/empirical/index.js +95 -13
- package/dist/empirical/index.js.map +1 -1
- package/dist/empirical/interactions.d.ts +89 -0
- package/dist/empirical/interactions.d.ts.map +1 -0
- package/dist/empirical/interactions.js +346 -0
- package/dist/empirical/interactions.js.map +1 -0
- package/dist/empirical/opportunity-calculator.d.ts +6 -18
- package/dist/empirical/opportunity-calculator.d.ts.map +1 -1
- package/dist/empirical/opportunity-calculator.js +19 -1
- package/dist/empirical/opportunity-calculator.js.map +1 -1
- package/dist/empirical/report.d.ts +3 -11
- package/dist/empirical/report.d.ts.map +1 -1
- package/dist/empirical/report.js +11 -7
- package/dist/empirical/report.js.map +1 -1
- package/dist/empirical/roi-calculator.d.ts +104 -0
- package/dist/empirical/roi-calculator.d.ts.map +1 -0
- package/dist/empirical/roi-calculator.js +403 -0
- package/dist/empirical/roi-calculator.js.map +1 -0
- package/dist/empirical/seasonality.d.ts +80 -0
- package/dist/empirical/seasonality.d.ts.map +1 -0
- package/dist/empirical/seasonality.js +340 -0
- package/dist/empirical/seasonality.js.map +1 -0
- package/dist/empirical/segmentation.d.ts +135 -0
- package/dist/empirical/segmentation.d.ts.map +1 -0
- package/dist/empirical/segmentation.js +379 -0
- package/dist/empirical/segmentation.js.map +1 -0
- package/dist/empirical/statistics.d.ts +118 -0
- package/dist/empirical/statistics.d.ts.map +1 -0
- package/dist/empirical/statistics.js +344 -0
- package/dist/empirical/statistics.js.map +1 -0
- package/dist/empirical/sweet-spot.d.ts +81 -0
- package/dist/empirical/sweet-spot.d.ts.map +1 -0
- package/dist/empirical/sweet-spot.js +198 -0
- package/dist/empirical/sweet-spot.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,246 +1,256 @@
|
|
|
1
|
-
#
|
|
1
|
+
# kanmi-perf-revenue
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Empirical Performance Revenue Engine — Measure how Core Web Vitals impact conversions from your actual data.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**No assumed coefficients.** No "0.5% CVR per 100ms" guesses. This tool measures the actual conversion rates at each performance bucket from YOUR session data.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
11
|
-
npm install -g @perf-revenue/engine
|
|
12
|
-
|
|
13
|
-
# Initialize configuration
|
|
14
|
-
perf-revenue config init
|
|
15
|
-
|
|
16
|
-
# Add a client
|
|
17
|
-
perf-revenue config add-client \
|
|
18
|
-
--name acme \
|
|
19
|
-
--display-name "Acme Corp" \
|
|
20
|
-
--ga4-project my-gcp-project \
|
|
21
|
-
--ga4-property 123456789 \
|
|
22
|
-
--datadog-app rum-app-id
|
|
23
|
-
|
|
24
|
-
# Set credentials
|
|
25
|
-
export ANTHROPIC_API_KEY=sk-ant-...
|
|
26
|
-
export DATADOG_API_KEY=...
|
|
27
|
-
export DATADOG_APP_KEY=...
|
|
28
|
-
|
|
29
|
-
# Run autonomous analysis
|
|
30
|
-
perf-revenue analyze --client acme -v
|
|
10
|
+
npm install kanmi-perf-revenue
|
|
31
11
|
```
|
|
32
12
|
|
|
33
|
-
##
|
|
13
|
+
## Quick Start
|
|
34
14
|
|
|
35
|
-
|
|
36
|
-
┌─────────────────────────────────────────────────────┐
|
|
37
|
-
│ perf-revenue analyze --client acme │
|
|
38
|
-
└─────────────────────────────────────────────────────┘
|
|
39
|
-
│
|
|
40
|
-
▼
|
|
41
|
-
┌─────────────────────────────────────────────────────┐
|
|
42
|
-
│ Claude Agent (Autonomous) │
|
|
43
|
-
│ ├── Tool: BigQuery (fetch GA4 business data) │
|
|
44
|
-
│ ├── Tool: Datadog API (fetch RUM performance) │
|
|
45
|
-
│ ├── Tool: Analysis Engine (calculate impact) │
|
|
46
|
-
│ └── Tool: Report Generator (format output) │
|
|
47
|
-
└─────────────────────────────────────────────────────┘
|
|
48
|
-
│
|
|
49
|
-
▼
|
|
50
|
-
┌─────────────────────────────────────────────────────┐
|
|
51
|
-
│ Executive Report (markdown) │
|
|
52
|
-
│ • $47K/month revenue opportunity │
|
|
53
|
-
│ • Prioritized by financial impact │
|
|
54
|
-
│ • CFO-ready format │
|
|
55
|
-
└─────────────────────────────────────────────────────┘
|
|
56
|
-
```
|
|
15
|
+
### CLI Usage
|
|
57
16
|
|
|
58
|
-
|
|
17
|
+
```bash
|
|
18
|
+
# Run with mock data (demo)
|
|
19
|
+
npx kanmi-perf-revenue --demo
|
|
59
20
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- **Conservative Estimates** - Underestimates by design, defensible assumptions
|
|
63
|
-
- **Executive Output** - VP/Director/CFO-ready reports
|
|
21
|
+
# Import from CSV/JSON file
|
|
22
|
+
npx kanmi-perf-revenue --file sessions.csv --client "Acme Corp"
|
|
64
23
|
|
|
65
|
-
|
|
24
|
+
# Use Datadog RUM directly
|
|
25
|
+
DD_API_KEY=xxx DD_APP_KEY=xxx npx kanmi-perf-revenue --start 2025-01-01 --end 2025-01-14
|
|
26
|
+
```
|
|
66
27
|
|
|
67
|
-
###
|
|
28
|
+
### Library Usage
|
|
68
29
|
|
|
69
|
-
|
|
30
|
+
```typescript
|
|
31
|
+
import {
|
|
32
|
+
analyzeFromFile,
|
|
33
|
+
analyzeWithMockData,
|
|
34
|
+
analyzeWithDatadog,
|
|
35
|
+
} from 'kanmi-perf-revenue';
|
|
36
|
+
|
|
37
|
+
// From CSV/JSON
|
|
38
|
+
const result = analyzeFromFile({
|
|
39
|
+
filePath: './sessions.csv',
|
|
40
|
+
clientName: 'Acme Corp',
|
|
41
|
+
});
|
|
70
42
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
43
|
+
// From Datadog RUM
|
|
44
|
+
const result = await analyzeWithDatadog({
|
|
45
|
+
apiKey: process.env.DD_API_KEY,
|
|
46
|
+
appKey: process.env.DD_APP_KEY,
|
|
47
|
+
startDate: '2025-01-01',
|
|
48
|
+
endDate: '2025-01-14',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
console.log(result.report);
|
|
52
|
+
console.log(`Top opportunity: $${result.topOpportunity?.monthlyRevenue}/month`);
|
|
79
53
|
```
|
|
80
54
|
|
|
81
|
-
|
|
55
|
+
## What You Get
|
|
82
56
|
|
|
83
|
-
|
|
57
|
+
### Empirical Conversion Curves
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
--name <id> # Client identifier
|
|
95
|
-
--display-name <name> # Display name
|
|
96
|
-
--ga4-project <id> # GCP project ID
|
|
97
|
-
--ga4-property <id> # GA4 property ID
|
|
98
|
-
--ga4-key-file <path> # Service account JSON (optional)
|
|
99
|
-
--datadog-app <id> # Datadog RUM app ID
|
|
100
|
-
--datadog-site <site> # Datadog site (default: datadoghq.com)
|
|
101
|
-
|
|
102
|
-
# Remove a client
|
|
103
|
-
perf-revenue config remove-client <name>
|
|
104
|
-
|
|
105
|
-
# List clients
|
|
106
|
-
perf-revenue config list-clients
|
|
59
|
+
Actual CVR measured at each performance bucket:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
| LCP Range | Sessions | CVR | Revenue |
|
|
63
|
+
|-------------|----------|--------|---------|
|
|
64
|
+
| 0.0s-1.0s | 1,852 | 3.67% | $8K |
|
|
65
|
+
| 1.0s-1.5s | 12,339 | 2.79% | $40K |
|
|
66
|
+
| 2.0s-2.5s | 13,684 | 2.22% | $37K |
|
|
67
|
+
| 3.0s+ | 420 | 1.40% | $500 |
|
|
107
68
|
```
|
|
108
69
|
|
|
109
|
-
###
|
|
70
|
+
### Revenue Opportunity Analysis
|
|
110
71
|
|
|
111
|
-
|
|
72
|
+
Prioritized recommendations with dollar amounts:
|
|
112
73
|
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
|
|
74
|
+
```
|
|
75
|
+
Top Opportunity: LCP
|
|
76
|
+
37% of sessions have LCP > 2.5s
|
|
77
|
+
These sessions convert 18.5% worse than faster sessions
|
|
78
|
+
Monthly revenue opportunity: $10K/month
|
|
116
79
|
```
|
|
117
80
|
|
|
118
|
-
##
|
|
119
|
-
|
|
120
|
-
Configuration is stored in `~/.perf-revenue/`:
|
|
81
|
+
## Features
|
|
121
82
|
|
|
83
|
+
| Feature | Description |
|
|
84
|
+
|---------|-------------|
|
|
85
|
+
| **8 Performance Metrics** | LCP, FCP, INP, CLS, TTFB, TTI, Onload, Page Size |
|
|
86
|
+
| **Segmentation** | Device, page type, geography, traffic source |
|
|
87
|
+
| **Statistical Significance** | Confidence intervals, p-values, effect sizes |
|
|
88
|
+
| **Correlation Analysis** | Which metrics correlate most with conversions |
|
|
89
|
+
| **Multi-Metric Interactions** | How LCP + INP together affect CVR |
|
|
90
|
+
| **Seasonality Patterns** | Hour-of-day, day-of-week analysis |
|
|
91
|
+
| **Funnel Analysis** | Where in the journey does performance matter most |
|
|
92
|
+
| **ROI Calculator** | Engineering effort vs expected revenue gain |
|
|
93
|
+
| **Forecasting** | 12-month revenue projections |
|
|
94
|
+
| **Cohort Analysis** | LTV by performance cohort |
|
|
95
|
+
| **A/B Test Integration** | Compare performance variants statistically |
|
|
96
|
+
| **Attribution Models** | First-touch, last-touch, linear, position-based |
|
|
97
|
+
| **Alerting** | Threshold breaches, regressions, anomalies |
|
|
98
|
+
| **Export Formats** | JSON, CSV, Slack blocks, HTML email, webhooks |
|
|
99
|
+
|
|
100
|
+
## Data Input Format
|
|
101
|
+
|
|
102
|
+
### CSV/JSON
|
|
103
|
+
|
|
104
|
+
Required columns:
|
|
105
|
+
- `session_id` — Unique session identifier
|
|
106
|
+
- `converted` or `has_purchase` — Boolean or 0/1
|
|
107
|
+
|
|
108
|
+
Optional columns:
|
|
109
|
+
- `lcp_ms`, `inp_ms`, `cls`, `fcp_ms`, `ttfb_ms` — Performance metrics
|
|
110
|
+
- `order_value` or `revenue` — Purchase amount
|
|
111
|
+
- `device` — mobile, desktop, tablet
|
|
112
|
+
- `page_type` — pdp, plp, checkout, home, etc.
|
|
113
|
+
- `country`, `traffic_source` — Segmentation
|
|
114
|
+
- `timestamp` — For time-based analysis
|
|
115
|
+
|
|
116
|
+
Example CSV:
|
|
117
|
+
```csv
|
|
118
|
+
session_id,lcp_ms,converted,order_value,device,page_type
|
|
119
|
+
abc123,1200,1,89.99,mobile,pdp
|
|
120
|
+
def456,3500,0,0,desktop,plp
|
|
121
|
+
ghi789,800,1,150.00,mobile,checkout
|
|
122
122
|
```
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
|
|
124
|
+
### Datadog RUM
|
|
125
|
+
|
|
126
|
+
The tool queries Datadog's RUM API for session-level data including Core Web Vitals, user actions, and custom events.
|
|
127
|
+
|
|
128
|
+
## CLI Reference
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
kanmi-perf-revenue [options]
|
|
132
|
+
|
|
133
|
+
Data Sources:
|
|
134
|
+
--file PATH Import from CSV or JSON file
|
|
135
|
+
--demo Run with mock data (for testing)
|
|
136
|
+
--api-key KEY Datadog API key (or set DD_API_KEY)
|
|
137
|
+
--app-key KEY Datadog App key (or set DD_APP_KEY)
|
|
138
|
+
|
|
139
|
+
Options:
|
|
140
|
+
--start DATE Start date (YYYY-MM-DD). Default: 14 days ago
|
|
141
|
+
--end DATE End date (YYYY-MM-DD). Default: today
|
|
142
|
+
--client NAME Client name for report header
|
|
143
|
+
--help, -h Show help
|
|
144
|
+
|
|
145
|
+
History & Tracking:
|
|
146
|
+
--save Save analysis to history
|
|
147
|
+
--tag TAG Tag the entry (e.g., "baseline", "post-fix")
|
|
148
|
+
--compare Compare to baseline
|
|
149
|
+
--history Show analysis history
|
|
150
|
+
--trend Show CVR trend over time
|
|
151
|
+
--metric METRIC Metric for trend (lcp, inp, cls)
|
|
126
152
|
```
|
|
127
153
|
|
|
128
|
-
###
|
|
154
|
+
### Workflow Example
|
|
129
155
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
| `DATADOG_API_KEY` | Yes | Datadog API key |
|
|
134
|
-
| `DATADOG_APP_KEY` | Yes | Datadog application key |
|
|
135
|
-
| `GOOGLE_APPLICATION_CREDENTIALS` | No | Path to GCP service account JSON |
|
|
156
|
+
```bash
|
|
157
|
+
# 1. Establish baseline
|
|
158
|
+
kanmi-perf-revenue --file week1.csv --save --tag baseline
|
|
136
159
|
|
|
137
|
-
|
|
160
|
+
# 2. After performance fix, compare
|
|
161
|
+
kanmi-perf-revenue --file week2.csv --save --tag post-fix --compare
|
|
138
162
|
|
|
139
|
-
|
|
163
|
+
# 3. View trend over time
|
|
164
|
+
kanmi-perf-revenue --trend --metric lcp
|
|
140
165
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
| 100ms INP improvement | +0.3% conversion rate |
|
|
145
|
-
| 0.01 CLS improvement | +0.1% conversion rate |
|
|
166
|
+
# 4. View history
|
|
167
|
+
kanmi-perf-revenue --history
|
|
168
|
+
```
|
|
146
169
|
|
|
147
|
-
##
|
|
170
|
+
## Advanced Usage
|
|
148
171
|
|
|
149
|
-
|
|
172
|
+
### Segmentation Analysis
|
|
150
173
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
3. **Prioritized Fix Order** - Ranked by financial impact
|
|
154
|
-
4. **What Not To Fix** - Issues below threshold
|
|
155
|
-
5. **Decision Guidance** - Actionable recommendations
|
|
174
|
+
```typescript
|
|
175
|
+
import { analyzeBySegment, generateSegmentationMarkdown } from 'kanmi-perf-revenue';
|
|
156
176
|
|
|
157
|
-
|
|
177
|
+
const report = analyzeBySegment(sessions, 'device');
|
|
178
|
+
console.log(generateSegmentationMarkdown(report));
|
|
179
|
+
// Shows CVR breakdown by mobile vs desktop vs tablet
|
|
180
|
+
```
|
|
158
181
|
|
|
159
|
-
|
|
182
|
+
### Statistical Testing
|
|
160
183
|
|
|
161
184
|
```typescript
|
|
162
185
|
import {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
} from '
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
twoProportionZTest,
|
|
187
|
+
calculateConfidenceInterval,
|
|
188
|
+
calculateRequiredSampleSize,
|
|
189
|
+
} from 'kanmi-perf-revenue';
|
|
190
|
+
|
|
191
|
+
// Compare two groups
|
|
192
|
+
const test = twoProportionZTest('fast', 150, 5000, 'slow', 80, 4000);
|
|
193
|
+
console.log(`p-value: ${test.p_value}, significant: ${test.is_significant}`);
|
|
194
|
+
|
|
195
|
+
// Sample size planning
|
|
196
|
+
const required = calculateRequiredSampleSize(0.03, 0.1); // 3% baseline, detect 10% lift
|
|
197
|
+
console.log(`Need ${required.sample_size_per_group} sessions per group`);
|
|
198
|
+
```
|
|
173
199
|
|
|
174
|
-
|
|
175
|
-
site: 'datadoghq.com',
|
|
176
|
-
applicationId: 'rum-app-id',
|
|
177
|
-
});
|
|
200
|
+
### ROI Calculation
|
|
178
201
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const datadogData = await fetchDatadogData(datadog);
|
|
182
|
-
const result = runAnalysis(ga4Data, datadogData, siteTotals);
|
|
183
|
-
```
|
|
202
|
+
```typescript
|
|
203
|
+
import { calculateROI, DEFAULT_COSTS } from 'kanmi-perf-revenue';
|
|
184
204
|
|
|
185
|
-
|
|
205
|
+
const roi = calculateROI(
|
|
206
|
+
{ metric: 'lcp', currentValue: 3500, targetValue: 2500, description: 'CDN optimization' },
|
|
207
|
+
sessions,
|
|
208
|
+
{ ...DEFAULT_COSTS, engineeringHours: 40 }
|
|
209
|
+
);
|
|
186
210
|
|
|
187
|
-
|
|
211
|
+
console.log(`ROI: ${roi.roi.roiPercent}%, break-even: ${roi.roi.breakEvenDays} days`);
|
|
212
|
+
console.log(`Recommendation: ${roi.roi.recommendation}`);
|
|
213
|
+
```
|
|
188
214
|
|
|
189
|
-
|
|
190
|
-
- Funnel drop-off analysis
|
|
191
|
-
- Conversion path journeys
|
|
215
|
+
### Alerting
|
|
192
216
|
|
|
193
|
-
|
|
217
|
+
```typescript
|
|
218
|
+
import { generateAlertReport, DEFAULT_ALERT_CONFIG } from 'kanmi-perf-revenue';
|
|
194
219
|
|
|
195
|
-
|
|
196
|
-
- Performance band distribution
|
|
197
|
-
- Frustration signals
|
|
220
|
+
const alerts = generateAlertReport(sessions, DEFAULT_ALERT_CONFIG, baselineSessions);
|
|
198
221
|
|
|
199
|
-
|
|
222
|
+
if (alerts.summary.critical > 0) {
|
|
223
|
+
console.log('CRITICAL ALERTS:', alerts.alerts.filter(a => a.severity === 'critical'));
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Export to Slack
|
|
200
228
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- Page type (checkout, pdp, plp, etc.)
|
|
204
|
-
- Device category (mobile, desktop, tablet)
|
|
229
|
+
```typescript
|
|
230
|
+
import { exportToSlack } from 'kanmi-perf-revenue';
|
|
205
231
|
|
|
206
|
-
|
|
232
|
+
const slackMessage = exportToSlack(result, { clientName: 'Acme Corp' });
|
|
233
|
+
// Send slackMessage.blocks to Slack API
|
|
234
|
+
```
|
|
207
235
|
|
|
208
|
-
##
|
|
236
|
+
## How It Works
|
|
209
237
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
238
|
+
1. **Bucket sessions by performance** — Group sessions into performance ranges (e.g., 0-1s, 1-2s, 2-3s LCP)
|
|
239
|
+
2. **Measure actual CVR per bucket** — Calculate conversion rate from your real data
|
|
240
|
+
3. **Calculate opportunity** — If slow sessions performed like fast sessions, how many more conversions?
|
|
241
|
+
4. **Prioritize by revenue impact** — Rank metrics by potential monthly revenue gain
|
|
213
242
|
|
|
214
|
-
|
|
215
|
-
npm run build
|
|
243
|
+
No industry benchmarks. No assumed coefficients. Just your data.
|
|
216
244
|
|
|
217
|
-
|
|
218
|
-
npm run typecheck
|
|
245
|
+
## Why Empirical?
|
|
219
246
|
|
|
220
|
-
|
|
221
|
-
npm run cli -- analyze --client test -v
|
|
222
|
-
```
|
|
247
|
+
Traditional performance-revenue models assume fixed relationships like "0.5% CVR per 100ms LCP improvement." These assumptions:
|
|
223
248
|
|
|
224
|
-
|
|
249
|
+
- Come from other companies' data, not yours
|
|
250
|
+
- May not apply to your industry, audience, or product
|
|
251
|
+
- Create false precision
|
|
225
252
|
|
|
226
|
-
|
|
227
|
-
src/
|
|
228
|
-
├── adapters/ # GA4 + Datadog data adapters
|
|
229
|
-
│ ├── ga4-adapter.ts
|
|
230
|
-
│ ├── datadog-adapter.ts
|
|
231
|
-
│ └── correlation-spec.ts
|
|
232
|
-
├── engine/ # Core analysis logic
|
|
233
|
-
│ ├── orchestrator.ts
|
|
234
|
-
│ ├── assisted-attribution.ts
|
|
235
|
-
│ └── period-utils.ts
|
|
236
|
-
├── schema/ # Type definitions
|
|
237
|
-
├── cli/ # Autonomous CLI
|
|
238
|
-
│ ├── index.ts # Entry point
|
|
239
|
-
│ ├── agent.ts # Claude agent
|
|
240
|
-
│ ├── config.ts # Configuration
|
|
241
|
-
│ └── tools/ # Agent tools
|
|
242
|
-
└── prompts/ # System prompts
|
|
243
|
-
```
|
|
253
|
+
This tool measures the actual relationship in YOUR data. If your fast sessions convert 3.5% and slow sessions convert 2.1%, that's a 67% relative difference — measured, not assumed.
|
|
244
254
|
|
|
245
255
|
## License
|
|
246
256
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A/B Test Integration
|
|
3
|
+
*
|
|
4
|
+
* Compare performance variants and analyze their impact on conversions.
|
|
5
|
+
* Integrates with experiment data to determine if performance changes
|
|
6
|
+
* drove conversion improvements.
|
|
7
|
+
*
|
|
8
|
+
* @author Kanmi Obasa <i@kanmiobasa.com>
|
|
9
|
+
*/
|
|
10
|
+
import type { SessionData } from './datadog-session-query.js';
|
|
11
|
+
export interface ABTestVariant {
|
|
12
|
+
/** Variant identifier */
|
|
13
|
+
variantId: string;
|
|
14
|
+
/** Variant name/description */
|
|
15
|
+
name: string;
|
|
16
|
+
/** Sessions in this variant */
|
|
17
|
+
sessions: number;
|
|
18
|
+
/** Conversions in this variant */
|
|
19
|
+
conversions: number;
|
|
20
|
+
/** Conversion rate */
|
|
21
|
+
cvr: number;
|
|
22
|
+
/** 95% confidence interval */
|
|
23
|
+
cvrCI: {
|
|
24
|
+
lower: number;
|
|
25
|
+
upper: number;
|
|
26
|
+
};
|
|
27
|
+
/** Average LCP */
|
|
28
|
+
avgLcp: number | null;
|
|
29
|
+
/** Average INP */
|
|
30
|
+
avgInp: number | null;
|
|
31
|
+
/** p75 LCP */
|
|
32
|
+
p75Lcp: number | null;
|
|
33
|
+
}
|
|
34
|
+
export interface ABTestComparison {
|
|
35
|
+
control: ABTestVariant;
|
|
36
|
+
treatment: ABTestVariant;
|
|
37
|
+
/** Absolute CVR difference */
|
|
38
|
+
absoluteDifference: number;
|
|
39
|
+
/** Relative CVR difference (treatment vs control) */
|
|
40
|
+
relativeDifference: number;
|
|
41
|
+
/** p-value from z-test */
|
|
42
|
+
pValue: number;
|
|
43
|
+
/** Is statistically significant at alpha=0.05? */
|
|
44
|
+
isSignificant: boolean;
|
|
45
|
+
/** Effect size (Cohen's h) */
|
|
46
|
+
effectSize: number;
|
|
47
|
+
/** Performance comparison */
|
|
48
|
+
performanceComparison: {
|
|
49
|
+
lcpDelta: number | null;
|
|
50
|
+
inpDelta: number | null;
|
|
51
|
+
/** Did performance improve? */
|
|
52
|
+
performanceImproved: boolean;
|
|
53
|
+
};
|
|
54
|
+
/** Recommendation */
|
|
55
|
+
recommendation: 'ship_treatment' | 'keep_control' | 'need_more_data' | 'inconclusive';
|
|
56
|
+
rationale: string;
|
|
57
|
+
}
|
|
58
|
+
export interface ABTestReport {
|
|
59
|
+
experimentId: string;
|
|
60
|
+
variants: ABTestVariant[];
|
|
61
|
+
comparisons: ABTestComparison[];
|
|
62
|
+
winner: ABTestVariant | null;
|
|
63
|
+
sampleSizeAnalysis: {
|
|
64
|
+
currentSamples: number;
|
|
65
|
+
requiredSamples: number;
|
|
66
|
+
isSufficient: boolean;
|
|
67
|
+
daysToSignificance: number | null;
|
|
68
|
+
};
|
|
69
|
+
insights: string[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Analyze an A/B test from session data.
|
|
73
|
+
*/
|
|
74
|
+
export declare function analyzeABTest(sessions: SessionData[], experimentId?: string): ABTestReport | null;
|
|
75
|
+
/**
|
|
76
|
+
* Create a synthetic A/B test by splitting sessions on performance.
|
|
77
|
+
*/
|
|
78
|
+
export declare function createPerformanceExperiment(sessions: SessionData[], metric: "lcp" | "inp" | "cls" | undefined, threshold: number): ABTestReport;
|
|
79
|
+
/**
|
|
80
|
+
* Generate markdown report for A/B test.
|
|
81
|
+
*/
|
|
82
|
+
export declare function generateABTestMarkdown(report: ABTestReport): string;
|
|
83
|
+
//# sourceMappingURL=ab-testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../src/empirical/ab-testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAY9D,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,kBAAkB;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kBAAkB;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,aAAa,CAAC;IACzB,8BAA8B;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,qBAAqB,EAAE;QACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,+BAA+B;QAC/B,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF,qBAAqB;IACrB,cAAc,EAAE,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,GAAG,cAAc,CAAC;IACtF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,OAAO,CAAC;QACtB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC,CAAC;IACF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,WAAW,EAAE,EACvB,YAAY,CAAC,EAAE,MAAM,GACpB,YAAY,GAAG,IAAI,CAyHrB;AAsED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,WAAW,EAAE,EACvB,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,YAAQ,EACrC,SAAS,EAAE,MAAM,GAChB,YAAY,CAwCd;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA+EnE"}
|