@coursebuilder/analytics 1.1.0 → 1.1.2-canary.0.0c9beb2ae
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/dist/api/index.d.ts +22 -2
- package/dist/api/index.js +40 -5
- package/dist/api/index.js.map +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +43 -1
- package/dist/catalog.js.map +1 -1
- package/dist/components/index.d.ts +46 -1
- package/dist/components/index.js +200 -8
- package/dist/components/index.js.map +1 -1
- package/dist/engine.js +94 -6
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +94 -6
- package/dist/index.js.map +1 -1
- package/dist/providers/database.d.ts +174 -2
- package/dist/providers/database.js +711 -20
- package/dist/providers/database.js.map +1 -1
- package/dist/providers/index.js +713 -22
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/survey.d.ts +1 -1
- package/dist/providers/survey.js +2 -2
- package/dist/providers/survey.js.map +1 -1
- package/dist/types.d.ts +189 -3
- package/package.json +7 -5
- package/src/api/catalog-handler.ts +44 -2
- package/src/api/token-handler.ts +3 -2
- package/src/catalog.ts +49 -1
- package/src/components/omnibus-dashboard.tsx +340 -6
- package/src/engine.ts +69 -8
- package/src/providers/attribution-recovery.test.ts +63 -0
- package/src/providers/attribution-recovery.ts +97 -0
- package/src/providers/database.ts +880 -42
- package/src/providers/survey.ts +3 -1
- package/src/types.ts +215 -2
package/src/providers/survey.ts
CHANGED
|
@@ -117,6 +117,7 @@ export interface SurveyAnalyticsProvider {
|
|
|
117
117
|
getSurveyResponses: (
|
|
118
118
|
range?: AnalyticsRange,
|
|
119
119
|
limit?: number,
|
|
120
|
+
offset?: number,
|
|
120
121
|
) => Promise<
|
|
121
122
|
Array<{
|
|
122
123
|
responseId: string
|
|
@@ -458,10 +459,11 @@ export function createSurveyProvider(
|
|
|
458
459
|
async function getSurveyResponses(
|
|
459
460
|
range: AnalyticsRange = '30d',
|
|
460
461
|
limit = 100,
|
|
462
|
+
offset = 0,
|
|
461
463
|
) {
|
|
462
464
|
const canonicalRows = await fetchCanonicalRows(range)
|
|
463
465
|
|
|
464
|
-
return canonicalRows.slice(
|
|
466
|
+
return canonicalRows.slice(offset, offset + limit).map((row) => ({
|
|
465
467
|
responseId: row.responseId,
|
|
466
468
|
surveyId: row.surveyId,
|
|
467
469
|
surveyTitle: row.surveyTitle ?? '',
|
package/src/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type Minutes = Brand<number, 'Minutes'>
|
|
|
9
9
|
export type Seconds = Brand<number, 'Seconds'>
|
|
10
10
|
|
|
11
11
|
export type AnalyticsRange = '24h' | '7d' | '30d' | '90d' | 'all'
|
|
12
|
+
export type TrafficAnalyticsRange = AnalyticsRange | '180d'
|
|
12
13
|
|
|
13
14
|
export interface RevenueSummary {
|
|
14
15
|
totalRevenue: USD
|
|
@@ -45,6 +46,8 @@ export interface RecentPurchase {
|
|
|
45
46
|
couponId: string | null
|
|
46
47
|
userName: string | null
|
|
47
48
|
userEmail: string | null
|
|
49
|
+
isTeam?: boolean
|
|
50
|
+
seats?: number | null
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
export interface AttributionCount {
|
|
@@ -57,11 +60,20 @@ export interface ShortlinkPerformance {
|
|
|
57
60
|
slug: string
|
|
58
61
|
url: string
|
|
59
62
|
clicks: Count
|
|
63
|
+
signups?: Count
|
|
64
|
+
purchases?: Count
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
export type CommerceRecordKind =
|
|
68
|
+
| 'paid_conversion'
|
|
69
|
+
| 'access_grant'
|
|
70
|
+
| 'synthetic'
|
|
71
|
+
| 'unknown'
|
|
72
|
+
|
|
62
73
|
export interface RevenueBySource {
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
kind?: CommerceRecordKind
|
|
75
|
+
source: string | null
|
|
76
|
+
medium: string | null
|
|
65
77
|
campaign: string | null
|
|
66
78
|
revenue: USD
|
|
67
79
|
count: Count
|
|
@@ -81,12 +93,85 @@ export interface ContentCorrelation {
|
|
|
81
93
|
purchaserCount: Count
|
|
82
94
|
}
|
|
83
95
|
|
|
96
|
+
export interface CommerceLaneSummary {
|
|
97
|
+
commerceRecords: Count
|
|
98
|
+
paidPurchases: Count
|
|
99
|
+
paidRevenue: USD
|
|
100
|
+
accessGrants: Count
|
|
101
|
+
accessGrantRevenue: USD
|
|
102
|
+
freeUpgrades: Count
|
|
103
|
+
syntheticPurchases: Count
|
|
104
|
+
byAccessGrantReason: Record<string, Count>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface AttributionSignalSummary {
|
|
108
|
+
shortlink: Count
|
|
109
|
+
utm: Count
|
|
110
|
+
paidClickId: Count
|
|
111
|
+
gaClientId: Count
|
|
112
|
+
selfReportedSource: Count
|
|
113
|
+
recoveredFromShortlinkAttributionTable?: Count
|
|
114
|
+
internalFreeUpgrade: Count
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type AttributionQualityLaneName =
|
|
118
|
+
| 'strong'
|
|
119
|
+
| 'medium'
|
|
120
|
+
| 'weak'
|
|
121
|
+
| 'unknown'
|
|
122
|
+
|
|
123
|
+
export interface AttributionQualityLane {
|
|
124
|
+
lane: AttributionQualityLaneName
|
|
125
|
+
purchases: Count
|
|
126
|
+
revenue: USD
|
|
127
|
+
revenuePercent: Percentage
|
|
128
|
+
notes: string[]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface AttributionQualitySummary {
|
|
132
|
+
strong: AttributionQualityLane
|
|
133
|
+
medium: AttributionQualityLane
|
|
134
|
+
weak: AttributionQualityLane
|
|
135
|
+
unknown: AttributionQualityLane
|
|
136
|
+
}
|
|
137
|
+
|
|
84
138
|
export interface AttributionCoverage {
|
|
85
139
|
totalRevenue: USD
|
|
86
140
|
attributedRevenue: USD
|
|
87
141
|
unattributedRevenue: USD
|
|
88
142
|
attributionRate: Percentage
|
|
89
143
|
totalPurchases: Count
|
|
144
|
+
paidPurchases?: Count
|
|
145
|
+
purchaseFieldAttributedPurchases?: Count
|
|
146
|
+
purchaseFieldAttributedRevenue?: USD
|
|
147
|
+
recoveredFromShortlinkAttributionTablePurchases?: Count
|
|
148
|
+
recoveredFromShortlinkAttributionTableRevenue?: USD
|
|
149
|
+
commerceRecords?: Count
|
|
150
|
+
accessGrants?: Count
|
|
151
|
+
freeUpgrades?: Count
|
|
152
|
+
syntheticPurchases?: Count
|
|
153
|
+
commerce?: CommerceLaneSummary
|
|
154
|
+
signals?: AttributionSignalSummary
|
|
155
|
+
quality?: AttributionQualitySummary
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface TrafficBreakdownRow {
|
|
159
|
+
sessions: Count
|
|
160
|
+
users: Count
|
|
161
|
+
sessionPercent: Percentage
|
|
162
|
+
trafficSessionPercent: Percentage
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface DeviceCategoryBreakdown extends TrafficBreakdownRow {
|
|
166
|
+
deviceCategory: string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface OperatingSystemBreakdown extends TrafficBreakdownRow {
|
|
170
|
+
operatingSystem: string
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ScreenResolutionBreakdown extends TrafficBreakdownRow {
|
|
174
|
+
screenResolution: string
|
|
90
175
|
}
|
|
91
176
|
|
|
92
177
|
export interface TrafficOverview {
|
|
@@ -96,6 +181,9 @@ export interface TrafficOverview {
|
|
|
96
181
|
pageviews: Count
|
|
97
182
|
avgSessionDuration: Seconds
|
|
98
183
|
bounceRate: Percentage
|
|
184
|
+
deviceCategories?: DeviceCategoryBreakdown[]
|
|
185
|
+
operatingSystems?: OperatingSystemBreakdown[]
|
|
186
|
+
screenResolutions?: ScreenResolutionBreakdown[]
|
|
99
187
|
}
|
|
100
188
|
|
|
101
189
|
export interface TrafficDaily {
|
|
@@ -279,6 +367,119 @@ export interface SurveyRevenueCorrelation {
|
|
|
279
367
|
byQuestion: SurveyConversionByQuestion[]
|
|
280
368
|
}
|
|
281
369
|
|
|
370
|
+
/** One survey answer bucket correlated to paid product revenue. */
|
|
371
|
+
export interface ProductSurveyRevenueAnswer {
|
|
372
|
+
surveyId: string
|
|
373
|
+
surveyTitle: string | null
|
|
374
|
+
surveySlug: string | null
|
|
375
|
+
questionId: string
|
|
376
|
+
question: string | null
|
|
377
|
+
answer: string
|
|
378
|
+
responses: Count
|
|
379
|
+
uniqueRespondents: Count
|
|
380
|
+
paidPurchasers: Count
|
|
381
|
+
paidRevenue: USD
|
|
382
|
+
conversionRate: Percentage
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** Product-filtered survey revenue report with aggregate counts and answer buckets. */
|
|
386
|
+
export interface ProductSurveyRevenueCorrelation {
|
|
387
|
+
productId: string | null
|
|
388
|
+
surveyId: string | null
|
|
389
|
+
surveySlug: string | null
|
|
390
|
+
totalResponses: Count
|
|
391
|
+
uniqueRespondents: Count
|
|
392
|
+
respondentsWithUserId: Count
|
|
393
|
+
paidPurchasers: Count
|
|
394
|
+
paidRevenue: USD
|
|
395
|
+
byAnswer: ProductSurveyRevenueAnswer[]
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/** Single-purchase attribution receipt used by operator audits and checkout debugging. */
|
|
399
|
+
export interface CheckoutAttributionReceipt {
|
|
400
|
+
purchase: {
|
|
401
|
+
id: string
|
|
402
|
+
createdAt: Date | string | null
|
|
403
|
+
productId: string | null
|
|
404
|
+
productName: string | null
|
|
405
|
+
totalAmount: USD
|
|
406
|
+
status: string | null
|
|
407
|
+
country: string | null
|
|
408
|
+
} | null
|
|
409
|
+
checks: {
|
|
410
|
+
purchaseFound: boolean
|
|
411
|
+
attributionSnapshot: boolean
|
|
412
|
+
utm: boolean
|
|
413
|
+
actualUtm: boolean
|
|
414
|
+
clickId: boolean
|
|
415
|
+
synthetic: boolean
|
|
416
|
+
shortlink: boolean
|
|
417
|
+
selfReportedSource: boolean
|
|
418
|
+
gaClientId: boolean
|
|
419
|
+
}
|
|
420
|
+
attribution: Record<string, unknown> | null
|
|
421
|
+
legacy: Record<string, unknown>
|
|
422
|
+
fieldKeys: string[]
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** Checkout survey answer bucket for otherwise dark purchase recovery analysis. */
|
|
426
|
+
export interface CheckoutSurveyFallbackAnswer {
|
|
427
|
+
answer: string
|
|
428
|
+
confidence: 'exact_purchase_link' | 'user_linked'
|
|
429
|
+
purchases: Count
|
|
430
|
+
revenue: USD
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/** Report-only fallback from checkout survey responses to dark purchase revenue. */
|
|
434
|
+
export interface CheckoutSurveyFallbackReport {
|
|
435
|
+
label: 'recovered_from_checkout_survey_response'
|
|
436
|
+
productId: string | null
|
|
437
|
+
totalDarkPurchases: Count
|
|
438
|
+
totalDarkRevenue: USD
|
|
439
|
+
exactPurchaseLinkedPurchases: Count
|
|
440
|
+
exactPurchaseLinkedRevenue: USD
|
|
441
|
+
userLinkedPurchases: Count
|
|
442
|
+
userLinkedRevenue: USD
|
|
443
|
+
byAnswer: CheckoutSurveyFallbackAnswer[]
|
|
444
|
+
notes: string[]
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export interface ValuePathAnswerBucket {
|
|
448
|
+
key: string
|
|
449
|
+
step: string
|
|
450
|
+
optionValue: string
|
|
451
|
+
count: Count
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export interface ValuePathStepBucket {
|
|
455
|
+
step: string
|
|
456
|
+
count: Count
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export interface ValuePathTerminalBucket {
|
|
460
|
+
emailResourceId: string
|
|
461
|
+
count: Count
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface ValuePathSummary {
|
|
465
|
+
contacts: Count
|
|
466
|
+
events: Count
|
|
467
|
+
intents: Count
|
|
468
|
+
completedIntents: Count
|
|
469
|
+
pendingIntents: Count
|
|
470
|
+
blockedIntents: Count
|
|
471
|
+
answerEvents: Count
|
|
472
|
+
dripEvents: Count
|
|
473
|
+
enteredEvents: Count
|
|
474
|
+
participantsWithAnswerClicks: Count
|
|
475
|
+
participantsWithNoAnswerClicks: Count
|
|
476
|
+
terminalParticipants: Count
|
|
477
|
+
answerOptions: ValuePathAnswerBucket[]
|
|
478
|
+
answerSteps: ValuePathStepBucket[]
|
|
479
|
+
terminalSteps: ValuePathTerminalBucket[]
|
|
480
|
+
notes: string[]
|
|
481
|
+
}
|
|
482
|
+
|
|
282
483
|
export interface SurfaceMap {
|
|
283
484
|
summary: RevenueSummary
|
|
284
485
|
'revenue/daily': RevenueDaily[]
|
|
@@ -291,6 +492,7 @@ export interface SurfaceMap {
|
|
|
291
492
|
'attribution/funnel': ConversionFunnel
|
|
292
493
|
'attribution/content': ContentCorrelation[]
|
|
293
494
|
'attribution/coverage': AttributionCoverage
|
|
495
|
+
'attribution/commerce-lanes': CommerceLaneSummary
|
|
294
496
|
traffic: TrafficOverview
|
|
295
497
|
'traffic/daily': TrafficDaily[]
|
|
296
498
|
'traffic/pages': TopPage[]
|
|
@@ -307,7 +509,12 @@ export interface SurfaceMap {
|
|
|
307
509
|
'surveys/questions': SurveyQuestionBreakdown[]
|
|
308
510
|
'surveys/responses': SurveyResponseRow[]
|
|
309
511
|
'correlation/survey-revenue': SurveyRevenueCorrelation
|
|
512
|
+
'correlation/survey-revenue/product': ProductSurveyRevenueCorrelation
|
|
310
513
|
'attribution/email-campaigns': EmailRevenueOverview
|
|
514
|
+
'attribution/email-campaigns/strict': EmailRevenueOverview
|
|
515
|
+
'attribution/checkout-receipt': CheckoutAttributionReceipt
|
|
516
|
+
'attribution/checkout-survey-fallback': CheckoutSurveyFallbackReport
|
|
517
|
+
'value-paths/summary': ValuePathSummary
|
|
311
518
|
}
|
|
312
519
|
|
|
313
520
|
export type SurfaceName = keyof SurfaceMap
|
|
@@ -315,6 +522,12 @@ export type SurfaceName = keyof SurfaceMap
|
|
|
315
522
|
export interface QueryOptions {
|
|
316
523
|
range?: AnalyticsRange
|
|
317
524
|
limit?: number
|
|
525
|
+
offset?: number
|
|
526
|
+
productId?: string
|
|
527
|
+
purchaseId?: string
|
|
528
|
+
surveyId?: string
|
|
529
|
+
surveySlug?: string
|
|
530
|
+
questionId?: string
|
|
318
531
|
}
|
|
319
532
|
|
|
320
533
|
export type QueryResult<S extends SurfaceName> =
|