@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.
@@ -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(0, limit).map((row) => ({
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
- source: string
64
- medium: string
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> =