@coursebuilder/analytics 1.1.0 → 1.1.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/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 +29 -0
- package/dist/components/index.js +91 -2
- 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 +144 -2
- package/dist/providers/database.js +652 -20
- package/dist/providers/database.js.map +1 -1
- package/dist/providers/index.js +654 -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 +151 -3
- package/package.json +5 -3
- 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 +163 -0
- package/src/engine.ts +66 -6
- package/src/providers/attribution-recovery.test.ts +63 -0
- package/src/providers/attribution-recovery.ts +97 -0
- package/src/providers/database.ts +812 -42
- package/src/providers/survey.ts +3 -1
- package/src/types.ts +166 -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
|
@@ -59,9 +59,16 @@ export interface ShortlinkPerformance {
|
|
|
59
59
|
clicks: Count
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
export type CommerceRecordKind =
|
|
63
|
+
| 'paid_conversion'
|
|
64
|
+
| 'access_grant'
|
|
65
|
+
| 'synthetic'
|
|
66
|
+
| 'unknown'
|
|
67
|
+
|
|
62
68
|
export interface RevenueBySource {
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
kind?: CommerceRecordKind
|
|
70
|
+
source: string | null
|
|
71
|
+
medium: string | null
|
|
65
72
|
campaign: string | null
|
|
66
73
|
revenue: USD
|
|
67
74
|
count: Count
|
|
@@ -81,12 +88,44 @@ export interface ContentCorrelation {
|
|
|
81
88
|
purchaserCount: Count
|
|
82
89
|
}
|
|
83
90
|
|
|
91
|
+
export interface CommerceLaneSummary {
|
|
92
|
+
commerceRecords: Count
|
|
93
|
+
paidPurchases: Count
|
|
94
|
+
paidRevenue: USD
|
|
95
|
+
accessGrants: Count
|
|
96
|
+
accessGrantRevenue: USD
|
|
97
|
+
freeUpgrades: Count
|
|
98
|
+
syntheticPurchases: Count
|
|
99
|
+
byAccessGrantReason: Record<string, Count>
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface AttributionSignalSummary {
|
|
103
|
+
shortlink: Count
|
|
104
|
+
utm: Count
|
|
105
|
+
paidClickId: Count
|
|
106
|
+
gaClientId: Count
|
|
107
|
+
selfReportedSource: Count
|
|
108
|
+
recoveredFromShortlinkAttributionTable?: Count
|
|
109
|
+
internalFreeUpgrade: Count
|
|
110
|
+
}
|
|
111
|
+
|
|
84
112
|
export interface AttributionCoverage {
|
|
85
113
|
totalRevenue: USD
|
|
86
114
|
attributedRevenue: USD
|
|
87
115
|
unattributedRevenue: USD
|
|
88
116
|
attributionRate: Percentage
|
|
89
117
|
totalPurchases: Count
|
|
118
|
+
paidPurchases?: Count
|
|
119
|
+
purchaseFieldAttributedPurchases?: Count
|
|
120
|
+
purchaseFieldAttributedRevenue?: USD
|
|
121
|
+
recoveredFromShortlinkAttributionTablePurchases?: Count
|
|
122
|
+
recoveredFromShortlinkAttributionTableRevenue?: USD
|
|
123
|
+
commerceRecords?: Count
|
|
124
|
+
accessGrants?: Count
|
|
125
|
+
freeUpgrades?: Count
|
|
126
|
+
syntheticPurchases?: Count
|
|
127
|
+
commerce?: CommerceLaneSummary
|
|
128
|
+
signals?: AttributionSignalSummary
|
|
90
129
|
}
|
|
91
130
|
|
|
92
131
|
export interface TrafficOverview {
|
|
@@ -279,6 +318,119 @@ export interface SurveyRevenueCorrelation {
|
|
|
279
318
|
byQuestion: SurveyConversionByQuestion[]
|
|
280
319
|
}
|
|
281
320
|
|
|
321
|
+
/** One survey answer bucket correlated to paid product revenue. */
|
|
322
|
+
export interface ProductSurveyRevenueAnswer {
|
|
323
|
+
surveyId: string
|
|
324
|
+
surveyTitle: string | null
|
|
325
|
+
surveySlug: string | null
|
|
326
|
+
questionId: string
|
|
327
|
+
question: string | null
|
|
328
|
+
answer: string
|
|
329
|
+
responses: Count
|
|
330
|
+
uniqueRespondents: Count
|
|
331
|
+
paidPurchasers: Count
|
|
332
|
+
paidRevenue: USD
|
|
333
|
+
conversionRate: Percentage
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Product-filtered survey revenue report with aggregate counts and answer buckets. */
|
|
337
|
+
export interface ProductSurveyRevenueCorrelation {
|
|
338
|
+
productId: string | null
|
|
339
|
+
surveyId: string | null
|
|
340
|
+
surveySlug: string | null
|
|
341
|
+
totalResponses: Count
|
|
342
|
+
uniqueRespondents: Count
|
|
343
|
+
respondentsWithUserId: Count
|
|
344
|
+
paidPurchasers: Count
|
|
345
|
+
paidRevenue: USD
|
|
346
|
+
byAnswer: ProductSurveyRevenueAnswer[]
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** Single-purchase attribution receipt used by operator audits and checkout debugging. */
|
|
350
|
+
export interface CheckoutAttributionReceipt {
|
|
351
|
+
purchase: {
|
|
352
|
+
id: string
|
|
353
|
+
createdAt: Date | string | null
|
|
354
|
+
productId: string | null
|
|
355
|
+
productName: string | null
|
|
356
|
+
totalAmount: USD
|
|
357
|
+
status: string | null
|
|
358
|
+
country: string | null
|
|
359
|
+
} | null
|
|
360
|
+
checks: {
|
|
361
|
+
purchaseFound: boolean
|
|
362
|
+
attributionSnapshot: boolean
|
|
363
|
+
utm: boolean
|
|
364
|
+
actualUtm: boolean
|
|
365
|
+
clickId: boolean
|
|
366
|
+
synthetic: boolean
|
|
367
|
+
shortlink: boolean
|
|
368
|
+
selfReportedSource: boolean
|
|
369
|
+
gaClientId: boolean
|
|
370
|
+
}
|
|
371
|
+
attribution: Record<string, unknown> | null
|
|
372
|
+
legacy: Record<string, unknown>
|
|
373
|
+
fieldKeys: string[]
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** Checkout survey answer bucket for otherwise dark purchase recovery analysis. */
|
|
377
|
+
export interface CheckoutSurveyFallbackAnswer {
|
|
378
|
+
answer: string
|
|
379
|
+
confidence: 'exact_purchase_link' | 'user_linked'
|
|
380
|
+
purchases: Count
|
|
381
|
+
revenue: USD
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Report-only fallback from checkout survey responses to dark purchase revenue. */
|
|
385
|
+
export interface CheckoutSurveyFallbackReport {
|
|
386
|
+
label: 'recovered_from_checkout_survey_response'
|
|
387
|
+
productId: string | null
|
|
388
|
+
totalDarkPurchases: Count
|
|
389
|
+
totalDarkRevenue: USD
|
|
390
|
+
exactPurchaseLinkedPurchases: Count
|
|
391
|
+
exactPurchaseLinkedRevenue: USD
|
|
392
|
+
userLinkedPurchases: Count
|
|
393
|
+
userLinkedRevenue: USD
|
|
394
|
+
byAnswer: CheckoutSurveyFallbackAnswer[]
|
|
395
|
+
notes: string[]
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export interface ValuePathAnswerBucket {
|
|
399
|
+
key: string
|
|
400
|
+
step: string
|
|
401
|
+
optionValue: string
|
|
402
|
+
count: Count
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export interface ValuePathStepBucket {
|
|
406
|
+
step: string
|
|
407
|
+
count: Count
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export interface ValuePathTerminalBucket {
|
|
411
|
+
emailResourceId: string
|
|
412
|
+
count: Count
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface ValuePathSummary {
|
|
416
|
+
contacts: Count
|
|
417
|
+
events: Count
|
|
418
|
+
intents: Count
|
|
419
|
+
completedIntents: Count
|
|
420
|
+
pendingIntents: Count
|
|
421
|
+
blockedIntents: Count
|
|
422
|
+
answerEvents: Count
|
|
423
|
+
dripEvents: Count
|
|
424
|
+
enteredEvents: Count
|
|
425
|
+
participantsWithAnswerClicks: Count
|
|
426
|
+
participantsWithNoAnswerClicks: Count
|
|
427
|
+
terminalParticipants: Count
|
|
428
|
+
answerOptions: ValuePathAnswerBucket[]
|
|
429
|
+
answerSteps: ValuePathStepBucket[]
|
|
430
|
+
terminalSteps: ValuePathTerminalBucket[]
|
|
431
|
+
notes: string[]
|
|
432
|
+
}
|
|
433
|
+
|
|
282
434
|
export interface SurfaceMap {
|
|
283
435
|
summary: RevenueSummary
|
|
284
436
|
'revenue/daily': RevenueDaily[]
|
|
@@ -291,6 +443,7 @@ export interface SurfaceMap {
|
|
|
291
443
|
'attribution/funnel': ConversionFunnel
|
|
292
444
|
'attribution/content': ContentCorrelation[]
|
|
293
445
|
'attribution/coverage': AttributionCoverage
|
|
446
|
+
'attribution/commerce-lanes': CommerceLaneSummary
|
|
294
447
|
traffic: TrafficOverview
|
|
295
448
|
'traffic/daily': TrafficDaily[]
|
|
296
449
|
'traffic/pages': TopPage[]
|
|
@@ -307,7 +460,12 @@ export interface SurfaceMap {
|
|
|
307
460
|
'surveys/questions': SurveyQuestionBreakdown[]
|
|
308
461
|
'surveys/responses': SurveyResponseRow[]
|
|
309
462
|
'correlation/survey-revenue': SurveyRevenueCorrelation
|
|
463
|
+
'correlation/survey-revenue/product': ProductSurveyRevenueCorrelation
|
|
310
464
|
'attribution/email-campaigns': EmailRevenueOverview
|
|
465
|
+
'attribution/email-campaigns/strict': EmailRevenueOverview
|
|
466
|
+
'attribution/checkout-receipt': CheckoutAttributionReceipt
|
|
467
|
+
'attribution/checkout-survey-fallback': CheckoutSurveyFallbackReport
|
|
468
|
+
'value-paths/summary': ValuePathSummary
|
|
311
469
|
}
|
|
312
470
|
|
|
313
471
|
export type SurfaceName = keyof SurfaceMap
|
|
@@ -315,6 +473,12 @@ export type SurfaceName = keyof SurfaceMap
|
|
|
315
473
|
export interface QueryOptions {
|
|
316
474
|
range?: AnalyticsRange
|
|
317
475
|
limit?: number
|
|
476
|
+
offset?: number
|
|
477
|
+
productId?: string
|
|
478
|
+
purchaseId?: string
|
|
479
|
+
surveyId?: string
|
|
480
|
+
surveySlug?: string
|
|
481
|
+
questionId?: string
|
|
318
482
|
}
|
|
319
483
|
|
|
320
484
|
export type QueryResult<S extends SurfaceName> =
|